255 lines
9.0 KiB
Java
255 lines
9.0 KiB
Java
package de.miaurizius.jgame2d.entity;
|
|
|
|
import de.miaurizius.jgame2d.core.Boot;
|
|
import de.miaurizius.jgame2d.core.enums.Direction;
|
|
import de.miaurizius.jgame2d.core.GamePanel;
|
|
import de.miaurizius.jgame2d.core.Utility;
|
|
import de.miaurizius.jgame2d.core.enums.EntityType;
|
|
import de.miaurizius.jgame2d.entity.projectile.Projectile;
|
|
|
|
import javax.imageio.ImageIO;
|
|
import java.awt.*;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.util.logging.Level;
|
|
|
|
public class Entity {
|
|
|
|
protected GamePanel panel;
|
|
public BufferedImage up1, up2, down1, down2, left1, left2, right1, right2;
|
|
public BufferedImage attackUp1, attackUp2, attackDown1, attackDown2, attackLeft1, attackLeft2, attackRight1, attackRight2;
|
|
public BufferedImage image, image2, image3;
|
|
public Rectangle solidArea = new Rectangle(0, 0, 48, 48);
|
|
public Rectangle attackArea = new Rectangle(0, 0, 0, 0);
|
|
public int solidAreaDefaultX, solidAreaDefaultY;
|
|
public boolean collision;
|
|
protected String[] dialogue = new String[20];
|
|
|
|
// STATE
|
|
public int worldX, worldY;
|
|
public Direction direction = Direction.DOWN;
|
|
public int spriteNum = 1;
|
|
int dialogueIndex;
|
|
public boolean collisionOn;
|
|
public boolean invincible;
|
|
boolean attacking;
|
|
public boolean alive = true;
|
|
public boolean dying;
|
|
public boolean hpBarOn;
|
|
public boolean consumable;
|
|
|
|
// COUNTER
|
|
public int spriteCounter;
|
|
public int actionLock;
|
|
public int invincibleCount;
|
|
int dyingCount;
|
|
int hpBarCounter;
|
|
|
|
// CHARACTER ATTRIBUTES
|
|
public EntityType type;
|
|
public String name;
|
|
public int speed;
|
|
public int maxLife;
|
|
public int life;
|
|
public int level;
|
|
public int strength;
|
|
public int dexterity;
|
|
public int attack;
|
|
public int defense;
|
|
public int exp;
|
|
public int nextLevelExp;
|
|
public int coins;
|
|
public int maxMana;
|
|
public int mana;
|
|
public Entity currentWeapon;
|
|
public Entity currentShield;
|
|
public Projectile projectile;
|
|
|
|
// ITEM ATTRIBUTES
|
|
public EntityType.WeaponType weaponType;
|
|
public int attackValue;
|
|
public int defenseValue;
|
|
public String description;
|
|
public int useCost;
|
|
public int value;
|
|
|
|
public Entity(GamePanel panel) {
|
|
this.panel = panel;
|
|
}
|
|
|
|
// DEFAULT
|
|
public void update() {
|
|
setAction();
|
|
collisionOn = false;
|
|
panel.collisionH.checkTile(this);
|
|
panel.collisionH.checkObject(this, false);
|
|
panel.collisionH.checkEntity(this, panel.npc);
|
|
panel.collisionH.checkEntity(this, panel.monster);
|
|
panel.collisionH.checkEntity(this, panel.iTile);
|
|
boolean contactPlayer = panel.collisionH.checkPlayer(this);
|
|
|
|
if(this.type == EntityType.MONSTER && contactPlayer) damagePlayer(attack);
|
|
|
|
if(!collisionOn) {
|
|
switch (direction) {
|
|
case UP -> worldY -= speed;
|
|
case DOWN -> worldY += speed;
|
|
case LEFT ->worldX -= speed;
|
|
case RIGHT -> worldX += speed;
|
|
}
|
|
}
|
|
|
|
spriteCounter++;
|
|
if(spriteCounter > 12) {
|
|
if(spriteNum == 1) spriteNum = 2;
|
|
else if(spriteNum == 2) spriteNum = 1;
|
|
else spriteNum = 0;
|
|
spriteCounter = 0;
|
|
}
|
|
|
|
// INVINCIBLE COUNTER
|
|
if(!invincible) return;
|
|
invincibleCount++;
|
|
if(invincibleCount > 40) {
|
|
invincible = false;
|
|
invincibleCount = 0;
|
|
}
|
|
}
|
|
public void draw(Graphics2D graphics2d) {
|
|
int screenX = worldX - panel.player.worldX + panel.player.screenX;
|
|
int screenY = worldY - panel.player.worldY + panel.player.screenY;
|
|
|
|
if(worldX + panel.tileSize > panel.player.worldX - panel.player.screenX &&
|
|
worldX - panel.tileSize < panel.player.worldX + panel.player.screenX &&
|
|
worldY + panel.tileSize > panel.player.worldY - panel.player.screenY &&
|
|
worldY - panel.tileSize < panel.player.worldY + panel.player.screenY
|
|
) {
|
|
|
|
// MONSTER HP-BAR
|
|
if(this.type == EntityType.MONSTER && hpBarOn) {
|
|
graphics2d.setColor(new Color(35, 35, 35));
|
|
graphics2d.fillRect(screenX-1, screenY-6, panel.tileSize+2, 12);
|
|
|
|
graphics2d.setColor(new Color(255, 0, 30));
|
|
graphics2d.fillRect(screenX, screenY-5, (int) ((double) panel.tileSize/maxLife)*life, 10);
|
|
|
|
hpBarCounter++;
|
|
if(hpBarCounter > 600) { //bar disappears after 10 seconds
|
|
hpBarCounter = 0;
|
|
hpBarOn = false;
|
|
}
|
|
}
|
|
|
|
// DRAW ENTITY
|
|
if(invincible) {
|
|
hpBarOn = true;
|
|
hpBarCounter = 0;
|
|
changeOpacity(graphics2d, 0.4f);
|
|
}
|
|
if(dying) dyingAnimation(graphics2d);
|
|
if(type == EntityType.PLAYER) { // only modify sprite render position for player because I dont know yet how monster attack sprite are gonna look
|
|
if(attacking) graphics2d.drawImage(parseSpriteATK(),
|
|
(direction == Direction.LEFT) ? screenX - panel.tileSize : screenX,
|
|
(direction == Direction.UP) ? screenY - panel.tileSize : screenY, null);
|
|
else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
|
} else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
|
|
|
changeOpacity(graphics2d, 1f);
|
|
}
|
|
}
|
|
|
|
// INTERACTION
|
|
public void setAction() {}
|
|
public void damageReaction() {}
|
|
public void damagePlayer(int attack) {
|
|
if(panel.player.invincible) return;
|
|
panel.playSE(6);
|
|
|
|
int damage = attack - panel.player.defense;
|
|
panel.player.life -= Math.max(damage, 0);
|
|
|
|
panel.player.invincible = true;
|
|
}
|
|
public void speak() {
|
|
if(dialogue[dialogueIndex] == null) dialogueIndex = 0;
|
|
panel.ui.currentDialogue = dialogue[dialogueIndex];
|
|
dialogueIndex++;
|
|
|
|
switch(panel.player.direction) {
|
|
case UP -> direction = Direction.DOWN;
|
|
case DOWN -> direction = Direction.UP;
|
|
case LEFT -> direction = Direction.RIGHT;
|
|
case RIGHT -> direction = Direction.LEFT;
|
|
}
|
|
}
|
|
public void dyingAnimation(Graphics2D graphics2d) {
|
|
dyingCount++;
|
|
int incr = 5;
|
|
if(dyingCount <= incr) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr && dyingCount <= incr*2) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*2 && dyingCount <= incr*3) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr*3 && dyingCount <= incr*4) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*4 && dyingCount <= incr*5) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr*5 && dyingCount <= incr*6) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*6 && dyingCount <= incr*7) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr*7 && dyingCount <= incr*8) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*8) {
|
|
alive = false;
|
|
}
|
|
}
|
|
public void use(Entity entity) {
|
|
} //If entity is consumable
|
|
public void checkDrop() {
|
|
|
|
}
|
|
public void dropItem(Entity droppedItem) {
|
|
for(int i = 0; i < panel.obj.length; i++) {
|
|
if(panel.obj[i] == null) {
|
|
panel.obj[i] = droppedItem;
|
|
panel.obj[i].worldX = worldX;
|
|
panel.obj[i].worldY = worldY;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// SETTING THINGS UP
|
|
BufferedImage parseSprite() {
|
|
return switch (direction) {
|
|
case UP -> (spriteNum == 1) ? up1 : up2;
|
|
case DOWN -> (spriteNum == 1) ? down1 : down2;
|
|
case LEFT -> (spriteNum == 1) ? left1 : left2;
|
|
case RIGHT -> (spriteNum == 1) ? right1 : right2;
|
|
};
|
|
}
|
|
BufferedImage parseSpriteATK() {
|
|
return switch (direction) {
|
|
case UP -> (spriteNum == 1) ? attackUp1 : attackUp2;
|
|
case DOWN -> (spriteNum == 1) ? attackDown1 : attackDown2;
|
|
case LEFT -> (spriteNum == 1) ? attackLeft1 : attackLeft2;
|
|
case RIGHT -> (spriteNum == 1) ? attackRight1 : attackRight2;
|
|
};
|
|
}
|
|
public BufferedImage initEntitySprites(String name) {
|
|
try {
|
|
return Utility.scaleImage(ImageIO.read(new FileInputStream("assets/" + name + ".png")), panel.tileSize, panel.tileSize);
|
|
} catch (IOException e) {
|
|
Boot.logger.log(Level.SEVERE, "Could not load entity-image", e);
|
|
}
|
|
return null;
|
|
}
|
|
public BufferedImage initEntitySprites(String name, int width, int height) {
|
|
try {
|
|
return Utility.scaleImage(ImageIO.read(new FileInputStream("assets/" + name + ".png")), width, height);
|
|
} catch (IOException e) {
|
|
Boot.logger.log(Level.SEVERE, "Could not load entity-image", e);
|
|
}
|
|
return null;
|
|
}
|
|
public void changeOpacity(Graphics2D graphics2d, float opacity) {
|
|
graphics2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
|
|
}
|
|
|
|
}
|