0
\$\begingroup\$

So iam trying to practice java with a text based adventure game. This code gives out an enemy of an array(random) and then gives it a Randoam health between 0 and 100. What I want to do is give each enemy in the array properties like hp or attack damage while having a random enemy "drop".

I thought about doing it with if statements but I did some research and found about getters and setters, but I haven't been able to get it working so I deleted it.

I also thought about doing it with multiple classes but I am just to new to java to get it working.

Here is my code (The base is from a yt video but I added some things like the boss, stats and item drops):

import java.util.Random; import java.util.Scanner;

public class Firstd {

public static void main(String[] args) {
    
    String filepath = "bgmusic.wav";
    String file = "death.wav";
    
    music musicObjekt = new music();
    musicObjekt.playMusic (filepath);
    
    
    //System Objects
    Scanner in = new Scanner(System.in); 
    Random rand = new Random();
    
    //Player variables
    int health = 100; //Start Health
    int attackDamage = 40; //Attack Damage
    int numHealthPots = 3; //Number of Health potions
    int healthPotionHealAmount = 30; //What number of Healing
    int healthPotionDropChance = 60; //Percentage of drops
    int score = 0; // score enemies defeated
    int numpots = 0; //used pots
    int statsdam = 0; // number of damage dealt
    int statsdamtaken = 0; //number of damage taken
    int swordChance = 15; 
    int shieldChance = 15; 
    int bossHealth = 200;
    
    boolean bossDefeated = false;
    boolean swordowned = false;
    boolean shieldowned = false;
    
    //Game variables
    
    String[] enemies = {"Zombie" , "Assasin" , "Giant" , "Skeleton"};
    
    
    
    int maxEnemyHealth = 80;
    
    
    int enemyAttackDamage = 25;
    

    
    boolean running = true;
    
    System.out.println("Welcome to the Dungeon");
    
    GAME: //Label of While Loop (Main Loop)
    while(running) {
        
        
        System.out.println("---------------------------------------------");

            
            int enemyHealth = rand.nextInt(maxEnemyHealth);
            int sword = rand.nextInt(swordChance);
            enemyHealth = enemyHealth += 10;
            
            String enemy = enemies[rand.nextInt(enemies.length)]; //Randoam Enemy from array
            
            System.out.println("\t# " + enemy + " appeared! #\n"); // Tab than # than rand enemy than #
            
            while(enemyHealth > 0) { //When Enemy not dead (0) keep going
            
            System.out.println("\tYour HP: " + health); //All the options aveible
            System.out.println("\t" + enemy + "´s HP: " + enemyHealth);
            System.out.println("\n\tWhat would you like to do?");
            System.out.println("\t1. Attack");
            System.out.println("\t2. Drink health potion");
            System.out.println("\t3. Run!");
            
            String input = in.nextLine(); //Input from User and set cases
            if(input.equals("1")) {
                
                
                int damageDealt = rand.nextInt(attackDamage);
                int damageTake = rand.nextInt(enemyAttackDamage);
                
                enemyHealth -= damageDealt; //Health minus the attack 
                
                if(shieldowned == true) {
                    if (damageTake <= 10) {
                        health -= damageTake;
                    }
                    health -= damageTake - 10;
                            }
                else {
                health -= damageTake;
                }
                
                System.out.println("\t> You strike the " + enemy + " for " + damageDealt + " damage");
                System.out.println("\t> You recived " + damageTake + " in retaliation!\n");
                statsdam += 0 + damageDealt;
                statsdamtaken += 0 + damageTake;
                
                if(health <= 0) {
                    System.out.println("\t> You have taken too much damage, you are too weak to go on!\n");
                    break GAME;
                }
            }
            else if(input.equals("2")) {
                if(numHealthPots > 0) {
                    health += healthPotionHealAmount;
                    numHealthPots --;
                    System.out.println("\t> You drint a health potion, healing yourself for " + healthPotionHealAmount 
                                        + "\n\t> You have now have " + health + " HP."
                                        + "\n\t> You have " + numHealthPots + " health potions left.\n");
                    numpots++;
                }
                else {
                    System.out.println("\t> You have no health potion left! Defeat enemies for a chance to get one!");
                    
                }
            
            }
            else if(input.equals("3")) {
                System.out.println("\t You hava run from the " + enemy + "!"); 
                continue GAME;  //Breakout of the Loop go to above generator a new enemy
                
            }
            else {
                System.out.print("\tWhat are you doing?");
            
                
            }
        
        
            
        

        
    }
        System.out.println("---------------------------------------------");
        System.out.println(" # " + enemy + " was defeated! #");
        System.out.println(" # You have " + health + "HP left. #");
        System.out.println("---------------------------------------------");
    
        System.out.println("---------------------------------------------");
        System.out.println("What would you like to do now?");
        System.out.println("1. Continue fighting");
        System.out.println("2. Exit dungeon");
        System.out.println("---------------------------------------------");
        
        String input5 = in.nextLine(); //Input when input not 1 or 2 say not valid
        
        while(!input5.equals("1") && !input5.equals("2")) {
            System.out.println("What are you doing?");
            input5 = in.nextLine();
        }
        if(input5.equals("1")) {
            System.out.println("You continue on your adventure!");
            continue GAME;
        } 
        else if (input5.equals("2")) {
            System.out.println("You exit the dungeon, successful from your adventure!\n");
            break;
        }
                    if(health < 1) { // if player dead
                    System.out.println("You limp out of the dungeon, weak from battle :(\n");
        
                        music musicObjekt1 = new music();
                        musicObjekt1.playMusic (file);
                
                break;
                    }
        score++;
        
        if(rand.nextInt(100) < swordChance) {
            if(swordowned == true) {
                continue;
            }
            else {
                
            attackDamage += 4 + attackDamage;
            System.out.println("The " + enemy + " dropped a sword! You are know able to make more damage! (+4HP attack damage)\n");
            swordowned = true;
        }
        }
        else {
            continue;
        }
        
        if(rand.nextInt(100) < shieldChance) {
            if(shieldowned == true) {
                continue;
            }
            else {
            System.out.println("The " + enemy + " dropped a shield! You are now more resistent to damage! (-10HP on every attack above 10HP)\n");
            shieldowned = true;
        }
        }
        else {
            continue;
        }
        
        

        
        
        
        
        if (score == 5) {
            System.out.println("---------------------------------------------");
            System.out.println("\tA Boss appeared!");
            System.out.println("\tIt´s a Witch!");
            System.out.println("\tThe Witch has " + bossHealth + "HP!");
            System.out.println("\tYou need to fight, no escape this time!");
            System.out.println("---------------------------------------------");
            
            BOSS:
            while(bossHealth > 0) { //When Enemy not dead (0) keep going
                
            System.out.println("---------------------------------------------");
            System.out.println("\tYour HP: " + health); //All the options avaible
            System.out.println("\tWitch´s HP: " + bossHealth);
            System.out.println("\n\tWhat would you like to do?");
            System.out.println("---------------------------------------------");
            System.out.println("\t1. Attack");
            System.out.println("\t2. Drink health potion");
            System.out.println("---------------------------------------------");
            
            String input1 = in.nextLine();
            if(input1.equals("1")) {
                int damageDealt = rand.nextInt(attackDamage);
                int damageTake = rand.nextInt(enemyAttackDamage);
                
                bossHealth -= damageDealt; //Health minus the attack 
                health -= damageTake;
                
                System.out.println("\t> You strike the Witch for " + damageDealt + " damage");
                System.out.println("\t> You recived " + damageTake + " in retaliation!\n");
                statsdam += 0 + damageDealt;
                statsdamtaken += 0 + damageTake;
                
                if(health < 1) {
                    System.out.println("\t> You have taken too much damage, you are too weak to go on!\n");
                    break BOSS;
            
                }
                if(bossHealth < 1) {
                    System.out.println("#########################");
                    System.out.println("# YOU KILLED THE WITCH! #"); 
                    System.out.println("# YOU RECIVE 2 HEALTH POTS! #"); 
                    System.out.println("#########################");
                    numHealthPots = 2 + numHealthPots;
                    System.out.println("You now own " + numHealthPots + " health potions!");
                    
                    bossDefeated = true;
                    
                    continue;
                }
                
            }
            else if(input1.equals("2")) {
                if(numHealthPots > 0) {
                    health += healthPotionHealAmount;
                    numHealthPots --;
                    System.out.println("\t> You drint a health potion, healing yourself for " + healthPotionHealAmount 
                                        + "\n\t> You have now have " + health + " HP."
                                        + "\n\t> You have " + numHealthPots + " health potions left.\n");
                    numpots++;
                }
                else {
                    System.out.println("\t> You have no health potion left! Defeat enemies for a chance to get one!");
                    
                }
            
            }
            else {
                System.out.print("\tYou can not escape!\t");
            
                
            }
        }

            break;
            
        }
        
        
        
        if(rand.nextInt(100) < healthPotionDropChance) { //Generator a rand number if number less than drop chance than drop a hp
            numHealthPots++;
            System.out.println(" # The " + enemy + " dropped a health potion! # ");
            System.out.println(" # You have " + numHealthPots + " health potion(s). # " );
            
        }
        

    
        
    }
    
    
    System.out.println("#########################");
    System.out.println("# THANKS FOR PLAYING! #");
    //System.out.println("# YOU KILLED " + score + " ENEMIE(S)! #"); // add if when 1 enemy than enemies when more than enemies 
    System.out.println("#########################");
    System.out.println("######### Stats #########");
    if (bossDefeated == true) {
        System.out.println("# You killed the Witch! Congrats!");
    }
    if (score == 0) {
        System.out.println("# You killed no enemy! Weakkk!! #");
    }
    else if (score == 1) {
        System.out.println("# You killed one enemy! #");
    }
    else if (score > 1) {
        System.out.println("# You killed " + score + " enemies! #");
        
    }
    if (swordowned == true) {
        System.out.println("# You found the sword! #");
    }
    else {
        System.out.println("# You did not find the sword :( #");
    }
    if (shieldowned == true) {
        System.out.println("# You found the shield! #");
    }
    else {
        System.out.println("# You did not find the shield :( #");
    }
    System.out.println("# You used " + numpots + " health potions! #");
    System.out.println("# You did " + statsdam + "HP damage to your enemies! #");
    System.out.println("# You took " + statsdamtaken + "HP damage from your enemies! #");
    System.out.println("########################");
    
    
        System.exit(0);
}
}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

