I'm in the process of writing a text-based RPG in Java using object-oriented programming. I'm fairly new to programming and currently learning through CodeHS and coding this within their sandbox, any help would be greatly appreciated.
My biggest struggle is with the relationship between the Player
and Enemy
class and how those relate to the Creature class. Methods such as roleToNumber()
also seem to not be the best way to do things, but I'm not sure as to how I could implement a similar system in an easier way.
This is the class that handles inputs and outputs as well as creating the encounters and battle phases:
import java.util.Scanner; public class MyProgram extends ConsoleProgram { public void run() { Scanner readName = new Scanner(System.in); System.out.print("Enter your name: "); String userName = readName.nextLine(); Scanner readRole = new Scanner(System.in); System.out.print("Choose your role (Fighter, Ranger, Arcanist): "); String userRole = readRole.nextLine(); while(true){ if(userRole.equalsIgnoreCase("Fighter") || userRole.equalsIgnoreCase("Ranger") || userRole.equalsIgnoreCase("Arcanist")){ break; }else{ System.out.println("Choose a valid role"); readRole = new Scanner(System.in); System.out.print("Choose your role (Fighter, Ranger, Arcanist): "); userRole = readRole.nextLine(); } } //a demo of all of the systems System.out.println(""); Player player = new Player(userName, userRole); scene(player, "a mansion"); if(!player.isDead()){ scene(player, "a rock"); } } public String attack(Creature one, Creature two){ int a = one.attack(two); return one.getName() + " hit " + two.getName() + " for " + a + " damage."; } public void battle(Player one, Creature two){ System.out.println(one); System.out.println(two); while(true){ Scanner readChoice = new Scanner(System.in); System.out.print("\nWhat do you want to do (Attack, Run, Status, Use Potion): "); String userChoice = readChoice.nextLine(); while(true){ if(!userChoice.equalsIgnoreCase("Status") && !userChoice.equalsIgnoreCase("Run") && !userChoice.equalsIgnoreCase("Attack") && !userChoice.equalsIgnoreCase("Use Potion")){ System.out.println("Choose a valid choice"); readChoice = new Scanner(System.in); System.out.print("\nWhat do you want to do (Attack, Run, Status, Use Potion): "); userChoice = readChoice.nextLine(); }else{ break; } } if(userChoice.equalsIgnoreCase("Status")){ System.out.println(one.status()); continue; } if(userChoice.equalsIgnoreCase("Use Potion")){ System.out.println(one.useHealthPotion()); System.out.println(one.status()); continue; } if(userChoice.equalsIgnoreCase("Run")){ int run = (int)(Math.random() * 100 + 1); if(run >= 50){ System.out.println("You successfully run."); break; }else{ System.out.println("You fail at running."); } }else if(userChoice.equalsIgnoreCase("Attack")){ System.out.println(attack(one, two)); System.out.println(two.status()); } if(!two.isDead()){ System.out.println(attack(two, one)); System.out.println(one.status()); if(one.isDead()){ System.out.println("You died!"); break; } }else{ System.out.println("You killed " + two.getName() + "\n"); System.out.println("You gained " + one.gainXp(two) + " exp"); if(one.checkXp()){ System.out.println("You leveled up, your health is restored!"); System.out.println("You have " + one.getXp() + " exp"); }else{ System.out.println("You have " + one.getXp() + " exp"); } System.out.println(one + "\n"); break; } } } public void scene(Player one, String description){ System.out.println(one.getName() + " arrives at " + description); int x = (int)(Math.random() * 3 + 1); for(int i = 0; i < x; i++){ if(one.isDead()){ break; } Enemy randEnemy = new Enemy(one.getLevel()); System.out.println("\nYou encounter " + randEnemy.getName() + " the " + randEnemy.getRole()); battle(one, randEnemy); } } }
This the Creature
class which has basic functions shared between Players
and Enemies
:
public class Creature{ public String name; public String role; public int maxHp; public int maxAtt; public int minAtt; public int level; public int curHp; public Creature(String name, String role){ this.name = name; this.role = role; } public int attack(Creature other){ int att = (int)(Math.random() * (this.maxAtt - this.minAtt + 1) + this.minAtt); other.curHp -= att; return att; } public boolean isDead(){ if(this.curHp <= 0){ return true; }else{ return false; } } public int getCurHp(){ return curHp; } public void setCurHp(int hp){ if(hp >= maxHp - curHp){ curHp = maxHp; }else{ curHp = hp; } } public String getName(){ return name; } public void setName(String name){ this.name = name; } public String getRole(){ return role; } public void setRole(String role){ this.role = role; } public int getMaxHp(){ return maxHp; } public int getLevel(){ return level; } public String status(){ return name + " has " + curHp + "/" + maxHp + " health."; } public String toString(){ return name + " the " + role + " is level " + level + " with " + curHp + "/" + maxHp + " HP and an attack of " + maxAtt + "-" + minAtt; } }
This is the Player
class:
public class Player extends Creature{ public int xp; private int hpPotions = 3; public Player(String name, String role){ super(name, role); this.level = 1; rollStats(); this.curHp = maxHp; } public String useHealthPotion(){ if(hpPotions >= 1 ){ this.setCurHp(this.getCurHp() + 25); hpPotions--; return hpPotions + " potions left."; }else{ return "No potions to use."; } } public int getHealthPotion(){ return hpPotions; } public void setHealthPotions(int newHpPotions){ hpPotions = newHpPotions; } public int gainXp(Creature other){ int x = other.getLevel(); int gainedXp = x * (int)(Math.random() * (60 - 21) + 20); xp += gainedXp; return gainedXp; } public boolean checkXp(){ if(xp >= level * 40){ xp = xp - (level * 40); levelUp(); return true; }else{ return false; } } public String status(){ return name + " has " + curHp + "/" + maxHp + " health."; } public String getXp(){ return xp + "/" + (level * 40); } //rolling for intitial stats public void rollStats(){ int hp = 0; int att = 0; switch(roleToNumber()){ case 1: hp = 16; att = 10; break; case 2: hp = 13; att = 13; break; case 3: hp = 12; att = 14; break; } maxHp = (roll(6) + hp); maxAtt = (roll(6) + att); minAtt = (maxAtt - 3); } private int roll(int sides){ int aRoll = (int)(Math.random() * sides + 1); return aRoll; } //Changes the inputed role to a number private int roleToNumber(){ if(role.equalsIgnoreCase("Fighter")){ return 1; }else if(role.equalsIgnoreCase("Ranger")){ return 2; }else if(role.equalsIgnoreCase("Arcanist")){ return 3; }else{ return 0; } } //coding for level up with modifiers based on role public void levelUp(){ level++; int hp = 0; int att = 0; switch(roleToNumber()){ case 1: hp = 24; att = 14; break; case 2: hp = 19; att = 19; break; case 3: hp = 16; att = 22; break; } maxHp += (hp * Math.random()/2 + .7); maxAtt += (att * Math.random()/2 + .7); minAtt = maxAtt - 3; this.curHp = maxHp; } }
And this is the Enemy
class:
public class Enemy extends Creature{ public Enemy(int leveled){ super("Filler", "Filler"); this.level = 1; this.setName(randomName()); this.setRole(randomRole()); rollStats(); if(leveled > 1){ for(int i = 1; i < leveled; i++){ levelUp(); } } this.curHp = maxHp; } //pulls a random name from an array public String randomName(){ String[] names = {"Spooky", "Scary", "Yup"}; int index = (int)(Math.random() * names.length); return names[index]; } //pulls a random role from an array, these are pased to roleToNumber public String randomRole(){ String[] roles = {"Orc", "Goblin", "Dragon"}; int index = (int)(Math.random() * roles.length); return roles[index]; } public void rollStats(){ int hp = 0; int att = 0; switch(roleToNumber()){ case 1: hp = 16; att = 10; break; case 2: hp = 13; att = 13; break; case 3: hp = 12; att = 14; break; } maxHp = (roll(6) + hp); maxAtt = (roll(6) + att); minAtt = (maxAtt - 3); } private int roll(int sides){ int aRoll = (int)(Math.random() * sides + 1); return aRoll; } private int roleToNumber(){ if(role.equalsIgnoreCase("Orc")){ return 1; }else if(role.equalsIgnoreCase("Goblin")){ return 2; }else if(role.equalsIgnoreCase("Dragon")){ return 3; }else{ return 0; } } public void levelUp(){ level++; int hp = 0; int att = 0; switch(roleToNumber()){ case 1: hp = 24; att = 14; break; case 2: hp = 19; att = 19; break; case 3: hp = 16; att = 22; break; } maxHp += (hp * Math.random()/2 + .5); maxAtt += (att * Math.random()/2 + .5); minAtt = maxAtt - 3; this.curHp = maxHp; } }
public x y
for starters). Before you go too much further, I highly recommend checking out this great talk "Stop Writing Classes": youtu.be/5ZKvwuZSiyc You don't have to take it as gospel, but it's worth thinking about. The other question I would ask: Is Java the right tool?\$\endgroup\$