在多个不同的班级中使用玩家的统计数据

时间:2017-07-10 01:13:07

标签: java oop methods

我正在制作一个文本冒险RPG游戏,你可以在那里参加一场战斗,并按照一个半开放的世界故事。我制作了一个玩家类,用来保存所有玩家的统计数据。

public class Player {

    // Generic Stats
    int playerLevel = 1;
    int playerHealth = 20;
    int EXP = 0;
    long money = 0;
    String name = "";
    String homeland = "";

    // Skills
    int fighting = 5;
    int block = 5;
    int doctor = 5;
    int speech = 5;

    // Attributes
    int damage = fighting * 2;

    // Prints the player's stats
    public void printStats() {          
        System.out.println();
        System.out.println("Level: " + playerLevel);
        System.out.println("EXP: " + EXP);
        System.out.println("HP: " + playerHealth);
        System.out.println("Money: " + money);
        System.out.println("Name: " + name);
        System.out.println("Homeland: " + homeland );
        System.out.println("Skills: Fighting: " + fighting + " Block: " + block + "Doctor: " + doctor + " Speech: " + speech);
        System.out.println();
    }

    // Changes the player's level
    public void changeLevel(int newLevel) {         
        playerLevel = newLevel;
    }

    // Levels up the player
    public void levelUp() {
        playerLevel++;
        EXP = 0;
    }

    // Give the player health
    public void addHealth(int addedHealth) {
        playerHealth = playerHealth + addedHealth;
    }

    // Remove the player's health
    public void removeHealth(int removedHealth) {
        playerHealth = playerHealth - removedHealth;
    }

    // Give the player money
    public void giveMoney(int givenMoney) {
        money = money + givenMoney;
    }

    // Give the player EXP
    public void giveEXP(int addedEXP) {
        EXP = EXP + addedEXP;
    }

    // Change the player's homeland
    public void changeHomeland(String newHomeland) {
        homeland = newHomeland;
    }

    // Change the player's name
    public void changeName(String newName) {
        name = newName;
    }

    // Increase Fighting
    public void increaseFightingSkill(int amountAdded) {
        fighting = fighting + amountAdded;
    }

    // Decrease Fighting
    public void decreaseFightingSkill(int amountdecreased) {
        fighting = fighting - amountdecreased;
    }

    // Increase Block
    public void increaseBlockSkill(int amountAdded) {
        block = block + amountAdded;
    }

    // Decrease Block
    public void decreaseBlockSkill(int amountdecreased) {
        block = block - amountdecreased;
    }

    // Increase Doctor
    public void increaseDoctorSkill(int amountAdded) {
        doctor = doctor + amountAdded;          
    }

    // Decrease Doctor
    public void decreaseDoctorSkill(int amountdecreased) {
        doctor = doctor - amountdecreased;
    }

    // Increase Speech
    public void increaseSpeechSkill(int amountAdded) {
        speech = speech + amountAdded;
    }

    // Decrease Speech
    public void decreaseSpeechSkill(int amountdecreased) {
        speech = speech - amountdecreased;
    }

}

如您所见,您还可以在此处更改玩家的统计数据。我正在制作一个主要课程,我只是初始化玩家,并在玩家做出决定,赢得战斗等时修改他们的统计数据。我在主要课程中初始化玩家。

Player player = new Player();

现在它被初始化了,我做了一个" Battle"类。这个概念是我想简单地初始化战斗,修改战斗的内容并完成它(就像我可以放入代码中的战斗模板)。像这样排序:

battle.enemySetHealth() // example modifier
battle.start() // simply run through the battle

问题是,我想在战斗类中使用玩家统计数据,而不是实际上只是定义另一个玩家,我想使用相同的玩家对象,因为我将在主要修改玩家的统计数据如果我定义一个新类,它将在战斗类中具有不同的统计数据,弄乱整个事物。我将使用战斗类中的玩家统计数据来确定攻击伤害,阻止传入攻击的机会,e.t.c。这是战斗类:

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