If you define a class enemy, like this:

public class Enemy
{
    // …
}

Then, instead of this:

    String[] enemies = {"Zombie" , "Assasin" , "Giant" , "Skeleton"};

You can do this:

    Enemy[] enemies = {new Enemy(), new Enemy(), new Enemy(), new Enemy()};

Oh, wait, we lost the names! So, let us add a name field:

public class Enemy
{
    public String Name;
    // …
}

And now we can do this:

    Enemy Zombie = new Enemy();
    Zombie.Name = "Zombie";

    Enemy Assassin = new Enemy();
    Assassin.Name = "Assassin";

    Enemy Giant = new Enemy();
    Giant.Name = "Giant";

    Enemy Skeleton = new Enemy();
    Skeleton.Name = "Skeleton";
    Enemy[] enemies = {Zombie, Assassin, Giant, Skeleton};

Well, we can do better. Let us define a constructor:

public class Enemy
{
    public String Name;

    public Enemy(String name)
    {
        Name = name;
    }
}

And now we can do this:

    Enemy[] enemies =
    {
        new Enemy("Zombie"),
        new Enemy("Assassin"),
        new Enemy("Giant"),
        new Enemy("Skeleton")
    };

And, as you can imagine, you can add other fields aside form the name for other stats. And you could use getters and setters with private fields instead of having public fields.


