diff --git a/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java b/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java index 1872040..d722419 100644 --- a/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java +++ b/src/de/miaurizius/jgame2d/core/handlers/AssetSetter.java @@ -3,6 +3,7 @@ package de.miaurizius.jgame2d.core.handlers; import de.miaurizius.jgame2d.core.GamePanel; import de.miaurizius.jgame2d.core.enums.Map; import de.miaurizius.jgame2d.entity.item.*; +import de.miaurizius.jgame2d.entity.monster.OrcMON; import de.miaurizius.jgame2d.entity.npc.MerchantNPC; import de.miaurizius.jgame2d.entity.npc.OldManNPC; import de.miaurizius.jgame2d.entity.monster.GreenSlimeMON; @@ -76,6 +77,11 @@ public class AssetSetter { panel.monster[Map.OVERWORLD.getIndex()][i] = new GreenSlimeMON(panel); panel.monster[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*38; panel.monster[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*42; + + i++; + panel.monster[Map.OVERWORLD.getIndex()][i] = new OrcMON(panel); + panel.monster[Map.OVERWORLD.getIndex()][i].worldX = panel.tileSize*12; + panel.monster[Map.OVERWORLD.getIndex()][i].worldY = panel.tileSize*33; } public void setITiles() { diff --git a/src/de/miaurizius/jgame2d/core/handlers/CollisionHandler.java b/src/de/miaurizius/jgame2d/core/handlers/CollisionHandler.java index ab3d352..785ddfc 100644 --- a/src/de/miaurizius/jgame2d/core/handlers/CollisionHandler.java +++ b/src/de/miaurizius/jgame2d/core/handlers/CollisionHandler.java @@ -1,6 +1,7 @@ package de.miaurizius.jgame2d.core.handlers; import de.miaurizius.jgame2d.core.GamePanel; +import de.miaurizius.jgame2d.core.enums.Direction; import de.miaurizius.jgame2d.entity.Entity; public class CollisionHandler { @@ -25,7 +26,11 @@ public class CollisionHandler { int tileNum1, tileNum2; - switch(entity.direction) { + // TEMP DIRECTION FOR KNOCKBACK + Direction direction = entity.direction; + if(entity.knockback) direction = entity.knockbackDirection; + + switch(direction) { case UP: entityTopRow = (entityTopWorldY - entity.speed)/panel.tileSize; tileNum1 = panel.tileM.mapTileNum[panel.currentMap.getIndex()][entityLeftCol][entityTopRow]; diff --git a/src/de/miaurizius/jgame2d/entity/Entity.java b/src/de/miaurizius/jgame2d/entity/Entity.java index 633f209..c8e3b3b 100644 --- a/src/de/miaurizius/jgame2d/entity/Entity.java +++ b/src/de/miaurizius/jgame2d/entity/Entity.java @@ -14,6 +14,7 @@ import java.awt.image.BufferedImage; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Objects; import java.util.Random; import java.util.logging.Level; @@ -25,6 +26,7 @@ public class Entity { public BufferedImage image, image2, image3; public Rectangle solidArea = new Rectangle(0, 0, 48, 48); public Rectangle attackArea = new Rectangle(0, 0, 0, 0); + public Entity attacker; public int solidAreaDefaultX, solidAreaDefaultY; public boolean collision; protected String[] dialogue = new String[20]; @@ -36,13 +38,14 @@ public class Entity { int dialogueIndex; public boolean collisionOn; public boolean invincible; - boolean attacking; + public boolean attacking; public boolean alive = true; public boolean dying; public boolean hpBarOn; public boolean consumable; public boolean onPath; public boolean knockback; + public Direction knockbackDirection; // COUNTER public int spriteCount; @@ -105,7 +108,7 @@ public class Entity { return; } - switch(panel.player.direction) { + switch(knockbackDirection) { case UP -> worldY -= speed; case DOWN -> worldY += speed; case LEFT ->worldX -= speed; @@ -118,7 +121,7 @@ public class Entity { knockback = false; knockbackCount = 0; speed = defaultSpeed; - } else { + } else if(attacking) attacking(); else { setAction(); checkCollision(); @@ -130,14 +133,14 @@ public class Entity { case RIGHT -> worldX += speed; } } - } - spriteCount++; - if(spriteCount > 24) { - if(spriteNum == 1) spriteNum = 2; - else if(spriteNum == 2) spriteNum = 1; - else spriteNum = 0; - spriteCount = 0; + spriteCount++; + if(spriteCount > 24) { + if(spriteNum == 1) spriteNum = 2; + else if(spriteNum == 2) spriteNum = 1; + else spriteNum = 0; + spriteCount = 0; + } } // INVINCIBLE COUNTER @@ -179,8 +182,9 @@ public class Entity { hpBarCount = 0; changeOpacity(graphics2d, 0.4f); } + //TODO: fix attacking sprite drawing position for monsters 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(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(), (direction == Direction.LEFT) ? screenX - panel.tileSize : screenX, (direction == Direction.UP) ? screenY - panel.tileSize : screenY, null); @@ -199,6 +203,48 @@ public class Entity { // INTERACTION public void setAction() {} public void damageReaction() {} + public void attacking() { + if(panel.player.attackCancel && type == EntityType.PLAYER) return; + spriteCount++; + if(spriteCount <= 5) spriteNum = 1; + if(spriteCount > 5 && spriteCount <= 25) { + spriteNum = 2; + int currentWorldX = worldX; + int currentWorldY = worldY; + int solidAreaWidth = solidArea.width; + int solidAreaHeight = solidArea.height; + + switch(direction) { + case UP -> worldY -= attackArea.height; + case DOWN -> worldY += attackArea.height; + case LEFT -> worldX -= attackArea.width; + case RIGHT -> worldX += attackArea.width; + } + solidArea.width = attackArea.width; + solidArea.height = attackArea.height; + + if(type == EntityType.MONSTER) if(panel.collisionH.checkPlayer(this)) damagePlayer(attackValue); + + if(type == EntityType.PLAYER) { + int monsterIndex = panel.collisionH.checkEntity(this, panel.monster[panel.currentMap.getIndex()]); + panel.player.damageMonster(monsterIndex, this, attack, currentWeapon.knockbackVal); + + int iTileIndex = panel.collisionH.checkEntity(this, panel.iTile[panel.currentMap.getIndex()]); + panel.player.interactTile(iTileIndex); + } + + worldX = currentWorldX; + worldY = currentWorldY; + solidArea.width = solidAreaWidth; + solidArea.height = solidAreaHeight; + + } + if(spriteCount > 25) { + spriteNum = 1; + spriteCount = 0; + attacking = false; + } + } public void damagePlayer(int attack) { if(panel.player.invincible) return; panel.playSE(6); @@ -292,6 +338,12 @@ public class Entity { } return index; } + public void setKnockback(Entity target, Entity attacker, int knockbackVal) { + this.attacker = attacker; + target.knockbackDirection = attacker.direction; + target.speed += knockbackVal; + target.knockback = true; + } // PARTICLE SETUP public Color getParticleColor() { @@ -345,9 +397,10 @@ public class Entity { return Math.abs(worldX - target.worldX); } public int dY(Entity target) { - return Math.abs(worldY - target.worldX); + return Math.abs(worldY - target.worldY); } public int dTile(Entity target) { + if(Objects.equals(name, "orc")) System.out.println("dX: " + dX(target) + " dY: " + dY(target)); return (dX(target) + dY(target)) / panel.tileSize; } public int getGoalCol(Entity target) { @@ -479,10 +532,11 @@ public class Entity { } } public void checkStopChasing(Entity target, int distance, int rate) { - if(dTile(target) > distance) if(new Random().nextInt(rate) == 0) onPath = false; + if(Objects.equals(name, "orc")) System.out.println("dTile: " + dTile(target) + " distance: " + distance); + if(dTile(target) > distance) onPath = false; } public void checkStartChasing(Entity target, int distance, int rate) { - if(dTile(target) < distance) if(new Random().nextInt(rate) == 0) onPath = true; + if(dTile(target) < distance) onPath = true; } public void checkShooting(int rate, int shotInterval) { if(new Random().nextInt(rate) == 0 && projectile.alive == false && shotAvailableCount == shotInterval) { @@ -498,6 +552,34 @@ public class Entity { shotAvailableCount = 0; } } + public void checkAttack(int rate, int straight, int horizontal) { + boolean targetInRange = false; + int xDist = dX(panel.player); + int yDist = dY(panel.player); + + switch(direction) { + case UP -> { + if(panel.player.worldY < worldY && yDist < straight && xDist < horizontal) targetInRange = true; + } + case DOWN -> { + if(panel.player.worldY > worldY && yDist < straight && xDist < horizontal) targetInRange = true; + } + case LEFT -> { + if(panel.player.worldX < worldX && xDist < straight && yDist < horizontal) targetInRange = true; + } + case RIGHT -> { + if(panel.player.worldX > worldX && xDist < straight && yDist < horizontal) targetInRange = true; + } + } + + if(targetInRange) + if (new Random().nextInt(rate) == 0) { + attacking = true; + spriteNum = 1; + spriteCount = 0; + shotAvailableCount = 0; + } + } public void setRandomDirection() { actionLock++; if(actionLock == 120) { //lock action for x frames diff --git a/src/de/miaurizius/jgame2d/entity/Player.java b/src/de/miaurizius/jgame2d/entity/Player.java index bc00189..a035d4b 100644 --- a/src/de/miaurizius/jgame2d/entity/Player.java +++ b/src/de/miaurizius/jgame2d/entity/Player.java @@ -176,45 +176,7 @@ public class Player extends Entity { } } - public void attacking() { - if(attackCancel) return; - spriteCount++; - if(spriteCount <= 5) spriteNum = 1; - if(spriteCount > 5 && spriteCount <= 25) { - spriteNum = 2; - int currentWorldX = worldX; - int currentWorldY = worldY; - int solidAreaWidth = solidArea.width; - int solidAreaHeight = solidArea.height; - - switch(direction) { - case UP -> worldY -= attackArea.height; - case DOWN -> worldY += attackArea.height; - case LEFT -> worldX -= attackArea.width; - case RIGHT -> worldX += attackArea.width; - } - solidArea.width = attackArea.width; - solidArea.height = attackArea.height; - - int monsterIndex = panel.collisionH.checkEntity(this, panel.monster[panel.currentMap.getIndex()]); - damageMonster(monsterIndex, attack, currentWeapon.knockbackVal); - - int iTileIndex = panel.collisionH.checkEntity(this, panel.iTile[panel.currentMap.getIndex()]); - interactTile(iTileIndex); - - worldX = currentWorldX; - worldY = currentWorldY; - solidArea.width = solidAreaWidth; - solidArea.height = solidAreaHeight; - - } - if(spriteCount > 25) { - spriteNum = 1; - spriteCount = 0; - attacking = false; - } - } - public void damageMonster(int index, int attack, int knockbackVal) { + public void damageMonster(int index, Entity attacker, int attack, int knockbackVal) { if(index == 999) return; if(panel.monster[panel.currentMap.getIndex()][index].invincible) return; @@ -222,7 +184,7 @@ public class Player extends Entity { if(damage > 0) { panel.playSE(5); - if(knockbackVal > 0) knockback(panel.monster[panel.currentMap.getIndex()][index], knockbackVal); + if(knockbackVal > 0) setKnockback(panel.monster[panel.currentMap.getIndex()][index], attacker, knockbackVal); panel.monster[panel.currentMap.getIndex()][index].life -= damage; panel.monster[panel.currentMap.getIndex()][index].invincible = true; } @@ -235,11 +197,6 @@ public class Player extends Entity { checkLevelUp(); } } - public void knockback(Entity entity, int knockbackVal) { - entity.direction = direction; - entity.speed += knockbackVal; - entity.knockback = true; - } public void interactTile(int index) { if(index == 999 || !panel.iTile[panel.currentMap.getIndex()][index].destructible || panel.iTile[panel.currentMap.getIndex()][index].invincible) return; diff --git a/src/de/miaurizius/jgame2d/entity/monster/OrcMON.java b/src/de/miaurizius/jgame2d/entity/monster/OrcMON.java new file mode 100644 index 0000000..3e5a437 --- /dev/null +++ b/src/de/miaurizius/jgame2d/entity/monster/OrcMON.java @@ -0,0 +1,83 @@ +package de.miaurizius.jgame2d.entity.monster; + +import de.miaurizius.jgame2d.core.GamePanel; +import de.miaurizius.jgame2d.core.enums.EntityType; +import de.miaurizius.jgame2d.entity.Entity; +import de.miaurizius.jgame2d.entity.item.CoinObj; +import de.miaurizius.jgame2d.entity.item.HeartObj; +import de.miaurizius.jgame2d.entity.item.PotionObj; + +import java.util.Random; + +public class OrcMON extends Entity { + + public OrcMON(GamePanel panel) { + super(panel); + type = EntityType.MONSTER; + name = "orc"; + defaultSpeed = 1; + speed = defaultSpeed; + maxLife = 10; + life = maxLife; + attack = 8; + defense = 2; + exp = 10; + + solidArea.x = 4; + solidArea.y = 4; + solidArea.width = 40; + solidArea.height = 44; + solidAreaDefaultX = solidArea.x; + solidAreaDefaultY = solidArea.y; + + attackArea.width = panel.tileSize; + attackArea.height = panel.tileSize; + + getImage(); + getAttackImage(); + } + + // INTERACTION + public void setAction() { + if(!onPath) checkStartChasing(panel.player, 10 ,100); + checkStopChasing(panel.player, 15, 100); + if(onPath) { + followPlayer(); + return; + } + setRandomDirection(); + if(!attacking) checkAttack(30, panel.tileSize*4, panel.tileSize); + } + public void damageReaction() { + actionLock = 0; + onPath = true; + } + public void checkDrop() { + int i = new Random().nextInt(100)+1; + if(i < 50) dropItem(new CoinObj(panel)); + if(i >= 50 && i < 75) dropItem(new HeartObj(panel)); + if(i >= 75 && i < 100) dropItem(new PotionObj(panel)); + } + + // SETTING THINGS UP + public void getImage() { + up1 = initEntitySprites("monster/orc_up_1"); + up2 = initEntitySprites("monster/orc_up_2"); + down1 = initEntitySprites("monster/orc_down_1"); + down2 = initEntitySprites("monster/orc_down_2"); + left1 = initEntitySprites("monster/orc_left_1"); + left2 = initEntitySprites("monster/orc_left_2"); + right1 = initEntitySprites("monster/orc_right_1"); + right2 = initEntitySprites("monster/orc_right_2"); + } + public void getAttackImage() { + attackUp1 = initEntitySprites("monster/orc_attack_up_1"); + attackUp2 = initEntitySprites("monster/orc_attack_up_2"); + attackDown1 = initEntitySprites("monster/orc_attack_down_1"); + attackDown2 = initEntitySprites("monster/orc_attack_down_2"); + attackLeft1 = initEntitySprites("monster/orc_attack_left_1"); + attackLeft2 = initEntitySprites("monster/orc_attack_left_2"); + attackRight1 = initEntitySprites("monster/orc_attack_right_1"); + attackRight2 = initEntitySprites("monster/orc_attack_right_2"); + } +} diff --git a/src/de/miaurizius/jgame2d/entity/projectile/Projectile.java b/src/de/miaurizius/jgame2d/entity/projectile/Projectile.java index dd3aaae..c952199 100644 --- a/src/de/miaurizius/jgame2d/entity/projectile/Projectile.java +++ b/src/de/miaurizius/jgame2d/entity/projectile/Projectile.java @@ -28,7 +28,7 @@ public class Projectile extends Entity { if(user.type == EntityType.PLAYER) { int monsterIndex = panel.collisionH.checkEntity(this, panel.monster[panel.currentMap.getIndex()]); if(monsterIndex != 999) { - panel.player.damageMonster(monsterIndex, attack, knockbackVal); + panel.player.damageMonster(monsterIndex, this, attack, knockbackVal); generateParticle(user.projectile, panel.monster[panel.currentMap.getIndex()][monsterIndex]); alive = false; } diff --git a/src/de/miaurizius/jgame2d/environment/Lighting.java b/src/de/miaurizius/jgame2d/environment/Lighting.java index a9f5770..471fa03 100644 --- a/src/de/miaurizius/jgame2d/environment/Lighting.java +++ b/src/de/miaurizius/jgame2d/environment/Lighting.java @@ -35,7 +35,7 @@ public class Lighting { } g2.setColor(Color.white); g2.setFont(g2.getFont().deriveFont(50f)); - g2.drawString(s, 800, 500); + g2.drawString(s + " " + dayCount, 700, 500); } } public void update() {