// Battle Scene
public class Battle {
    //Variables
    String enemyName = "Unnamed Enemy";
    int enemyHealth = 20;
    int enemyAttack = 5;
    int enemyDefense = 5;
    int enemyDisposition = 0;
    int attackDamage;
    // Sets up tools
    clear clear = new clear();
    Scanner sc = new Scanner(System.in);
    Random rand = new Random();

    // Allows changing of enemy name
    public void enemyName(String newEnemyName) {
        enemyName = newEnemyName;
    }

    // Sets a new disposition for the enemy to start the fight with
    public void enemyStartingDisposition(int newStartingDisposition) {
        enemyDisposition = newStartingDisposition;
    }

    // Sets a new amount of health for the enemy to start with
    public void enemyStartingHealth(int newStartingHealth) {
        enemyHealth = newStartingHealth;
    }

    // Sets a new defense for the enemy to start with
    public void enemyStartingDefense(int newEnemyDefense) {
        enemyDefense = newEnemyDefense;
    }

    // Sets a new attack for the enemy to start with
    public void enemyStartingAttack(int newEnemyAttack) {
        enemyAttack = newEnemyAttack;
    }

    // Starts the battle
    public void startFight() throws InterruptedException {
        System.out.println("Woah! " + enemyName + " jumped out of nowhere!!!");
        System.out.println("(Attack)");
        System.out.println("(Talk)");
        System.out.println("(Run)");
        while (true) {
            System.out.print("What should you do? : ");
            String userInput = sc.nextLine();
            if (userInput.equals("Attack")) {
                // hopefully put in a way to attack based on your stats
            } if (userInput.equals("Talk")) {
                // a way to use speech to talk your way out of the fight
            } if (userInput.equals("Run")) {
                //ability to run away based on agility/speed 
            } else {
                System.out.println();
                System.out.println("Invalid Answer!");
                Thread.sleep(2000);
                clear.Screen();
            }   
        }
        //Break here
    }
}

我还希望在最后修改玩家的统计数据,比如赚钱和赚取收入。那我该怎么做呢?它变得非常混乱。

3 个答案:

答案 0 :(得分:0)

您可以将Player实体作为实际参数传递给Battle类的方法,并将当前实体作为参数返回。 示例代码如下:

战斗类代码:

public class Battle {
    //battle win function
    public Player winBattle(Player player){
        /**
         * win rules
         */
        player.setStatus("dead");
        return player;
    }

}

玩家类代码:

Player player = new Player();
Battle battle=new Battle();
player=battle.run(player);

答案 1 :(得分:0)

你想要做的是将你在主类中创建的玩家对象传递给战斗类中的startfight()方法。然后,在startfight中,您将能够访问所有玩家的统计数据,而无需重新定义它们。创建一个Enemy类来代表游戏中的ememy也可能很有用。这样你就不需要为战斗类中定义的敌人提供统计数据。此外,由于玩家和敌人共享一些统计数据(如损坏和名称),因此创建一个具有损坏的superclass并将其命名为实例变量以避免代码重复可能会很有用。因为玩家的游戏总是相同的,所以我们可以将玩家作为战斗的实例变量(因为你只想使用战斗类的一个实例)。尽管如此,这里是你的代码,包含我提出的改变。

GameUnit.java

/**
 * Represents a game unit - a Player or an Enemy because they both share common stats
 */
public class GameUnit {
    int attackDamage;// your "damage" in the player class and "enemyAttack" in the battle class
    int health = 5;// "playerHealth" in the player class and "enemyHealth" in the battle class
    int defense = 5;

    String name = "unnamed game unit";

    public void printStats() {
        System.out.println();
        System.out.println("Game Unit attackDamage: " + attackDamage);
        System.out.println("Game Unit health: " + health);
        System.out.println("GameUnit defense: " + defense);
    }

    // Give the unit health
    public void addHealth(int addedHealth) {
        health = health + addedHealth;
    }

    public void setHealth(int newHealth) {
        health = newHealth;
    }

    // Remove the player's health
    public void removeHealth(int removedHealth) {
        health = health - removedHealth;
    }

    // Change the unit's name
    public void changeName(String newName) {
        name = newName;
    }

    public void setAttackDamage(int attackDamage) {
        this.attackDamage = attackDamage;
    }

    // Increase Block
    public void increaseBlockSkill(int amountAdded) {
        defense = defense + amountAdded;
    }

    // Decrease Block
    public void decreaseBlockSkill(int amountdecreased) {
        defense = defense - amountdecreased;
    }

    public void setDefense(int defense) {
        this.defense = defense;
    }
}

Player.java

public class Player extends GameUnit {
    int level = 1;
    // health is now in GameUnit because enemy needs health too
    int EXP = 0;
    long money = 0;
    String homeland = "";

    int fighting = 5;
    //block is defense in GameUnit
    int doctor = 5;
    int speech = 5;

    // Constructor that sets name from "unnamed game unit" to Player
    public Player() {
        name = "Player";// Set the name declared in the GameUnit class to player because this instance is the player
        attackDamage = fighting * 2;
    }

    // Override printStats in GameUnit to print the remaining player stats
    public void printStats() {
        super.printStats();// Prints attack damage and health
        System.out.println("Player level: " + level);
        System.out.println("Health: " + health);
        System.out.println("EXP: " + EXP);
        System.out.println("money " + money);
        System.out.println("Homeland: " + homeland);
        System.out.println("Skills: Fighting: " + fighting + "Doctor: " + doctor + " Speech: " + speech);
        System.out.println();
    }


    // Changes the player's level
    public void changeLevel(int newLevel) {

        level = newLevel;
    }

    // Levels up the player
    public void levelUp() {
        level++;
        EXP = 0;
    }// Give the player money
    public void giveMoney(int givenMoney) {
        money = money + givenMoney;
    }

    // Give the player EXP
    public void giveEXP(int addedEXP) {
        EXP = EXP + addedEXP;
    }

    // Change the player's homeland
    public void changeHomeland(String newHomeland) {
        homeland = newHomeland;
    }

    // Increase Fighting
    public void increaseFightingSkill(int amountAdded) {
        fighting = fighting + amountAdded;
    }

    // Decrease Fighting
    public void decreaseFightingSkill(int amountdecreased) {
        fighting = fighting - amountdecreased;
    }

    // Increase Doctor
    public void increaseDoctorSkill(int amountAdded) {
        doctor = doctor + amountAdded;

    }

    // Decrease Doctor
    public void decreaseDoctorSkill(int amountdecreased) {
        doctor = doctor - amountdecreased;
    }

    // Increase Speech
    public void increaseSpeechSkill(int amountAdded) {
        speech = speech + amountAdded;
    }

    // Decrease Speech
    public void decreaseSpeechSkill(int amountdecreased) {
        speech = speech - amountdecreased;
    }
}

Enemy.java

public class Enemy extends GameUnit {
    //enemyHealth is health in GameUnit
    //enemyAttack is attackDamage in GameUnit
    int enemyDisposition = 0;

    //No need for setEnemy name because changeName does the perfect thing in GameUnit

    //Set health does the job of enemyStartingHealth
    public void setEnemyDisposition(int enemyDisposition) {
        this.enemyDisposition = enemyDisposition;
    }

}

Battle.java

import java.util.*;

public class Battle {
    private Player player;
    private Enemy enemy;

    private Clear clear = new Clear();// Remember Java classes are supposed to start with upper cases
    private Scanner sc = new Scanner(System.in);
    private Random rand = new Random();

