I started to develop my first java project, it's a kind of basic roleplaying game. I want to create a character.
First I'll explain a few things:
Game class - gets character class input (like Fighter).
Character - has all the character data.
CharacterClass - abstract class that includes information for each character class (like Fighter).
Fighter (and other classes) extends the abstract class CharacterClass, should set initial stats for the chosen character class (like Fighter).
What I want to do is choose a character class in Game (let's assume that I choose Fighter), and get all the stats by displayStats. When the character chooses a class then Game should call something like: Chracter ch = new Character(name, scan), and then ch.displayCharacter.
My problem is Fighter's constructor and assigning this data to Character's constructor.
public class Game {
public static void main(String[] args) {
System.out.println("Choose a character: ");
System.out.println("1. Fighter");
System.out.println("2. Rogue");
System.out.println("3. Mage");
System.out.println("4. Cleric");
Scanner sc = new Scanner(System.in);
int scan = sc.nextInt();
System.out.println("Character Class: " + CharacterUtil.getCharacterClass(scan));
System.out.println("Choose Name:");
Scanner nameIn = new Scanner(System.in);
String name = nameIn.next();
System.out.println("Name: " + name);
}
}
public class Character {
private String name;
private String characterClass;
private int level;
private int hp;
private int currentHp;
private long xp;
/*private int BAB; /*Base attack bonus*/
private int strength;
private int constitution;
private int dexterity;
private int intelligence;
private int wisdom;
private int charisma;
Character(String name, String chracterClass){
this.name = name;
this.characterClass = chracterClass;
level = ;
hp = ;
currentHp = hp;
xp = 0;
strength = ;
constitution = ;
dexterity = ;
intelligence = ;
wisdom = ;
charisma = ;
}
void displayCharacter(){
System.out.println("Name: " + name);
System.out.println("Level: " + level);
System.out.println("Class: " + characterClass);
System.out.println("HP: " + hp);
System.out.println("Attributes: ");
System.out.println("Strength: " + strength);
System.out.println("Constitution: " + constitution);
System.out.println("Dexterity: " + dexterity);
System.out.println("Intelligence: " + intelligence);
System.out.println("Wisdom: " + wisdom);
System.out.println("Charisma: " + strength);
System.out.println("XP: " + xp);
}
}
abstract class CharacterClass {
private int level;
private int hp;
private int strength;
private int constitution;
private int dexterity;
private int intelligence;
private int wisdom;
private int charisma;
CharacterClass(){
level = 1;
hp = 10;
strength = 10;
constitution = 10;
dexterity = 10;
intelligence = 10;
wisdom = 10;
charisma = 10;
}
class Fighter extends CharacterClass {
Fighter(){
super.level = 1;
super.hp = 10;
super.strength = 16;
super.constitution = 14;
super.dexterity = 14;
super.intelligence = 10;
super.wisdom= 10;
super.charisma = 10;
}
}
Either make your CharacterClass private fields protected instead of private so they can be accessed by subclasses or implement getters/setters in your abstract class and use them in your subclass constructor.
Also super.field does not mean anything : your are instanciating an object which will have the fields from the abstract class and the subclass, it will be this.fields that you want to access.
Sample code :
public abstract class CharacterClass {
private int intelligence;
private int strength;
private int dexterity;
private int vitality;
protected CharacterClass() {
setIntelligence(10);
setStrength(10);
setDexterity(10);
setVitality(10);
}
public int getDexterity() {
return dexterity;
}
protected void setDexterity(int dexterity) {
this.dexterity = dexterity;
}
public int getVitality() {
return vitality;
}
protected void setVitality(int vitality) {
this.vitality = vitality;
}
public int getStrength() {
return strength;
}
protected void setStrength(int strength) {
this.strength = strength;
}
public int getIntelligence() {
return intelligence;
}
protected void setIntelligence(int intelligence) {
this.intelligence = intelligence;
}
}
public class Fighter extends CharacterClass {
public Fighter() {
setStrength(15);
setVitality(15);
}
}
public class Main {
public static void main(String[] args) {
CharacterClass player = new Fighter();
System.out.println(player.getStrength());
System.out.println(player.getIntelligence());
}
}
This will print 15 followed by 10, because the strength has been modified by figther, but the intelligence is still the one defined in CharacterClass.
Note that you probably want your player to be more than a CharacterClass or a Figther. While you will have a lot of Figther, Rogues and Mages as PNJs, the player will have a whole other range of possibilities, like storing items in his inventory, interacting with the world, etc.
Good luck with your game !
Related
Based on the following UML class diagram I am trying to get the total population of all the House and ApartmentBuilding objects using an interface (Dwelling) and I am stuck on how to proceed. I have included the code I have so far.
Dwelling:
interface Dwelling {
int getNumberOfOccupants();
}
House:
import javafx.scene.canvas.GraphicsContext;
import java.util.Scanner;
public class House extends Building implements Dwelling {
private final int bedrooms;
private final int occupants;
private House(String name, double xPosition,int bedrooms, int occupants){
super(name,xPosition);
this.bedrooms = bedrooms;
this.occupants = occupants;
}
public static House create() {
Scanner scan = new Scanner(System.in);
House a;
System.out.println("Enter name of the House: ");
String name = scan.nextLine();
System.out.println("Enter XPosition of the House: ");
int xPosition = scan.nextInt();
System.out.println("Enter number of bedrooms: ");
int bedrooms = scan.nextInt();
System.out.println("Enter number of occupants: ");
int occupants = scan.nextInt();
a = new House(name, xPosition, bedrooms, occupants);
return a;
}
public void draw(GraphicsContext canvas){
}
#Override
public String toString(){
return "House: " + "bedrooms= " + bedrooms + " occupants= " + occupants + "\n" + super.toString();
}
#Override
public int getNumberOfOccupants() {
return occupants;
}
}
ApartmentBuilding:
import javafx.scene.canvas.GraphicsContext;
import java.util.Scanner;
public class ApartmentBuilding extends HighRise implements Dwelling{
private final int occupantsPerFloor;
private ApartmentBuilding(String name, double xPosition, int numberOfFloors, int occupantsPerFloor){
super(name, xPosition, numberOfFloors);
this.occupantsPerFloor = occupantsPerFloor;
}
public static ApartmentBuilding create() {
Scanner scan = new Scanner(System.in);
ApartmentBuilding a;
System.out.println("Enter name of the Apartment Building: ");
String name = scan.nextLine();
System.out.println("Enter XPosition of the Apartment Building: ");
int xPosition = scan.nextInt();
System.out.println("Enter number of floors: ");
int numberOfFloors = scan.nextInt();
System.out.println("Enter number of occupants per floor: ");
int occupantsPerFloor = scan.nextInt();
a = new ApartmentBuilding(name, xPosition, numberOfFloors, occupantsPerFloor);
return a;
}
public void draw(GraphicsContext canvas){
}
#Override
public String toString(){
return "Apartment Building: " + "occupantsPerFloor= " + occupantsPerFloor + "\n" + super.toString() + "\n";
}
#Override
public int getNumberOfOccupants() {
return numberOfFloors * occupantsPerFloor;
}
}
Building:
import javafx.scene.canvas.GraphicsContext;
public class Building implements Drawable {
private final String name;
private final double xPosition;
public Building(String name, double xPosition){
this.name = name;
this.xPosition = xPosition;
}
public String getName(){
return name;
}
public void draw(GraphicsContext canvas) {
}
public double getXPosition() {
return xPosition;
}
#Override
public String toString(){
return "Type... Building: " + "name= " + getName() + ", xPosition= " + getXPosition() + "\n";}
}
HighRise:
public class HighRise extends Building{
int numberOfFloors;
public HighRise(String name, double xPosition, int numberOfFloors) {
super(name, xPosition);
this.numberOfFloors=numberOfFloors;
}
public int getNumberOfFloors(){
return numberOfFloors;
}
#Override
public String toString() {
return "Type... HighRise: " + "numberOfFloors= " + getNumberOfFloors() + "\n" + super.toString();
}
}
Village:
import javafx.scene.canvas.GraphicsContext;
import java.util.Scanner;
public class Village extends Building{
private static String name;
private static int xPosition;
public static final double Y_FLOOR = 300;
private int size;
private final String villageName;
private final Building[] buildings;
private Village(String villageName, int size){
super(name, xPosition);
this.size = size;
this.villageName = villageName;
this.buildings = new Building[size];
}
public static Village create() {
Scanner scan = new Scanner(System.in);
Village a;
System.out.println("Enter name of village: ");
String villageName = scan.nextLine();
System.out.println("Enter number of buildings: ");
int num = scan.nextInt();
a = new Village(villageName, num);
for(int i = 0; i < num; i++) {
System.out.println("Enter type of Building: 1= House, 2= Apartment, 3= Store ");
int choice = scan.nextInt();
if (choice == 1){
a.buildings[i] = House.create();
}
if (choice == 2){
a.buildings[i] = ApartmentBuilding.create();
}
}
return a;
}
public int getPopulation(){
return size;
}
public void draw(GraphicsContext canvas){
}
public String toString(){
String str = "\n"+ "Village of " + villageName + "\n\n";
for (int i=0; i<buildings.length; i++) {
str = str + buildings[i].toString() + "\n"; // this adds each buildings information to the string
}
return str;
}
}
I am new at programming and trying my best to learn but I am getting stuck on this, unfortunately.
..I am trying to get the total population of all the House and ApartmentBuilding objects using an interface (Dwelling)..
You can not get the population while using that UML. Please try modify a bit as below.
First, Dwelling must declaire getPopulation();
Implementing getPopulation() within House and ApartmentBuilding
You need a variable to keep the population within House and ApartmentBuilding class as well (it will be returned while calling getPopulation()).
After that, you able to cast House and ApartmentBuilding to Dwelling. Then dwelling.getPopulation(). Hope it is useful.
I am working on a OOP final project which is a text based survival game. I am currently trying to finish it up by having the player enter how many enemies they would like to fight then it loops through it until the amount is met. What would be the best route? I want it so that enemies can be selected twice, but my partner wants to do a shuffle of the array because less work.
Mostly I am stuck on where and what kind of loop I should make and where should I place it.
This is some code in the main class.
Entity entity = new Entity();
ArrayList<Entity> enemies = new ArrayList<>();
EnemyList enemyList = new EnemyList();
Entity troll = new Troll();
troll.setName("Troll");
enemyList.characters.add(troll);
Entity imp = new Imp();
imp.setName("Imp");
enemyList.characters.add(imp);
Entity knight = new Knight();
knight.setName("knight");
enemyList.characters.add(knight);
Entity skeleton = new Skeleton();
skeleton.setName("Skeleton");
enemyList.characters.add(skeleton);
Integer[] array = new Integer[enemyList.characters.size()];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
Collections.shuffle(Arrays.asList(array));
for (int i = 0; i < enemyCount; i++) {
for (Entity someEnemy : enemyList.characters) {
System.out.println(enemyList.characters.get(array[i]));
System.out.println(someEnemy.getName(entity) + "\n");
System.out.println("A " + someEnemy.getName(entity) + " Appears! It has " + someEnemy.getHealth() + "HP");
while (someEnemy.getHealth() > 0) {
int attack = character.getAttack();
System.out.println("You hit the " + someEnemy.getName(entity) + " for " + character.getAttack());
int monsterTotalHealth = someEnemy.setHealth(someEnemy.getHealth() - attack);
System.out.println(someEnemy.getName(entity) + " has " + monsterTotalHealth + "HP Left");
System.out.println("");
if (someEnemy.getHealth() > 0) {
System.out.println("The monster attacks back for " + someEnemy.getStrength());
int remainingHP = character.damageDelt(someEnemy.getStrength());
System.out.println("Your remaining health is " + remainingHP);
System.out.println("");
character.setHealth(character.getHealth());
}
if (character.isDead()) {
System.out.println("You have been defeated!");
System.exit(0);
} else if (someEnemy.getHealth() < 0) {
System.out.println("Fighting Next monster");
}
}
}
}
Entity class
public class Entity {
private String name;
private int health;
private int level;
private int vitality;
private int strength;
private int resistance;
private int dexterity;
private int endurance;
private int intelligence;
private int attack;
public String getName(Entity someenemy) {
return name;
}
public int getHealth() {
return health;
}
public int getLevel() {
return level;
}
public int getVitality() {
return vitality;
}
public int getStrength() {
return strength;
}
public int getResistance() {
return resistance;
}
public int getDexterity() {
return dexterity;
}
public int getEndurance() {
return endurance;
}
public int getIntelligence() {
return intelligence;
}
public int getAttack() { return attack; }
public void setName(String name) {
this.name = name;
}
public int setHealth(int health) {
this.health = health;
return health;
}
public void setLevel(int level) {
this.level = level;
}
public int setVitality(int vitality) {
this.vitality = vitality;
return vitality;
}
public void setStrength(int strength) {
this.strength = strength;
}
public void setResistance(int resistance) {
this.resistance = resistance;
}
public void setDexterity(int dexterity) {
this.dexterity = dexterity;
}
public void setEndurance(int endurance) {
this.endurance = endurance;
}
public void setIntelligence(int intelligence) {
this.intelligence = intelligence;
}
public void setAttack(int attack) {
this.attack = attack;
}
#Override
public String toString() {
return "This enemy is appearing: " + name +
", health is " + health +
", strength is " + strength;
}
}
EnemyList class
import java.util.ArrayList;
import java.util.List;
public class EnemyList {
List<Entity> characters = new ArrayList<>();
public void print()
{
for (Entity entity : characters)
{
System.out.println(entity.toString());
}
}
}
Mechanics Interface
interface Mechanics {
boolean isDead();
int damageDelt (int damage);
//int levelup();
}
Ok, will try to help here.
First of all, I think this is unnecessary:
Integer[] array = new Integer[enemyList.characters.size()];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
Collections.shuffle(Arrays.asList(array));
You already have an array, contained in the enemyList instance, called characters.
Now let's say your user wants to fight with 5 enemies. To randomize the event, you shuffle the array first.
Collections.shuffle(enemyList.characters);
Assuming that maxEnemies = 5 , let's go to the loop:
boolean win = true;
for (int i=0;i<maxEnemies;i++)
{
Entity enemy = enemyList.characters.get(i);
String enemyName = enemy.getName();
System.out.println("Fighting "+enemyName);
//... your logic here
if (character.isDead())
{
win=false;
break;
}
}
if (!win)
System.out.println("You have been defeated! You are a disgrace to your family");
else
System.out.println("You've defeated "+maxEnemies+" bastards. You WON!
Tiger blood runs through your veins");
Note I moved the "fighting next enemy" text to the beginning of the loop clause, since the shown text would be incorrect when the last enemy has been defeated (there will be no next enemy).
As the index is based on your count (0-4), no monster will appear twice.
Note that you should validate the user input, deniying the input if the number of enemies he wills to fight is bigger than the number of Entities stored in the array. So the input regarding number of entities to fight <= enemyList.characters.size
I made some changes to the exit method as well, but feel free to change them so it fits your purposes. Instead of killing the thread, you could just call break() in order to finish the loop, and continue with the process the way you want.
public class Monster{
public final String TOMBSTONE = "Here Lies a Dead monster";
private int health = 500;
private int attack = 20;
private int movement = 2;
public String name = "Big Monster";
public int getAttack()
{
return attack;
}
public int getMovement()
{
return movement;
}
public int getHealth()
{
return health;
}
public Monster(int health, int attack, int movement)
{
this.health = health;
this.attack = attack;
this.movement = movement;
}
public Monster()
{
}}
public class Frank {
public static void main(String[] args){
Monster NewMonster = new Monster();
NewMonster.name = "Frank";
System.out.println(NewMonster.name + " has an attack value of " + NewMonster.getAttack());
}
}
When trying to create a new object from my Monster class I get this error:
Frank.java:5: error: cannot find symbol
Monster NewMonster = new Monster();
^
symbol: class Monster
location: class Frank
I am very new to Java so sorry if this is a simple/easy fix but everything I have researched does not give me a solution to this error.
Thanks in advance for any replies/feedback.
1 You have to define only one class a public which will be saved as per your java file name (.java)
2 object references will be always in lower case
class Monster {
public final String TOMBSTONE = "Here Lies a Dead monster";
private int health = 500;
private int attack = 20;
private int movement = 2;
public String name = "Big Monster";
public int getAttack() {
return attack;
}
public int getMovement() {
return movement;
}
public int getHealth() {
return health;
}
public Monster(int health, int attack, int movement) {
this.health = health;
this.attack = attack;
this.movement = movement;
}
public Monster() {
}
}
// only Frank can be a public class in a single java file, or else create two different java classes and import.
public class Frank {
public static void main(String[] args){
Monster newMonster = new Monster();
newMonster.name = "Frank";
System.out.println(newMonster.name + " has an attack value of " + newMonster.getAttack());
}
}
Output: Frank has an attack value of 20
You are not allowed to have multiple public classes in one file in Java. Therefore you need to either remove a public modifier of one of your classes or put the main method in your public class. I did the latter, since it is not necessary to place the main method in a seperate class just to instantiate your object.
I have updated your code and it runs now
public class Monster{
public static void main(String[] args) {
Monster NewMonster = new Monster();
NewMonster.name = "Frank";
System.out.println(NewMonster.name + " has an attack value of
" + NewMonster.getAttack());
}
public final String TOMBSTONE = "Here Lies a Dead monster";
private int health = 500;
private int attack = 20;
private int movement = 2;
public String name = "Big Monster";
public int getAttack() {
return attack;
}
public int getMovement(){
return movement;
}
public int getHealth(){
return health;
}
public Monster(int health, int attack, int movement){
this.health = health;
this.attack = attack;
this.movement = movement;
}
public Monster(){}
}
sorry to be annoying, I am new to programming and am a bit confused.
How do I link variables of two classes? ie get a variable of one class into another? I'm trying to make an OOP scenario for a game platform where a player can join a game(max of 2 players per game, and pay an associated fee. I;'m trying to get a method which totals these in the Game class but I'm unsure how to add up all the players "amountOwed" into this. I also have to make sure both players are not the same player? any advice GREATLY appreciated! here is what i have so far
import java.time.LocalDate;
import java.time.Period;
import java.util.Date;
public class Player {
private static int instanceCounter = 0;
private int playerId;
private String playerName;
public int birthDay;
public int birthMonth;
public int birthYear;
public int playerAge;
public double amountOwed;
public Player(int playerId, String playerName, int birthDay, int birthMonth, int birthYear, double amountOwed) {
this.playerId = playerId;
this.playerName = playerName;
this.birthDay = birthDay;
this.birthMonth = birthMonth;
this.birthYear = birthYear;
this.amountOwed = amountOwed;
instanceCounter++;
}
public double getAmountOwed() {
return (amountOwed);
}
public int calculateAge() {
LocalDate birthDate = LocalDate.of(birthYear, birthMonth, birthDay);
LocalDate currentDate = LocalDate.now();
return playerAge = Period.between(birthDate, currentDate).getYears();
}
public String printDetails() {
return (playerName + ", with ID " + playerId + ", is " + playerAge + " and owes the game platform£" + amountOwed);
}
public String payFees() {
amountOwed = 0;
return ("Thank you" + playerName + ",you have paid for your game, your balance now stands at £0.00");
}
public String joinGameChess() {
if (instanceCounter < 3) {
return (playerName + " has joined the game.");
} else {
return ("Sorry, maximum of 2 players per game");
}
}
public String leaveGame() {
return (playerName + "has left the game.");
}
}
public class Game {
private String gameName;
private int gameId;
private int minAge;
private double fee;
public double amountOwed;
public double totalFeesOwed;
public Game(String gameName, int gameId, int minAge, double fee) {
this.gameId = gameId;
this.gameName = gameName;
this.minAge = minAge;
this.fee = fee;
}
public String printGameDetails() {
return (gameName + "of ID " + gameId + "has a minimum age of " + minAge + " and costs " + fee + " to play");
}
}
public class W07Practical {
public static void main(String[] args) {
Player marina = new Player(123, "Marina", 15, 4, 1999, 0);
marina.calculateAge();
System.out.println(marina.printDetails());
Game chess = new Game("chess", 1234, 19, 2);
marina.getAmountOwed();
System.out.println(marina.joinGameChess());
Player elise = new Player(153, "elise", 16, 3, 2000, 0);
System.out.println(elise.joinGameChess());
Player john = new Player(322, "john", 23, 5, 2002, 0);
System.out.println(john.joinGameChess());
System.out.println(john.printDetails());
System.out.println(elise.printDetails());
}
}
Total amount owed:
amountOwed = player1.getAmountOwed() + player2.getAmountOwed();
You can check both players are not same by their name or to be more precise by comparing their birthdays. For further precision compare both
Create gets and sets methods:
getStudentName() and setstudentName()
getStudentNumber() and setStudentNumber()
I am confused on what to put in the public void printGrades() and printAverage()
import java.util.Scanner;
public class studentGrader
{
Scanner input = new Scanner(System.in);
private String studentName;
private String studentNumber;
private String[] testNames;
private int[] testGrades;
private int currentTestPointer;
private int maxTestCount = 10;
private int averageGrade;
private int testScore;
public studentGrader(String studentNameL,String studentNumberL)
{
studentName = studentNameL;
studentNumber = studentNumberL;
testNames = new String[maxTestCount];
testGrades = new int[maxTestCount];
currentTestPointer = 0;
averageGrade = 0;
}
public void addTest(String testName, int testScore)
{
testNames[currentTestPointer] = testName;
}
public void printGrades()
{
}
public void printAverage()
{
}
}
//Most Getters are very simple.
//The goal is to simply return some variable that is privately stored in a class
//Notice that the variable "studentName" is of type "String" and the method is returning a type "String"
public String getStudentName() {
return studentName;
}
//Most Setters are the same as getters, except they set the variable instead
//This method takes in a parameter(in this case "name") and then sets the desired variable to given parameter
public void setstudentName(String name) {
studentName = name;
}
The getStudentNumber and setStudentNumber are the same and I'll leave that left undone as a mental exercise.
//This is an example of how to print something
public void printAverage() {
//There may be additional logic in here to determine the correct average grade
system.out.print(averageGrade);
}
There are some rules from Java code style (that not flow to error, but they are used by everyone) along with some JVM defaults:
Class name should be in camel-case: class studentGrader - class StudentGrader
Scanner class is used to work with inbound data (console, files, ets); this is not a data holder. Should be removed from the class and used as local variable in method.
In constructor (usually), same name for local properties and method parameters should be used. To get access to the local properties, do use this: this.studentName = studentName
Arrays testNames and testGrades are objects with know size. So you should declare it in the class definition and make it final (reference is final, but not array's content): private final String[] testNames = new String[10]; and private final int[] testGrades = new int[10];
Class local parameters are initialized to the default values. For int it is a 0. So no need to do it in the constructor for currentTestPointer and averageGrade
void addTest(String testName, int testScore), in your current increment currentTestPointer and check for arrays out of bound (not more than 10) (I think, it is better to use Map)
averageGrade should be double (I think): private double averageGrade;``
Finally, your class could look like this:
public class StudentGrader {
private static final int MAX_TEST_AMOUNT = 10;
private String studentName;
private String studentNumber;
private final String[] testNames = new String[MAX_TEST_AMOUNT];
private final int[] testGrades = new int[MAX_TEST_AMOUNT];
private int currentTestPointer;
private double averageGrade;
private int testScore;
public StudentGrader(String studentName, String studentNumber) {
this.studentName = studentName;
this.studentNumber = studentNumber;
}
public void addTest(String testName, int testScore) {
if (currentTestPointer < MAX_TEST_AMOUNT) {
testNames[currentTestPointer] = testName;
testGrades[currentTestPointer] = testScore;
currentTestPointer++;
}
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(String studentNumber) {
this.studentNumber = studentNumber;
}
public void printGrades() {
// <testName>: <testGrade>
for (int i = 0; i < currentTestPointer; i++)
System.out.println(testNames[i] + ": " + testGrades[i]);
}
public void printAverage() {
averageGrade = 0;
if (currentTestPointer > 0) {
for (int i = 0; i < currentTestPointer; i++)
averageGrade += testGrades[i];
averageGrade /= currentTestPointer;
}
System.out.println(averageGrade);
}
}