feat: Hurt animation and killing of zombie
This commit is contained in:
@ -57,7 +57,9 @@ public class Game {
|
|||||||
private transient GameStates gameStates = new GameStates(this);
|
private transient GameStates gameStates = new GameStates(this);
|
||||||
private Stats stats = new Stats();
|
private Stats stats = new Stats();
|
||||||
|
|
||||||
/** Current time of day in the game (0–600 range). */
|
/**
|
||||||
|
* Current time of day in the game (0–600 range).
|
||||||
|
*/
|
||||||
@Setter
|
@Setter
|
||||||
private int daytime = 0;
|
private int daytime = 0;
|
||||||
//
|
//
|
||||||
@ -83,9 +85,9 @@ public class Game {
|
|||||||
var steveData = (SteveData) block.getData();
|
var steveData = (SteveData) block.getData();
|
||||||
|
|
||||||
if (steveData.isTop()) {
|
if (steveData.isTop()) {
|
||||||
return new int[] { j, i + 1 };
|
return new int[]{j, i + 1};
|
||||||
} else {
|
} else {
|
||||||
return new int[] { j, i };
|
return new int[]{j, i};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,12 +210,16 @@ public class Game {
|
|||||||
int dealDamage = inventory.getItemInHand().map(Item::getDealDamage).orElse(1);
|
int dealDamage = inventory.getItemInHand().map(Item::getDealDamage).orElse(1);
|
||||||
if (mob.getHp() - dealDamage <= 0) {
|
if (mob.getHp() - dealDamage <= 0) {
|
||||||
// Mob is killed
|
// Mob is killed
|
||||||
gameStates.dependencies.entityKill.get(mob.getBlockId()).killed(this, mob);
|
gameStates.dependencies.entityKill.get(mob.getBlockId()).killed(this, mob, x, y);
|
||||||
world[y][x].remove(mob);
|
world[y][x].remove(mob);
|
||||||
} else {
|
} else {
|
||||||
mob.decreaseHp(dealDamage);
|
mob.decreaseHp(dealDamage);
|
||||||
mob.setSpriteState(gameStates.dependencies.entityHurtAnimation.get(mob.getBlockId())
|
mob.setSpriteState(gameStates.dependencies.entityHurtAnimation.get(mob.getBlockId())
|
||||||
.setHurtAnimation(true, mob.getSpriteState().get()));
|
.setHurtAnimation(true, mob.getSpriteState().get()));
|
||||||
|
if (mob.getLinkedMobTexture() != null) {
|
||||||
|
mob.getLinkedMobTexture().setSpriteState(gameStates.dependencies.entityHurtAnimation.get(mob.getBlockId())
|
||||||
|
.setHurtAnimation(true, mob.getLinkedMobTexture().getSpriteState().get()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
screenRenderer.render(this);
|
screenRenderer.render(this);
|
||||||
@ -228,6 +234,11 @@ public class Game {
|
|||||||
for (Block mob : mobs) {
|
for (Block mob : mobs) {
|
||||||
mob.setSpriteState(gameStates.dependencies.entityHurtAnimation.get(mob.getBlockId())
|
mob.setSpriteState(gameStates.dependencies.entityHurtAnimation.get(mob.getBlockId())
|
||||||
.setHurtAnimation(false, mob.getSpriteState().get()));
|
.setHurtAnimation(false, mob.getSpriteState().get()));
|
||||||
|
|
||||||
|
if (mob.getLinkedMobTexture() != null) {
|
||||||
|
mob.getLinkedMobTexture().setSpriteState(gameStates.dependencies.entityHurtAnimation.get(mob.getBlockId())
|
||||||
|
.setHurtAnimation(false, mob.getLinkedMobTexture().getSpriteState().get()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
screenRenderer.render(this);
|
screenRenderer.render(this);
|
||||||
}).start();
|
}).start();
|
||||||
|
@ -32,6 +32,7 @@ public class Block {
|
|||||||
private boolean onFire = false;
|
private boolean onFire = false;
|
||||||
private int burningTime = 0;
|
private int burningTime = 0;
|
||||||
private int burningTime2 = 0;
|
private int burningTime2 = 0;
|
||||||
|
private Block linkedMobTexture;
|
||||||
|
|
||||||
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
||||||
this.blockId = blockId;
|
this.blockId = blockId;
|
||||||
|
@ -4,5 +4,5 @@ import cz.jzitnik.game.Game;
|
|||||||
import cz.jzitnik.game.entities.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
|
||||||
public interface EntityKillInterface {
|
public interface EntityKillInterface {
|
||||||
void killed(Game game, Block mob);
|
void killed(Game game, Block mob, int x, int y);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ public class CowLogic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void killed(Game game, Block mob) {
|
public void killed(Game game, Block mob, int x, int y) {
|
||||||
int leatherAmount = random.nextInt(3);
|
int leatherAmount = random.nextInt(3);
|
||||||
InventoryItem inventoryItem = new InventoryItem(leatherAmount, ItemBlockSupplier.getItem("leather"));
|
InventoryItem inventoryItem = new InventoryItem(leatherAmount, ItemBlockSupplier.getItem("leather"));
|
||||||
int beefAmount = random.nextInt(3) + 1;
|
int beefAmount = random.nextInt(3) + 1;
|
||||||
|
@ -199,7 +199,7 @@ public class PigLogic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void killed(Game game, Block mob) {
|
public void killed(Game game, Block mob, int x, int y) {
|
||||||
int amount = random.nextInt(2) + 1;
|
int amount = random.nextInt(2) + 1;
|
||||||
InventoryItem inventoryItem = new InventoryItem(amount, ItemBlockSupplier.getItem("porkchop"));
|
InventoryItem inventoryItem = new InventoryItem(amount, ItemBlockSupplier.getItem("porkchop"));
|
||||||
game.getInventory().addItem(inventoryItem);
|
game.getInventory().addItem(inventoryItem);
|
||||||
|
@ -242,7 +242,7 @@ public class SheepLogic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void killed(Game game, Block mob) {
|
public void killed(Game game, Block mob, int x, int y) {
|
||||||
int amount = random.nextInt(3) + 1;
|
int amount = random.nextInt(3) + 1;
|
||||||
var sheepData = (SheepData) mob.getData();
|
var sheepData = (SheepData) mob.getData();
|
||||||
|
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package cz.jzitnik.game.mobs.services.zombie;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.annotations.EntityHurtAnimationHandler;
|
||||||
|
import cz.jzitnik.game.annotations.EntityKillHandler;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import cz.jzitnik.game.mobs.*;
|
||||||
|
import cz.jzitnik.game.sprites.Zombie;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static cz.jzitnik.game.sprites.Zombie.ZombieState.*;
|
||||||
|
|
||||||
|
@EntityHurtAnimationHandler("zombie")
|
||||||
|
@EntityKillHandler("zombie")
|
||||||
|
public class ZombieHurtKillLogic implements EntityHurtAnimationChanger, EntityKillInterface {
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
|
public Zombie.ZombieState setHurtAnimation(boolean hurt, Enum current) {
|
||||||
|
if (hurt) {
|
||||||
|
return switch (current) {
|
||||||
|
case TOP, TOP_HURT -> TOP_HURT;
|
||||||
|
case BOTTOM, BOTTOM_HURT -> BOTTOM_HURT;
|
||||||
|
default -> throw new IllegalStateException("Unexpected state: " + current);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return switch (current) {
|
||||||
|
case TOP, TOP_HURT -> TOP;
|
||||||
|
case BOTTOM, BOTTOM_HURT -> BOTTOM;
|
||||||
|
default -> throw new IllegalStateException("Unexpected state: " + current);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void killed(Game game, Block mob, int x, int y) {
|
||||||
|
int rottenFlesh = random.nextInt(3) + 1;
|
||||||
|
|
||||||
|
boolean isTop = mob.getSpriteState().isPresent() && (mob.getSpriteState().get().equals(TOP_HURT) || mob.getSpriteState().get().equals(TOP));
|
||||||
|
int newY = isTop ? y + 1 : y - 1;
|
||||||
|
|
||||||
|
game.getWorld()[newY][x].remove(mob.getLinkedMobTexture());
|
||||||
|
|
||||||
|
// Rotten flesh is currently not an item. So this is commented out
|
||||||
|
// TODO: Add rotten flesh to the game
|
||||||
|
//InventoryItem drop = new InventoryItem(rottenFlesh, ItemBlockSupplier.getItem("rotten_flesh"));
|
||||||
|
//game.getInventory().addItem(drop);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package cz.jzitnik.game.mobs.services.zombie;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.annotations.EntityLogic;
|
||||||
|
import cz.jzitnik.game.mobs.EntityLogicInterface;
|
||||||
|
import cz.jzitnik.game.mobs.EntityLogicProvider;
|
||||||
|
|
||||||
|
@EntityLogic("zombie")
|
||||||
|
public class ZombieMoveLogic implements EntityLogicInterface {
|
||||||
|
@Override
|
||||||
|
public void nextIteration(EntityLogicProvider.EntityLogicMobDTO entityLogicMobDTO) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,49 +1,30 @@
|
|||||||
package cz.jzitnik.game.mobs.services.zombie;
|
package cz.jzitnik.game.mobs.services.zombie;
|
||||||
|
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.annotations.EntityHurtAnimationHandler;
|
|
||||||
import cz.jzitnik.game.annotations.EntityKillHandler;
|
|
||||||
import cz.jzitnik.game.annotations.EntityLogic;
|
|
||||||
import cz.jzitnik.game.annotations.EntitySpawn;
|
import cz.jzitnik.game.annotations.EntitySpawn;
|
||||||
import cz.jzitnik.game.entities.Block;
|
|
||||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
|
||||||
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||||
import cz.jzitnik.game.mobs.*;
|
import cz.jzitnik.game.mobs.EntitySpawnInterface;
|
||||||
import cz.jzitnik.game.sprites.Zombie;
|
import cz.jzitnik.game.sprites.Zombie;
|
||||||
import cz.jzitnik.game.sprites.Zombie.ZombieState;
|
|
||||||
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jline.terminal.Terminal;
|
import org.jline.terminal.Terminal;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static cz.jzitnik.game.sprites.Zombie.ZombieState.*;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@EntitySpawn
|
@EntitySpawn
|
||||||
@EntityLogic("zombie")
|
public class ZombieSpawnLogic implements EntitySpawnInterface {
|
||||||
@EntityHurtAnimationHandler("zombie")
|
|
||||||
@EntityKillHandler("zombie")
|
|
||||||
public class ZombieLogic
|
|
||||||
implements EntityLogicInterface, EntitySpawnInterface, EntityHurtAnimationChanger, EntityKillInterface {
|
|
||||||
|
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
|
|
||||||
@Override
|
|
||||||
public void nextIteration(EntityLogicProvider.EntityLogicMobDTO entityLogicMobDTO) {
|
|
||||||
log.debug("Running zombie logic");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawn(int playerX, int playerY, Game game, Terminal terminal) {
|
public void spawn(int playerX, int playerY, Game game, Terminal terminal) {
|
||||||
int[] view = ScreenMovingCalculationProvider.calculate(playerX, playerY, terminal.getHeight(), terminal.getWidth(), game.getWorld()[0].length, game.getWorld().length);
|
int[] view = ScreenMovingCalculationProvider.calculate(playerX, playerY, terminal.getHeight(), terminal.getWidth(), game.getWorld()[0].length, game.getWorld().length);
|
||||||
int startX = view[0];
|
int startX = view[0];
|
||||||
int endX = view[1];
|
int endX = view[1];
|
||||||
|
|
||||||
//attemptZombieSpawn(startX - 20, startX - 5, playerY, game);
|
attemptZombieSpawn(startX - 20, startX - 5, playerY, game);
|
||||||
//attemptZombieSpawn(endX + 5, endX + 20, playerY, game);
|
attemptZombieSpawn(endX + 5, endX + 20, playerY, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void attemptZombieSpawn(int startX, int endX, int centerY, Game game) {
|
private void attemptZombieSpawn(int startX, int endX, int centerY, Game game) {
|
||||||
if (countZombies(startX, endX, centerY - 15, centerY + 15, game) < 3 && random.nextInt(100) < 2) {
|
if (countZombies(startX, endX, centerY - 15, centerY + 15, game) < 3 && random.nextInt(100) < 2) {
|
||||||
var spawnLocations = zombieCanSpawn(startX, endX, centerY, game);
|
var spawnLocations = zombieCanSpawn(startX, endX, centerY, game);
|
||||||
@ -54,10 +35,13 @@ public class ZombieLogic
|
|||||||
int y = loc.getValue();
|
int y = loc.getValue();
|
||||||
|
|
||||||
var top = ItemBlockSupplier.getEntity("zombie");
|
var top = ItemBlockSupplier.getEntity("zombie");
|
||||||
top.setSpriteState(ZombieState.TOP);
|
top.setSpriteState(Zombie.ZombieState.TOP);
|
||||||
|
|
||||||
var bottom = ItemBlockSupplier.getEntity("zombie");
|
var bottom = ItemBlockSupplier.getEntity("zombie");
|
||||||
bottom.setSpriteState(ZombieState.BOTTOM);
|
bottom.setSpriteState(Zombie.ZombieState.BOTTOM);
|
||||||
|
|
||||||
|
top.setLinkedMobTexture(bottom);
|
||||||
|
bottom.setLinkedMobTexture(top);
|
||||||
|
|
||||||
game.getWorld()[y - 1][x].add(top);
|
game.getWorld()[y - 1][x].add(top);
|
||||||
game.getWorld()[y][x].add(bottom);
|
game.getWorld()[y][x].add(bottom);
|
||||||
@ -66,6 +50,7 @@ public class ZombieLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private HashMap<Integer, Integer> zombieCanSpawn(int startX, int endX, int playerY, Game game) {
|
private HashMap<Integer, Integer> zombieCanSpawn(int startX, int endX, int playerY, Game game) {
|
||||||
var map = new HashMap<Integer, Integer>();
|
var map = new HashMap<Integer, Integer>();
|
||||||
var world = game.getWorld();
|
var world = game.getWorld();
|
||||||
@ -89,29 +74,6 @@ public class ZombieLogic
|
|||||||
return count / 2; // Each zombie has two parts
|
return count / 2; // Each zombie has two parts
|
||||||
}
|
}
|
||||||
|
|
||||||
public Zombie.ZombieState setHurtAnimation(boolean hurt, Enum current) {
|
|
||||||
if (hurt) {
|
|
||||||
return switch (current) {
|
|
||||||
case TOP, TOP_HURT -> TOP_HURT;
|
|
||||||
case BOTTOM, BOTTOM_HURT -> BOTTOM_HURT;
|
|
||||||
default -> throw new IllegalStateException("Unexpected state: " + current);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return switch (current) {
|
|
||||||
case TOP, TOP_HURT -> TOP;
|
|
||||||
case BOTTOM, BOTTOM_HURT -> BOTTOM;
|
|
||||||
default -> throw new IllegalStateException("Unexpected state: " + current);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void killed(Game game, Block mob) {
|
|
||||||
int rottenFlesh = random.nextInt(3) + 1;
|
|
||||||
//InventoryItem drop = new InventoryItem(rottenFlesh, ItemBlockSupplier.getItem("rotten_flesh"));
|
|
||||||
//game.getInventory().addItem(drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <K, V> Map.Entry<K, V> getRandomEntry(HashMap<K, V> map) {
|
public static <K, V> Map.Entry<K, V> getRandomEntry(HashMap<K, V> map) {
|
||||||
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
|
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
|
||||||
return list.get(new Random().nextInt(list.size()));
|
return list.get(new Random().nextInt(list.size()));
|
Reference in New Issue
Block a user