    public Battle(Player thePlayer) {// Pass our only instance of player
        player = thePlayer;// Because objects are passed by reference in Java,
        // player will be the same instance of Player. In other words, when
        // you modify the player object in main, the instance variables in this
        // player reference will change accordingly because player in this class
        // and player in main both point to the same object
    }

    public void setEnemy(Enemy newEnemy) {
        enemy = newEnemy;
    }

    // Starts the battle
    public void startFight() {

        System.out.println("Woah! " + enemy.name + " jumped out of nowhere!!!");
        System.out.println("(Attack)");
        System.out.println("(Talk)");
        System.out.println("(Run)");
        boolean won = false;
        while (true) {

            if (enemy.health <= 0) {// enemy is dead
                won = true;
                break;
            }

            if (player.health <= 0) {// player is dead
                won = false;
                break;
            }

            System.out.print("What should you do? : ");
            String userInput = sc.nextLine();
            if (userInput.equals("Attack")) {
                enemy.removeHealth(player.attackDamage);// hurt the enemy or whatever
                // hopefully put in a way to attack based on your stats
            }
            if (userInput.equals("Talk")) {
                if (player.speech > 10) {
                    // ...
                }

            }
            if (userInput.equals("Run")) {
                // ability to run away based on agility/speed

            } else {
                System.out.println();
                System.out.println("Invalid Answer!");
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                    // ignore all exceptions
                }
                clear.screen();// and methods are supposed to use lower camel case so the first word (screen) is lowercase
            }
        }
        if (won) {
            player.money += 1000;
            player.giveEXP(10);
            if (player.EXP > 100) {
                player.levelUp();
            }
        } else {
            player.money -= 500;
        }
        // Break here

    }

}

Main.java

public class Main {

    public static void main(String[] args) {

        Player player = new Player();

        Battle battle = new Battle(player);// Pass player to battle

        Enemy firstEnemy = new Enemy();
        firstEnemy.changeName("First Enemy");

        battle.setEnemy(firstEnemy);
        battle.startFight();
        // ...do other battles, create new enemies with random stats etc...
    }
}

Java库也使用层次结构:link

如果这种层次结构业务没有意义,那么在继续游戏之前提高Java技能可能会有所帮助。一旦你失去信心,我的设置可能无法封装你想要如何表示你的游戏对象(玩家和敌人),所以你可能想要画出UML diagram来展示玩家和敌人的共同点(健康,阻挡)但是,玩家可能会拥有敌人现在可以拥有的某些东西(等级,xp等)。有了这些知识,您就可以重建层次结构,这样您就不必担心所有内容的存储方式,并且您可以不间断地处理内容。

良好的继承/层次结构示例here

答案 2 :(得分:0)

接受的答案很好,但我认为值得注意的是,如果你在整个游戏中只有一名玩家,你应该在你的主要课程中创建一个public static Player,如下所示:

public class Main {

public static Player player;

public static void main(String args[]) {
player = new Player();
//...
battle.start();
}

}

然后在Battle类中,当你想要奖励玩家exp(或其他东西)时,你可以简单地说:

Main.player.rewardExp(25);

Main.player.exp += 25;

我个人觉得你的游戏更具技术意义,但是如果你要添加更多玩家或敌人,那么接近它会更有意义:

Battle b = new Battle(player, enemy);
battle.start();

传递玩家和敌人的参数,然后将它们存储为每个战斗实例的变量,使战斗可以轻松访问它们。

**编辑:**您可能还想考虑制作实体课程。 你的玩家的某些变量(特征,统计数据),如HP,力量等等,也是敌人的统计数据。

为了防止两次写入相同的代码,您可以创建一个包含HPPOWER以及EXP等变量的--SUPERCLASS。

然后只需要你的Player类和Enemy类extends Entity,你就可以将这些统计数据用于两个类,而无需在两个类中编写它们。 您甚至可以预设方法,例如die()giveExp()loseHp()

希望我解释得那么好。