Oh, but I need to warn you. There are enemies, and there are enemies. I mean, there is the enemy kind to which multiple enemy units belong, and there is the particular enemy unit that exists in the game world. These should not be the same object.

So, I don't think you should add the current health of the enemy as a field of this class. Well, unless you mean there are only these four enemy units ever.

There are multiple ways to go about this:

  • You could use prototypes. That is, there are actually these four enemy units, but what you do is clone them. I mean, you will have a method on the enemy class that give you back a new object with the same values. And you deploy these cloned objects in the game world.
  • You could use descriptors. That is, there will be an object that has the values that are common to the enemy kind. And the enemy units will copy those values when you create them.
  • You could use composition. Again there will be object that has the values that are common to the enemy kind. But this time you don't copy those values, you reference the object.
  • And yes, some people will push you to use inheritance. Which implies making a new class for each enemy kind. Despite that not being really necessary since they only differ in values. A red car is not a different class of car from a green car, instead its color field has a different value.

I'm going to say composition.

Feel free to explore the other options. Heck, don't lose track of the fact that these are options. And they may have drawbacks down the line. But, in absence of the future (isn't that always?), we resource to the past. And composition often works well - or has often worked well, in the past.

Thus, we will have a class for the enemy, and a class for the enemy kind:

public class EnemyKind
{
    public String Name;
    public int MaxHealth;

    // add fields for other stats
    // change it to getter and setters if you want

    public Enemy(String name, int maxHealth /*, other stuff*/)
    {
        Name = name;
        MaxHealth = maxHealth;
        // other stuff
    }
}

And a class for the enemy unit:

public class EnemyUnit
{
    public EnemyKind Kind;
    public int Health;

    // add fields, you know…

    public EnemyUnit(EnemyKind kind /*, perhaps other stuff*/)
    {
        Kind = kind;
        // Should there be a MinHealth?
        // If you are going to use random here, either:
        //     - Make a singleton Random.
        //     - Or add a Random as a parameter.
        Health = kind.MaxHealth;
        // other stuff
    }
}

And now you can make your array like this:

    EnemyKind[] enemies =
    {
        new EnemyKind("Zombie", 80),
        new EnemyKind("Assassin", 100),
        new EnemyKind("Giant", 110),
        new EnemyKind("Skeleton", 90)
    };

Please notice that the first argument will go into the Name field and the second argument will go into the MaxHealth field. So the numbers above are the max health for these kinds of enemies. Just some values I came up with. In a similar fashion you could specify other stats/attributes.

And when you need to deploy an enemy, you would do something like this:

EnemyUnit enemy = new EnemyUnit(enemies[rand.nextInt(enemies.length)]);
System.out.println("\t# " + enemy.Kind.Name + " appeared! #\n");

You also mention drops. I'm not sure how you want to handle them. However, you could have an array of possible drops defined in EnemyKind. And then pick from the Kind of the enemy that was killed.

\$\endgroup\$
1
  • \$\begingroup\$ @Theroat Thanks a lot, that was exactly what I was looking for. I did the drops like this: If the player attacks a Randoam number is drawn and then it is compared to another value. If the number drawn is in the range that I choose it would give the player more attack damage. But I think doing them in another class would be better if I want to add more items than 2, because my solution is very beginner friendly but it requires a lot of code. \$\endgroup\$
    – vampsz
    Commented Feb 9, 2022 at 8:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .