Complete game

This commit is contained in:
2026-05-15 23:50:32 +03:30
parent 0e04d8a1a2
commit aac9687228
42 changed files with 403 additions and 179 deletions
+189 -26
View File
@@ -19,22 +19,20 @@ public class Main {
Enemy goblin = new Goblin();
Enemy skeleton = new Skeleton();
Enemy vampire = new Vampire();
Enemy dragon = new Dragon();
Enemy[] enemies = {goblin, vampire, skeleton}; // An array of the enemies except Dragon which is the final boss
// Locations, one for each enemy
Location forest = new Location("Whispering forest", goblin);
Location catacombs = new Location("forgotten catacombs", skeleton);
Location castle = new Location("crimson castle", vampire);
Location peak = new Location("ashen peak", dragon);
Location[] locations = {forest, catacombs, castle}; // An array of the location except peak where is the Dragon(final boss) located
System.out.println(" =============== Java Knight ===============\n");
System.out.println("\t=============== Java Knight ===============\n");
boolean running = true;
while(running){
System.out.println(" Choose your option:");
System.out.println(" 1. Start game" +
System.out.println("\tChoose your option:");
System.out.println("\t1. Start game" +
" 2. Exit");
int option = scanner.nextInt();
if(option == 1){
@@ -56,34 +54,34 @@ public class Main {
Random random = new Random();
// Set up
System.out.print(" Enter your name: ");
System.out.print("\tEnter your name: ");
String name = scanner.next();
Player player = null;
int option = 0;
while(option > 3 || option < 1){
System.out.println("\n Select your character: (Enter number)");
System.out.println(" 1. Knight" +
" 2. Assassin" +
" 3. Wizard");
System.out.println("\t1. Knight (fights with a sword)\n" +
"\t2. Assassin (fights with dual daggers)\n" +
"\t3. Wizard (fights with his magic staff)");
if (scanner.hasNextInt()) {
option = scanner.nextInt();
} else {
System.out.println(" Invalid input! Please enter a number.");
System.out.println("\tInvalid input! Please enter a number.");
scanner.next();
}
}
switch (option){
case 1:
player = new Knight(name);
System.out.printf("Your Character: %s, Your Name: %s\n", "Knight", player.getName());
System.out.printf("\n\tYour Character: %s, Your Name: %s\n\n", "Knight", player.getName());
break;
case 2:
player = new Assassin(name);
System.out.printf("Your Character: %s, Your Name: %s\n", "Assassin", player.getName());
System.out.printf("\n\tYour Character: %s, Your Name: %s\n\n", "Assassin", player.getName());
break;
case 3:
player = new Wizard(name);
System.out.printf("\nYour Character: %s, Your Name: %s\n\n", "Wizard", player.getName());
System.out.printf("\n\tYour Character: %s, Your Name: %s\n\n", "Wizard", player.getName());
break;
default:
player = null;
@@ -94,21 +92,74 @@ public class Main {
// Choosing location and enemy
Location loc = locations[random.nextInt(locations.length)];
loc = setLocation(loc, locations, player, random, scanner);
System.out.println(" =============== Prepare to fight ===============");
Enemy enemy = loc.getEnemy();
System.out.println("\t=============== Prepare to fight ===============");
while(player.isAlive()){
while(enemy.isAlive()){
playerMove(player, enemy, scanner);
if(!enemy.isStunned() && enemy.getAlive()) {
enemyMove(enemy, player, random);
}
else{
enemy.stun(false);
}
}
player.addXP(30);
enemy.heal();
// Key dropping (50% chance)
boolean[] logics = {false, true};
boolean drop = true;
if(enemy.hasKey() && drop){
player.addKey(enemy);
}
// resetting player and enemy for the next battle
player.fillMana();
enemy.fillHP();
// the final battle, Dragon fight
if(player.getKeys() == 3){
System.out.println("\t=============== Entering Ashen Peak to fight the Dragon ===============");
enemy = new Dragon();
loc = new Location("ashen peak", enemy);
while(enemy.isAlive() && player.isAlive()){
playerMove(player, enemy, scanner);
if(!enemy.isStunned() && enemy.isAlive()) {
enemyMove(enemy, player, random);
}
else{
enemy.stun(false);
}
}
break;
}
else{
loc = setLocation(loc, locations, player, random, scanner);
enemy = loc.getEnemy();
}
}
}
public static Location setLocation(Location currentLocation, Location[] locations, Player player, Random random, Scanner scanner){
System.out.printf(" %s should fight %s in %s\n", player.getName(), currentLocation.getEnemy().getName(), currentLocation.getName());
System.out.printf("\t%s should fight %s who fights with %s in %s\n",
player.getName(), currentLocation.getEnemy().getName(), currentLocation.getEnemy().getWeapon().getName(), currentLocation.getName());
int option = 0;
while(option > 3 || option < 1){
System.out.println(" Choose your option: ");
System.out.println(" 1. Fight " + currentLocation.getEnemy().getName() +
" 2. Change location");
while(option > 2 || option < 1){
System.out.println("\tChoose your option: ");
System.out.println("\t1. Fight " + currentLocation.getEnemy().getName() +
"\t2. Change location");
if (scanner.hasNextInt()) {
option = scanner.nextInt();
} else {
System.out.println(" Invalid input! Please enter a number.");
System.out.println("\tInvalid input! Please enter a number.");
scanner.next();
}
}
@@ -116,7 +167,7 @@ public class Main {
if(option == 1){
return currentLocation;
}
else if(option == 2){
else{
Location[] temp_locations = new Location[locations.length - 1];
int counter = 0;
for(Location l : locations){
@@ -126,14 +177,126 @@ public class Main {
}
}
currentLocation = temp_locations[random.nextInt(temp_locations.length)];
System.out.println(" Changing locations...");
setLocation(currentLocation, locations, player, random, scanner);
}
else{
System.out.println(" Invalid input! Try again.");
System.out.println("\tChanging locations...\n");
setLocation(currentLocation, locations, player, random, scanner);
}
return currentLocation;
}
public static void playerMove(Player player, Enemy enemy, Scanner scanner){
player.defend(false);
int option = 0;
while(option > 5 || option < 1){
System.out.println("\n Your turn. Choose your move: \n" +
" 1. Light attack" +
" 2. Heavy attack" +
" 3. Defend" +
" 4. Heal" +
" 5. Special Ability");
if (scanner.hasNextInt()) {
option = scanner.nextInt();
if(option != 1 && player.getMp() <= 0){ // when mana runs out the only available action is light attack
System.out.println("\tYou are out of Mana. You can only choose \"1. Light attack\"");
option = 0;
}
else if(option == 4 && player.getHp() == player.getMaxHP()){
System.out.println("\tYour HP is at its maximum. Choose another option.");
option = 0;
}
} else {
System.out.println("\tInvalid input! Please enter a number.");
scanner.next();
}
}
switch (option){
case 1: // light attack
if(!enemy.isDefending()){
player.lightAttack(enemy);
}
break;
case 2: // heavy attack
if(player.getMp() >= player.getWeapon().getManaCost()) {
player.heavyAttack(enemy);
}
else{
System.out.println("\tYou don\'t have enough Mana");
playerMove(player, enemy, scanner);
}
break;
case 3: // defend
if(player.getMp() >= player.getDefendMP()) {
player.defend(true);
}
else{
System.out.println("\tYou don\'t have enough Mana");
playerMove(player, enemy, scanner);
}
break;
case 4: // heal
if(player.getMp() >= player.getDefendMP()) {
player.heal( (int)((0.2)*player.getMaxHP()) );
}
else{
System.out.println("\tYou don\'t have enough Mana");
playerMove(player, enemy, scanner);
}
break;
case 5: // special ability
if(player.getMp() >= player.getSpecialAbilityMP()) {
player.specialAbility(enemy);
}
else{
System.out.println("\tYou don\'t have enough Mana");
playerMove(player, enemy, scanner);
}
break;
}
showStatus(player, enemy);
}
public static void enemyMove(Enemy enemy, Player player, Random random){
enemy.defend(false);
enemy.stun(false); // have been checked before calling this method
System.out.println("\t" + enemy.getName() + "'s turn: ");
int move_id = random.nextInt(5) + 1;
switch (move_id){
case 1: // attack (light attack)
enemy.attack(player);
break;
case 2: // special ability (heavy attack)
if(enemy instanceof Skeleton && enemy.isRevived()){
enemyMove(enemy, player, random);
}
enemy.specialAbility(player);
break;
case 3: // defend
enemy.defend(true);
break;
case 4: // heal
enemy.heal( (int)((0.2)*player.getMaxHP()) );
break;
}
showStatus(player, enemy);
}
public static void showStatus(Player player, Enemy enemy){
System.out.printf("\t[%s - %d/%d HP | %d/%d Mana]\t[%s - %d/%d HP]\n\n",
player.getName(), player.getHp(), player.getMaxHP(), player.getMp(), player.getMaxMP(),
enemy.getName(), enemy.getHp(), enemy.getMaxHP()
);
}
}
@@ -4,7 +4,9 @@ public interface Entity {
void specialAbility(Entity target);
void defend();
void defend(boolean value);
boolean isDefending();
void heal(int health);
@@ -14,6 +16,8 @@ public interface Entity {
void stun(boolean value);
void dodge(boolean value);
String getName();
boolean isAlive();
}
@@ -16,22 +16,16 @@ public class Dragon extends Enemy{
@Override
public void attack(Entity target) {
System.out.printf("\t%s attacks!\n", getName());
target.takeDamage(28);
}
@Override
public void specialAbility(Entity target) {
System.out.printf("\t%s breathes fire!\n", getName());
target.takeDamage(weapon.getDamage());
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP;
}
}
public int getMaxHP() {
return maxHP;
}
@@ -41,4 +35,13 @@ public class Dragon extends Enemy{
return "Dragon";
}
@Override
public boolean isAlive() {
if(hp <= 0){
System.out.printf("\t=============== Victory! ===============\n", getName());
alive = false;
}
return alive;
}
}
@@ -6,28 +6,60 @@ import org.project.item.weapons.Weapon;
public abstract class Enemy implements Entity {
Weapon weapon;
protected int hp;
private boolean defending = false;
protected boolean lifeStealing = false;
protected int maxHP;
protected boolean defending = false;
private boolean stunned = false;
private boolean dodged = false;
protected boolean revived = false;
protected boolean alive = true;
protected boolean key = true;
public Enemy(int hp, Weapon weapon) {
this.hp = hp;
maxHP = hp; // TODO: fix this from superclasses
this.weapon = weapon;
}
@Override
public void takeDamage(int damage) {
hp -= damage;
System.out.printf("\t%s took %d damage\n", getName(), damage);
}
public void attack(Entity target) {
System.out.printf("\t%s used Light Attack!\n", getName());
if(target.isDefending()){
System.out.printf("\t%s is defending. %s lost his attack.\n", target.getName(), getName());
return;
}
target.takeDamage(weapon.getDamage());
}
@Override
public void defend() {
defending = true;
public void defend(boolean value) {
if(value) {
System.out.printf("\t%s used Defend, You cannot attack in your next turn!\n", getName());
defending = true;
return;
}
defending = false;
}
@Override
public void heal(int health) {
System.out.printf("\t%s used Heal!\n", getName());
hp += health;
if (hp > maxHP) {
hp = maxHP;
}
}
public void heal(){
hp = maxHP;
alive = true;
}
public void fillHP(){
hp = maxHP;
}
@Override
@@ -35,31 +67,55 @@ public abstract class Enemy implements Entity {
stunned = value;
}
@Override
public void dodge(boolean value) {
dodged = value;
public void dropKey(){
key = false;
}
public int getHp() {
return hp;
}
public int getMaxHP() {
return maxHP;
}
public Weapon getWeapon() {
return weapon;
}
@Override
public boolean isDefending() {
return defending;
}
public boolean isLifeStealing() {
return lifeStealing;
}
public boolean isStunned() {
return stunned;
}
public abstract String getName();
public boolean isRevived() {
return revived;
}
public boolean hasKey() {
return key;
}
@Override
public boolean isAlive() {
if(hp <= 0){
System.out.printf("\t=============== You defeated %s ===============\n\tGoing to the next Location...", getName());
alive = false;
}
return alive;
}
public boolean getAlive(){
if(hp <= 0){
alive = false;
}
return alive;
}
}
@@ -17,15 +17,12 @@ public class Goblin extends Enemy{
@Override
public void specialAbility(Entity target) {
target.takeDamage(criticalHit_damage);
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP;
if(target.isDefending()){
System.out.printf("\t%s is defending. %s lost his attack.\n", target.getName(), getName());
return;
}
System.out.printf("\t%s used critical hit!\n", getName());
target.takeDamage(criticalHit_damage);
}
public int getMaxHP() {
@@ -16,15 +16,9 @@ public class Skeleton extends Enemy{
@Override
public void specialAbility(Entity target) {
hp = maxHP/2; // revive
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP;
}
System.out.printf("\t%s revived itself!\n", getName());
hp = maxHP/2; // revive (once per battle)
revived = true;
}
public int getMaxHP() {
@@ -16,17 +16,9 @@ public class Vampire extends Enemy{
@Override
public void specialAbility(Entity target) {
lifeStealing = true;
target.takeDamage((8/10)*(weapon.getDamage()));
hp += (int)((2/10)*(weapon.getDamage()));
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP;
}
System.out.printf("\t%s used life steal ability!\n", getName());
target.takeDamage((int)((0.8)*(weapon.getDamage())));
hp += (int)((0.2)*(weapon.getDamage()));
}
public int getMaxHP() {
@@ -7,26 +7,28 @@ import org.project.item.weapons.Weapon;
public class Assassin extends Player {
protected String name;
Weapon weapon;
private static final int maxHP = 110;
private static final int maxMP = 110;
public Assassin(String name){
Weapon AssassinWeapon = new DualDagger();
super(name, maxHP, maxMP, AssassinWeapon);
specialAbilityMP = 30;
}
@Override
public void lightAttack(Entity target) {
super.lightAttack(target);
System.out.printf("\t%s used Light Attack! (%d Mana)\n", name, 0);
target.takeDamage(18);
}
@Override
public void specialAbility(Entity target) {
System.out.printf("\t%s used Special Ability! Enemy gets hit critically (%d Mana)\n", name, 30);
target.takeDamage(52); // critical attack
this.mp -= 30;
dodge(true);
this.mp -= specialAbilityMP;
defending = true; // dodging (becomes invisible), technically does what Defend does.
}
}
@@ -7,26 +7,31 @@ import org.project.item.weapons.Weapon;
public class Knight extends Player {
protected String name;
Weapon weapon;
private static final int maxHP = 130;
private static final int maxMP = 70;
public Knight(String name){
Weapon knightWeapon = new Sword();
super(name, maxHP, maxMP, knightWeapon);
specialAbilityMP = 25;
}
@Override
public void lightAttack(Entity target) {
super.lightAttack(target);
System.out.printf("\t%s used Light Attack! (%d Mana)\n", name, 0);
target.takeDamage(22);
}
@Override
public void specialAbility(Entity target) {
System.out.printf("\t%s used Special Ability! Enemy misses its next turn. (%d Mana)\n", name, 25);
target.takeDamage(30);
this.mp -= 25;
this.mp -= specialAbilityMP;
target.stun(true);
}
}
@@ -1,51 +1,76 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.entity.enemies.Enemy;
import org.project.item.weapons.Weapon;
public abstract class Player implements Entity {
protected String name;
Weapon weapon;
protected int hp;
private int maxHP;
protected int maxHP;
protected int mp;
private int maxMP;
private int xp;
private boolean defending = false;
protected int maxMP;
protected boolean defending = false;
private boolean stunned = false;
private boolean dodged = false;
protected int keys;
protected boolean alive = true;
protected final int defendMP = 20;
protected int specialAbilityMP;
public Player(String name, int hp, int mp, Weapon weapon) {
this.name = name;
this.hp = hp;
maxHP = hp;
this.mp = mp;
maxMP = mp;
this.weapon = weapon;
}
public void lightAttack(Entity target){
if(target.isDefending()){ // check if enemy is defending or not
System.out.printf("\t%s is Defending. You missed your attack.\n", target.getName());
return;
}
}
public void heavyAttack(Entity target){ // Uses weapons
if(target.isDefending()){ // check if enemy is defending or not
System.out.printf("\t%s is Defending. You missed your attack.\n", target.getName());
return;
}
System.out.printf("\t%s used Heavy Attack! (%d Mana)\n", name, weapon.getManaCost());
target.takeDamage(weapon.getDamage());
mp -= weapon.getManaCost();
}
public abstract void lightAttack(Entity target);
@Override
public void defend() {
defending = true;
public void defend(boolean value) {
if(value){
System.out.printf("\t%s used Defend, Enemy cannot attack in his next turn! (%d Mana)\n", name, 20);
mp -= 20;
defending = true;
return;
}
defending = false;
}
@Override
public void takeDamage(int damage) {
hp -= damage;
System.out.printf("\t%s took %d damage\n", name, damage);
}
@Override
public void heal(int health) {
System.out.printf("\t%s used Heal! (%d Mana)\n", name, 20);
hp += health;
if (hp > maxHP) {
hp = maxHP;
}
mp -= 20;
}
@Override
@@ -53,16 +78,22 @@ public abstract class Player implements Entity {
stunned = value;
}
@Override
public void dodge(boolean value) {
dodged = value;
public void fillMana() {
mp = maxMP;
hp = maxHP;
}
public void fillMana(int mana) {
mp += mana;
if (mp > maxMP) {
mp = maxMP;
}
public void addKey(Enemy target){
keys++;
target.dropKey();
System.out.printf("\t%s gained %s's key! gained keys: %d\n\n", getName(), target.getName(), keys);
}
public void addXP(int xp){
System.out.printf("\t%d XP added.\n", xp);
maxMP += xp;
maxHP += xp;
}
@@ -91,11 +122,29 @@ public abstract class Player implements Entity {
return weapon;
}
@Override
public boolean isDefending() {
return defending;
}
public boolean isDodged() {
return dodged;
public int getKeys() {
return keys;
}
public int getDefendMP() {
return defendMP;
}
public int getSpecialAbilityMP() {
return specialAbilityMP;
}
@Override
public boolean isAlive() {
if(hp <= 0){
System.out.println("\t=============== Game Over ===============");
alive = false;
}
return alive;
}
}
@@ -7,26 +7,28 @@ import org.project.item.weapons.Weapon;
public class Wizard extends Player {
protected String name;
Weapon weapon;
private static final int maxHP = 150;
private static final int maxMP = 85;
public Wizard(String name){
Weapon WizardWeapon = new MagicStaff();
super(name, maxHP, maxMP, WizardWeapon);
specialAbilityMP = 28;
}
@Override
public void lightAttack(Entity target) {
super.lightAttack(target);
System.out.printf("\t%s used Light Attack! (%d Mana)\n", name, 0);
target.takeDamage(16);
}
@Override
public void specialAbility(Entity target) {
target.takeDamage(32); // cast spell
this.mp -= 28;
System.out.printf("\t%s used Special Ability! Casting spell. (%d Mana)\n", name, 28);
target.takeDamage(32); // casts spell
this.mp -= specialAbilityMP;
heal(15);
}
}
@@ -1,42 +0,0 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Armor {
private int defense;
private int maxDefense;
private int durability;
private int maxDurability;
private boolean isBroke;
public Armor(int defense, int durability) {
this.defense = defense;
this.durability = durability;
}
public void checkBreak() {
if (durability <= 0) {
isBroke = true;
defense = 0;
}
}
// TODO: (BONUS) UPDATE THE REPAIR METHOD
public void repair() {
isBroke = false;
defense = maxDefense;
durability = maxDurability;
}
public int getDefense() {
return defense;
}
public int getDurability() {
return durability;
}
public boolean isBroke() {
return isBroke;
}
}
@@ -1,6 +0,0 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public class KnightArmor {
// TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
}
@@ -1,8 +0,0 @@
package org.project.item.consumables;
// TODO: UPDATE IMPLEMENTATION
public abstract class Consumable {
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
}
@@ -1,16 +0,0 @@
//package org.project.item.consumables;
//
//import org.project.entity.Entity;
//
//// TODO: UPDATE IMPLEMENTATION
//public class Flask {
// /*
// THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN.
// */
//
// // TODO: UPDATE USE METHOD
// @Override
// public void use(Entity target) {
// target.heal(target.getMaxHP() / 10);
// }
//}
@@ -10,4 +10,8 @@ public class Bite extends Weapon {
super(damage, 0);
}
@Override
public String getName() {
return "Bite";
}
}
@@ -10,4 +10,8 @@ public class BoneClub extends Weapon {
super(damage, 0);
}
@Override
public String getName() {
return "Bone Club";
}
}
@@ -10,4 +10,8 @@ public class Dagger extends Weapon {
super(damage, 0);
}
@Override
public String getName() {
return "Daggers";
}
}
@@ -11,4 +11,8 @@ public class DualDagger extends Weapon {
super(damage, manaCost);
}
@Override
public String getName() {
return "Dual Daggers";
}
}
@@ -10,4 +10,8 @@ public class Flame extends Weapon {
super(damage, 0);
}
@Override
public String getName() {
return "Flame";
}
}
@@ -11,4 +11,8 @@ public class MagicStaff extends Weapon {
super(damage, manaCost);
}
@Override
public String getName() {
return "Magic Staff";
}
}
@@ -11,4 +11,8 @@ public class Sword extends Weapon {
super(damage, manaCost);
}
@Override
public String getName() {
return "Sword";
}
}
@@ -26,5 +26,6 @@ public abstract class Weapon implements Item {
return manaCost;
}
public abstract String getName();
}
Binary file not shown.