add guarding mechanic and implement guard sprite handling
This commit is contained in:
@@ -5,6 +5,14 @@ public enum Direction {
|
|||||||
UP,
|
UP,
|
||||||
DOWN,
|
DOWN,
|
||||||
LEFT,
|
LEFT,
|
||||||
RIGHT
|
RIGHT;
|
||||||
|
|
||||||
|
public Direction getOpposite() {
|
||||||
|
return switch (this) {
|
||||||
|
case UP -> DOWN;
|
||||||
|
case DOWN -> UP;
|
||||||
|
case LEFT -> RIGHT;
|
||||||
|
case RIGHT -> LEFT;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ import java.awt.event.KeyListener;
|
|||||||
|
|
||||||
public class KeyHandler implements KeyListener {
|
public class KeyHandler implements KeyListener {
|
||||||
|
|
||||||
public boolean upPressed, downPressed, leftPressed, rightPressed, spacePressed, shotKeyPressed;
|
public boolean upPressed, downPressed, leftPressed, rightPressed, spacePressed, shotKeyPressed, CTLKeyPressed;
|
||||||
public GamePanel panel;
|
public GamePanel panel;
|
||||||
public boolean debug;
|
public boolean debug;
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@ public class KeyHandler implements KeyListener {
|
|||||||
case KeyEvent.VK_S, KeyEvent.VK_DOWN -> downPressed = true;
|
case KeyEvent.VK_S, KeyEvent.VK_DOWN -> downPressed = true;
|
||||||
case KeyEvent.VK_A, KeyEvent.VK_LEFT -> leftPressed = true;
|
case KeyEvent.VK_A, KeyEvent.VK_LEFT -> leftPressed = true;
|
||||||
case KeyEvent.VK_D, KeyEvent.VK_RIGHT -> rightPressed = true;
|
case KeyEvent.VK_D, KeyEvent.VK_RIGHT -> rightPressed = true;
|
||||||
|
case KeyEvent.VK_CONTROL -> CTLKeyPressed = true;
|
||||||
case KeyEvent.VK_SPACE -> spacePressed = true;
|
case KeyEvent.VK_SPACE -> spacePressed = true;
|
||||||
//case KeyEvent.VK_F -> shotKeyPressed = true;
|
//case KeyEvent.VK_F -> shotKeyPressed = true;
|
||||||
|
|
||||||
@@ -276,6 +277,7 @@ public class KeyHandler implements KeyListener {
|
|||||||
case KeyEvent.VK_S, KeyEvent.VK_DOWN -> downPressed = false;
|
case KeyEvent.VK_S, KeyEvent.VK_DOWN -> downPressed = false;
|
||||||
case KeyEvent.VK_A, KeyEvent.VK_LEFT -> leftPressed = false;
|
case KeyEvent.VK_A, KeyEvent.VK_LEFT -> leftPressed = false;
|
||||||
case KeyEvent.VK_D, KeyEvent.VK_RIGHT -> rightPressed = false;
|
case KeyEvent.VK_D, KeyEvent.VK_RIGHT -> rightPressed = false;
|
||||||
|
case KeyEvent.VK_CONTROL -> CTLKeyPressed = false;
|
||||||
case KeyEvent.VK_F -> shotKeyPressed = false;
|
case KeyEvent.VK_F -> shotKeyPressed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public class Entity {
|
|||||||
protected GamePanel panel;
|
protected GamePanel panel;
|
||||||
public BufferedImage up1, up2, down1, down2, left1, left2, right1, right2;
|
public BufferedImage up1, up2, down1, down2, left1, left2, right1, right2;
|
||||||
public BufferedImage attackUp1, attackUp2, attackDown1, attackDown2, attackLeft1, attackLeft2, attackRight1, attackRight2;
|
public BufferedImage attackUp1, attackUp2, attackDown1, attackDown2, attackLeft1, attackLeft2, attackRight1, attackRight2;
|
||||||
|
public BufferedImage guardUp, guardDown, guardLeft, guardRight;
|
||||||
public BufferedImage image, image2, image3;
|
public BufferedImage image, image2, image3;
|
||||||
public Rectangle solidArea = new Rectangle(0, 0, 48, 48);
|
public Rectangle solidArea = new Rectangle(0, 0, 48, 48);
|
||||||
public Rectangle attackArea = new Rectangle(0, 0, 0, 0);
|
public Rectangle attackArea = new Rectangle(0, 0, 0, 0);
|
||||||
@@ -38,6 +39,7 @@ public class Entity {
|
|||||||
int dialogueIndex;
|
int dialogueIndex;
|
||||||
public boolean collisionOn;
|
public boolean collisionOn;
|
||||||
public boolean invincible;
|
public boolean invincible;
|
||||||
|
public boolean transparent;
|
||||||
public boolean attacking;
|
public boolean attacking;
|
||||||
public boolean alive = true;
|
public boolean alive = true;
|
||||||
public boolean dying;
|
public boolean dying;
|
||||||
@@ -45,6 +47,7 @@ public class Entity {
|
|||||||
public boolean consumable;
|
public boolean consumable;
|
||||||
public boolean onPath;
|
public boolean onPath;
|
||||||
public boolean knockback;
|
public boolean knockback;
|
||||||
|
public boolean guarding;
|
||||||
public Direction knockbackDirection;
|
public Direction knockbackDirection;
|
||||||
|
|
||||||
// COUNTER
|
// COUNTER
|
||||||
@@ -181,16 +184,16 @@ public class Entity {
|
|||||||
if(invincible) {
|
if(invincible) {
|
||||||
hpBarOn = true;
|
hpBarOn = true;
|
||||||
hpBarCount = 0;
|
hpBarCount = 0;
|
||||||
changeOpacity(graphics2d, 0.4f);
|
if(transparent) changeOpacity(graphics2d, 0.4f);
|
||||||
}
|
}
|
||||||
if(dying) dyingAnimation(graphics2d);
|
if(dying) dyingAnimation(graphics2d);
|
||||||
if(type == EntityType.PLAYER || name.equals("orc")) { // only modify sprite render position for player because I dont know yet how monster attack sprite are gonna look
|
if(type == EntityType.PLAYER || name.equals("orc")) { // only modify sprite render position for player because I dont know yet how monster attack sprite are gonna look
|
||||||
if(attacking) graphics2d.drawImage(parseSpriteATK(),
|
if(attacking) graphics2d.drawImage(parseSpriteATK(),
|
||||||
(direction == Direction.LEFT) ? screenX - panel.tileSize : screenX,
|
(direction == Direction.LEFT) ? screenX - panel.tileSize : screenX,
|
||||||
(direction == Direction.UP) ? screenY - panel.tileSize : screenY, null);
|
(direction == Direction.UP) ? screenY - panel.tileSize : screenY, null);
|
||||||
|
else if(guarding) graphics2d.drawImage(parseSpriteGRD(), screenX, screenY, null);
|
||||||
else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
||||||
} else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
} else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
||||||
|
|
||||||
changeOpacity(graphics2d, 1f);
|
changeOpacity(graphics2d, 1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,11 +250,18 @@ public class Entity {
|
|||||||
}
|
}
|
||||||
public void damagePlayer(int attack) {
|
public void damagePlayer(int attack) {
|
||||||
if(panel.player.invincible) return;
|
if(panel.player.invincible) return;
|
||||||
panel.playSE(6);
|
|
||||||
|
|
||||||
|
boolean block = panel.player.guarding && panel.player.direction == this.direction.getOpposite();
|
||||||
int damage = attack - panel.player.defense;
|
int damage = attack - panel.player.defense;
|
||||||
panel.player.life -= Math.max(damage, 0);
|
|
||||||
|
|
||||||
|
if(block) {
|
||||||
|
panel.playSE(15);
|
||||||
|
damage = 0;
|
||||||
|
} else panel.playSE(6);
|
||||||
|
|
||||||
|
panel.player.life -= Math.max(damage, (block ? 0 : 1));
|
||||||
|
|
||||||
|
if(damage != 0) panel.player.transparent = true;
|
||||||
panel.player.invincible = true;
|
panel.player.invincible = true;
|
||||||
}
|
}
|
||||||
public void speak() {
|
public void speak() {
|
||||||
@@ -427,6 +437,14 @@ public class Entity {
|
|||||||
case RIGHT -> (spriteNum == 1) ? attackRight1 : attackRight2;
|
case RIGHT -> (spriteNum == 1) ? attackRight1 : attackRight2;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
BufferedImage parseSpriteGRD() {
|
||||||
|
return switch (direction) {
|
||||||
|
case UP -> guardUp;
|
||||||
|
case DOWN -> guardDown;
|
||||||
|
case LEFT -> guardLeft;
|
||||||
|
case RIGHT -> guardRight;
|
||||||
|
};
|
||||||
|
}
|
||||||
public BufferedImage initEntitySprites(String name) {
|
public BufferedImage initEntitySprites(String name) {
|
||||||
try {
|
try {
|
||||||
return Utility.scaleImage(ImageIO.read(new FileInputStream("assets/" + name + ".png")), panel.tileSize, panel.tileSize);
|
return Utility.scaleImage(ImageIO.read(new FileInputStream("assets/" + name + ".png")), panel.tileSize, panel.tileSize);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class Player extends Entity {
|
|||||||
KeyHandler keyH;
|
KeyHandler keyH;
|
||||||
public final int screenX;
|
public final int screenX;
|
||||||
public final int screenY;
|
public final int screenY;
|
||||||
|
private int standCount;
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
public boolean attackCancel;
|
public boolean attackCancel;
|
||||||
@@ -44,16 +45,25 @@ public class Player extends Entity {
|
|||||||
setDefaultValues();
|
setDefaultValues();
|
||||||
getPlayerImage();
|
getPlayerImage();
|
||||||
getPlayerAttackImage();
|
getPlayerAttackImage();
|
||||||
|
getGuardImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEFAULT
|
// DEFAULT
|
||||||
public void update() {
|
public void update() {
|
||||||
if(life > maxLife) life = maxLife;
|
if(life > maxLife) life = maxLife;
|
||||||
|
|
||||||
|
// ATTACKING
|
||||||
if(attacking) {
|
if(attacking) {
|
||||||
attacking();
|
attacking();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BLOCKING
|
||||||
|
if(keyH.CTLKeyPressed) {
|
||||||
|
guarding = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// MOVEMENT
|
// MOVEMENT
|
||||||
if(keyH.upPressed || keyH.downPressed || keyH.leftPressed || keyH.rightPressed || keyH.spacePressed) {
|
if(keyH.upPressed || keyH.downPressed || keyH.leftPressed || keyH.rightPressed || keyH.spacePressed) {
|
||||||
if(!keyH.spacePressed) {
|
if(!keyH.spacePressed) {
|
||||||
@@ -102,6 +112,7 @@ public class Player extends Entity {
|
|||||||
|
|
||||||
attackCancel = false;
|
attackCancel = false;
|
||||||
panel.keyH.spacePressed = false;
|
panel.keyH.spacePressed = false;
|
||||||
|
guarding = false;
|
||||||
|
|
||||||
spriteCount++;
|
spriteCount++;
|
||||||
if(spriteCount > 12) {
|
if(spriteCount > 12) {
|
||||||
@@ -110,6 +121,13 @@ public class Player extends Entity {
|
|||||||
else spriteNum = 0;
|
else spriteNum = 0;
|
||||||
spriteCount = 0;
|
spriteCount = 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
standCount++;
|
||||||
|
if(standCount == 20) {
|
||||||
|
spriteNum = 1;
|
||||||
|
standCount = 0;
|
||||||
|
}
|
||||||
|
guarding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(panel.keyH.shotKeyPressed && !projectile.alive) {
|
if(panel.keyH.shotKeyPressed && !projectile.alive) {
|
||||||
@@ -123,6 +141,7 @@ public class Player extends Entity {
|
|||||||
invincibleCount++;
|
invincibleCount++;
|
||||||
if(invincibleCount > 60) {
|
if(invincibleCount > 60) {
|
||||||
invincible = false;
|
invincible = false;
|
||||||
|
transparent = false;
|
||||||
invincibleCount = 0;
|
invincibleCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,11 +188,10 @@ public class Player extends Entity {
|
|||||||
|
|
||||||
int damage = panel.monster[panel.currentMap.getIndex()][index].attack - defense;
|
int damage = panel.monster[panel.currentMap.getIndex()][index].attack - defense;
|
||||||
|
|
||||||
if(damage > 0) {
|
panel.playSE(6);
|
||||||
panel.playSE(6);
|
life -= Math.max(damage, 0);
|
||||||
life -= damage;
|
if(damage != 0) panel.player.transparent = true;
|
||||||
invincible = true;
|
invincible = true;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public void damageMonster(int index, Entity attacker, int attack, int knockbackVal) {
|
public void damageMonster(int index, Entity attacker, int attack, int knockbackVal) {
|
||||||
@@ -347,6 +365,12 @@ public class Player extends Entity {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void getGuardImages() {
|
||||||
|
guardUp = initEntitySprites("player/guarding/boy_guard_up");
|
||||||
|
guardDown = initEntitySprites("player/guarding/boy_guard_down");
|
||||||
|
guardLeft = initEntitySprites("player/guarding/boy_guard_left");
|
||||||
|
guardRight = initEntitySprites("player/guarding/boy_guard_right");
|
||||||
|
}
|
||||||
public int searchItemInInventory(String itemName) {
|
public int searchItemInInventory(String itemName) {
|
||||||
for(int i = 0; i < inventory.size(); i++) {
|
for(int i = 0; i < inventory.size(); i++) {
|
||||||
if(inventory.get(i).name.equals(itemName)) {
|
if(inventory.get(i).name.equals(itemName)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user