Files
JGame2D/src/de/miaurizius/jgame2d/entity/Player.java

408 lines
15 KiB
Java

package de.miaurizius.jgame2d.entity;
import de.miaurizius.jgame2d.core.*;
import de.miaurizius.jgame2d.core.enums.Direction;
import de.miaurizius.jgame2d.core.enums.EntityType;
import de.miaurizius.jgame2d.core.enums.GameState;
import de.miaurizius.jgame2d.core.handlers.KeyHandler;
import de.miaurizius.jgame2d.entity.item.KeyObj;
import de.miaurizius.jgame2d.entity.item.ShieldWoodObj;
import de.miaurizius.jgame2d.entity.item.SwordNormalObj;
import de.miaurizius.jgame2d.entity.projectile.FireballObj;
import java.awt.*;
public class Player extends Entity {
KeyHandler keyH;
public final int screenX;
public final int screenY;
// STATE
public boolean attackCancel;
public boolean lightUpdated;
public Player(GamePanel panel, KeyHandler keyH) {
super(panel);
this.keyH = keyH;
name = "player";
type = EntityType.PLAYER;
screenX = panel.screenWidth/2 - panel.tileSize/2;
screenY = panel.screenHeight/2 - panel.tileSize/2;
solidArea = new Rectangle();
solidArea.x = 12;
solidArea.y = 20;
solidAreaDefaultX = solidArea.x;
solidAreaDefaultY = solidArea.y;
solidArea.width = 24;
solidArea.height = 24;
setDefaultValues();
getPlayerImage();
getPlayerAttackImage();
}
// DEFAULT
public void update() {
if(life > maxLife) life = maxLife;
if(attacking) {
attacking();
return;
}
// MOVEMENT
if(keyH.upPressed || keyH.downPressed || keyH.leftPressed || keyH.rightPressed || keyH.spacePressed) {
if(!keyH.spacePressed) {
if(keyH.upPressed) direction = Direction.UP;
else if(keyH.downPressed) direction = Direction.DOWN;
else if(keyH.leftPressed) direction = Direction.LEFT;
else direction = Direction.RIGHT;
}
// CHECK TILE COLLISION
collisionOn = false;
panel.collisionH.checkTile(this);
// CHECK OBJECT COLLISION
int objIndex = panel.collisionH.checkObject(this, true);
pickObject(objIndex);
// CHECK ENTITY COLLISION
int npcIndex = panel.collisionH.checkEntity(this, panel.npc[panel.currentMap.getIndex()]);
interactNPC(npcIndex);
// CHECK MONSTER COLLISION
int monsterIndex = panel.collisionH.checkEntity(this, panel.monster[panel.currentMap.getIndex()]);
interactMonster(monsterIndex);
// CHECK INTERACTIVE TILE COLLISION
int iTileIndex = panel.collisionH.checkEntity(this, panel.iTile[panel.currentMap.getIndex()]);
// CHECK EVENT
panel.eventH.checkEvent();
if(!collisionOn && !keyH.spacePressed) {
switch (direction) {
case UP -> worldY -= speed;
case DOWN -> worldY += speed;
case LEFT ->worldX -= speed;
case RIGHT -> worldX += speed;
}
}
if(keyH.spacePressed && !attackCancel) {
panel.playSE(7);
attacking = true;
spriteCount = 0;
}
attackCancel = false;
panel.keyH.spacePressed = false;
spriteCount++;
if(spriteCount > 12) {
if(spriteNum == 1) spriteNum = 2;
else if(spriteNum == 2) spriteNum = 1;
else spriteNum = 0;
spriteCount = 0;
}
}
if(panel.keyH.shotKeyPressed && !projectile.alive) {
projectile.set(worldX, worldY, direction, true, this);
panel.projectileList.add(projectile);
panel.playSE(10);
}
// INVINCIBLE COUNTER
if(!invincible) return;
invincibleCount++;
if(invincibleCount > 60) {
invincible = false;
invincibleCount = 0;
}
if(life <= 0) {
panel.gameState = GameState.GAMEOVER;
panel.ui.commandNum = -1;
panel.stopMusic();
panel.playSE(12);
}
}
// INTERACTION
public void pickObject(int index) {
if(index == 999 || panel.obj[panel.currentMap.getIndex()][index] == null) return;
// PICKUP ONLY ITEMS
if(panel.obj[panel.currentMap.getIndex()][index].type == EntityType.PICKUP) {
panel.obj[panel.currentMap.getIndex()][index].use(this);
panel.obj[panel.currentMap.getIndex()][index] = null;
return;
}
// OBSTACLES
if(panel.obj[panel.currentMap.getIndex()][index].type == EntityType.OBSTACLE) {
if(!keyH.spacePressed) return;
attackCancel = true;
panel.obj[panel.currentMap.getIndex()][index].interact();
return;
}
// INVENTORY ITEMS
else {
if(!canObtainItem(panel.obj[panel.currentMap.getIndex()][index])) {
panel.ui.addMessage("Your inventory is full!");
return;
}
panel.playSE(1);
panel.ui.addMessage("Picked up " + panel.obj[panel.currentMap.getIndex()][index].name + "!");
}
panel.obj[panel.currentMap.getIndex()][index] = null;
}
public void interactMonster(int index) {
if(index == 999) return;
if(invincible || panel.monster[panel.currentMap.getIndex()][index].dying || !panel.monster[panel.currentMap.getIndex()][index].alive) return;
int damage = panel.monster[panel.currentMap.getIndex()][index].attack - defense;
if(damage > 0) {
panel.playSE(6);
life -= damage;
invincible = true;
}
}
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) {
if(index == 999) return;
if(panel.monster[panel.currentMap.getIndex()][index].invincible) return;
int damage = attack - panel.monster[panel.currentMap.getIndex()][index].defense;
if(damage > 0) {
panel.playSE(5);
if(knockbackVal > 0) knockback(panel.monster[panel.currentMap.getIndex()][index], knockbackVal);
panel.monster[panel.currentMap.getIndex()][index].life -= damage;
panel.monster[panel.currentMap.getIndex()][index].invincible = true;
}
panel.monster[panel.currentMap.getIndex()][index].damageReaction();
if(panel.monster[panel.currentMap.getIndex()][index].life <= 0) {
panel.monster[panel.currentMap.getIndex()][index].dying = true;
panel.ui.addMessage("Gained +" + panel.monster[panel.currentMap.getIndex()][index].exp + " XP!");
exp += panel.monster[panel.currentMap.getIndex()][index].exp;
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;
if(!panel.iTile[panel.currentMap.getIndex()][index].meetItemReq(this)) return;
panel.iTile[panel.currentMap.getIndex()][index].playSE();
panel.iTile[panel.currentMap.getIndex()][index].life--;
panel.iTile[panel.currentMap.getIndex()][index].invincible = true;
generateParticle(panel.iTile[panel.currentMap.getIndex()][index], panel.iTile[panel.currentMap.getIndex()][index]);
if(panel.iTile[panel.currentMap.getIndex()][index].life == 0) panel.iTile[panel.currentMap.getIndex()][index] = panel.iTile[panel.currentMap.getIndex()][index].getDestroyedForm();
}
public void interactNPC(int index) {
if(index == 999) return;
//if(!panel.keyH.spacePressed) return; //Only uncomment if text should only appear if player hits space
attackCancel = true;
panel.gameState = GameState.DIALOGUE;
panel.npc[panel.currentMap.getIndex()][index].speak();
}
public void speak() {
//This method only exists for character specific things later...
super.speak();
}
// BACKGROUND JOBS
public void checkLevelUp() {
if(exp < nextLevelExp) return;
level++;
nextLevelExp = nextLevelExp*2;
maxLife += 2;
strength++;
dexterity++;
attack = getAttack();
defense = getDefense();
panel.playSE(8);
panel.gameState = GameState.DIALOGUE;
panel.ui.currentDialogue = "You are level " + level + " now!\nYou feel stronger!";
}
public void selectItem() {
int itemIndex = panel.ui.getItemIndex(panel.ui.playerSlotCol, panel.ui.playerSlotRow);
if(itemIndex >= inventory.size()) return;
Entity selectedItem = inventory.get(itemIndex);
if(selectedItem.type == EntityType.WEAPON) {
currentWeapon = selectedItem;
getAttack();
getPlayerAttackImage();
}
if(selectedItem.type == EntityType.SHIELD) {
currentShield = selectedItem;
getDefense();
}
if(selectedItem.type == EntityType.LIGHT) {
if(currentLight == selectedItem) currentLight = null; else currentLight = selectedItem;
lightUpdated = true;
}
if(selectedItem.consumable)
if(selectedItem.use(this))
if(selectedItem.amt > 1) selectedItem.amt--; else inventory.remove(selectedItem);
}
public void setDefaultPositions() {
worldX = panel.tileSize * 23;
worldY = panel.tileSize * 21;
direction = Direction.DOWN;
}
public void restoreLife() {
life = maxLife;
invincible = false;
}
// SETTING THINGS UP
public void setDefaultValues() {
worldX = panel.tileSize * 23;
worldY = panel.tileSize * 21;
defaultSpeed = 4;
speed = defaultSpeed;
direction = Direction.DOWN;
// PLAYER STATUS (1 heart = 2 lives)
maxLife = 6;
life = maxLife;
level = 1;
strength = 1;
dexterity = 1;
exp = 0;
nextLevelExp = 5;
coins = 500;
currentWeapon = new SwordNormalObj(panel);
currentShield = new ShieldWoodObj(panel);
projectile = new FireballObj(panel);
attack = getAttack();
defense = getDefense();
// INVENTORY
inventory.clear();
inventory.add(currentWeapon);
inventory.add(currentShield);
inventory.add(new KeyObj(panel));
}
public int getAttack() {
attackArea = currentWeapon.attackArea;
return attack = strength * currentWeapon.attackValue;
}
public int getDefense() {
return defense = dexterity * currentShield.defenseValue;
}
public void getPlayerImage() {
up1 = initEntitySprites("player/boy_up_1");
up2 = initEntitySprites("player/boy_up_2");
down1 = initEntitySprites("player/boy_down_1");
down2 = initEntitySprites("player/boy_down_2");
left1 = initEntitySprites("player/boy_left_1");
left2 = initEntitySprites("player/boy_left_2");
right1 = initEntitySprites("player/boy_right_1");
right2 = initEntitySprites("player/boy_right_2");
}
public void getPlayerAttackImage() {
switch(currentWeapon.weaponType) {
case SWORD:
attackUp1 = initEntitySprites("player/attack/boy_attack_up_1", panel.tileSize, panel.tileSize * 2);
attackUp2 = initEntitySprites("player/attack/boy_attack_up_2", panel.tileSize, panel.tileSize * 2);
attackDown1 = initEntitySprites("player/attack/boy_attack_down_1", panel.tileSize, panel.tileSize * 2);
attackDown2 = initEntitySprites("player/attack/boy_attack_down_2", panel.tileSize, panel.tileSize * 2);
attackLeft1 = initEntitySprites("player/attack/boy_attack_left_1", panel.tileSize * 2, panel.tileSize);
attackLeft2 = initEntitySprites("player/attack/boy_attack_left_2", panel.tileSize * 2, panel.tileSize);
attackRight1 = initEntitySprites("player/attack/boy_attack_right_1", panel.tileSize * 2, panel.tileSize);
attackRight2 = initEntitySprites("player/attack/boy_attack_right_2", panel.tileSize * 2, panel.tileSize);
break;
case AXE:
attackUp1 = initEntitySprites("player/attack/boy_axe_up_1", panel.tileSize, panel.tileSize * 2);
attackUp2 = initEntitySprites("player/attack/boy_axe_up_2", panel.tileSize, panel.tileSize * 2);
attackDown1 = initEntitySprites("player/attack/boy_axe_down_1", panel.tileSize, panel.tileSize * 2);
attackDown2 = initEntitySprites("player/attack/boy_axe_down_2", panel.tileSize, panel.tileSize * 2);
attackLeft1 = initEntitySprites("player/attack/boy_axe_left_1", panel.tileSize * 2, panel.tileSize);
attackLeft2 = initEntitySprites("player/attack/boy_axe_left_2", panel.tileSize * 2, panel.tileSize);
attackRight1 = initEntitySprites("player/attack/boy_axe_right_1", panel.tileSize * 2, panel.tileSize);
attackRight2 = initEntitySprites("player/attack/boy_axe_right_2", panel.tileSize * 2, panel.tileSize);
break;
}
}
public int searchItemInInventory(String itemName) {
for(int i = 0; i < inventory.size(); i++) {
if(inventory.get(i).name.equals(itemName)) {
return i;
}
}
return 999;
}
public boolean canObtainItem(Entity item) {
int i = searchItemInInventory(item.name);
if(item.stackable) {
if(i != 999) {
inventory.get(i).amt++;
return true;
} else if(inventory.size() != maxInvSize) {
inventory.add(item);
return true;
}
} else if(inventory.size() != maxInvSize) {
inventory.add(item);
return true;
}
return false;
}
}