Java ミニゲーム ソース付き 〜ここまでのまとめ〜

今回は、ミニゲーム作成で作ったものをまとめます。
まとめたのちに、次の実装はどうしようか決めようと考えた次第です。

Gitリポジトリはこちらです。下の方に、接続方法などの記事へのリンクがあります。

オブジェクト指向について

オブジェクト指向について、Oracle認定の書籍を参考にまとめた記事です。参考にどうぞ

大まかな処理フロー

GameMainクラス
クラスの記述内容がコードより、ライセンスのJavaDoc部分が大半を占める状態です(笑)

public class GameMain {
    public static void main(String[] args) {
        // ゲームクラス
        TextRpgGame main = new TextRpgGame();
        // 初期処理
        main.init();
        while (true) {
            // 入力受付
            String in = main.input();
            if ("bye".equals(in)) {
                break;
            }
            // データの更新
            if (main.update(in)) {
                // 画面の描画
                main.render();
            }
        }
    }
}

メインメソッドを持っていて、ループ処理を行っています。
while(true) { ... }の部分が俗にいう「ゲームループ」の部分になります。

処理の説明としては、以下の通りです。

  1. TextRpgGameのインスタンスを取得
  2. 初期処理を行う
  3. ゲームループ開始
  4. 標準入力を受け取る
  5. "bye"と入力されたらアプリの終了
  6. 入力データにより、ゲームで使用するデータ(プレーヤーとモンスター)の情報を更新する
  7. 表示するステータスを再描画

こんな感じの処理を行っています。

TextRpgGameについて

メインメソッドから呼ばれるそれぞれのメソッドを実装しています。
具体的には下のものです。

  1. init(): 初期処理を行う。ステータスの表示など
  2. input(): 標準入力を受け取る。
  3. update (): データの更新を行う。使用しているプレーヤークラス、モンスタークラスのデータを更新します。主にHPの値を更新します。
  4. render(): ステータスの更新、モンスターを倒したなどの戦闘終了の文言を表示する。
public class TextRpgGame {
    /** コマンド:たたかう */
    private static final String ATTACK = "1";
    /** コマンド:ぼうぎょ */
    private static final String DEFFENCE = "2";
    /** コマンド:にげる */
    private static final String ESCAPE = "3";

    /** 入力部品 */
    private Scanner scan;
    /** プレーヤー */
    private Player player;
    /** モンスター */
    private Monster monster;

    /** 初期表示を行う */
    public void init() {
        player = new Player(20, 10, 1, "プレーヤー");
        monster = new Monster(10, 5, 1, "たくのじ");

        System.out.println(monster.getName() + "が現れた!");
        monster.say();
        scan = new Scanner(System.in);
    }

    /** 入力処理 */
    public String input() {
        return scan.next();
    }

    /** 入力後に行う処理 */
    public boolean update(String input) {
        if (CheckerUtils.isNumber(input, CheckerUtils.REG_1_TO_3) == false) {
            System.out.println("1-3を入力してください。: " + input);
            return false;
        }
        // コマンド実行後の計算
        if (ATTACK.equals(input)) {
            // モンスターへダメージ
            int monsterDamage = this.calcAttack(player.attack(), monster.deffence(), player.getName());
            int monsterResult = monster.getHp() + monsterDamage;
            monster.setHp(monsterResult);
        }
        // モンスターの攻撃
        int monsterAttack = this.calcAttack(player.deffence(), monster.attack(), monster.getName());
        int playerResult = player.getHp() + monsterAttack;
        player.setHp(playerResult);

        return true;
    }

    /** 
     * 画面を更新する。
     * @return ture: 終了 false: 続く
     */
    public boolean render() {
        if (monster.getHp() > 0) {
            monster.say();
        } else if (player.getHp() <= 0 ) {
            System.out.print(player.getName() + "はたおれてしまった。");
            return true;
        } else {
            monster.lastMessage();
            System.out.print(monster.getName() + "をやっつけた。");
            return true;
        }
        return false;
    }

    public void viewStatus() {
        viewStatus(player.getHp(), player.getMp(), monster.getHp(), monster.getMp());
    }

    private void viewStatus(int playerHp, int playerMp, int monsterHp, int monsterMp) {
        String line1 = "たたかう: 1   プレーヤー   たくのじ";
        String line2 = "ぼうぎょ: 2   HP: A1     HP: B1";
        String line3 = "にげる : 3   MP: A2     MP: B2";
        // 値を入れ替える
        line2 = line2.replace("A1", String.format("%02d", playerHp)).replace("B1", String.format("%02d", monsterHp));
        line3 = line3.replace("A2", String.format("%02d", playerHp)).replace("B2", String.format("%02d", monsterHp));

        System.out.println(line1);
        System.out.println(line2);
        System.out.println(line3);
    }

    private int calcAttack(int attack, int deffence, String attackerName) {
        int result = 0;
        System.out.println(attackerName + "のこうげき");
        if (attack > deffence) {
            result = deffence - attack;
            System.out.println(Math.abs(result) + "のダメージ!");
        } else {
            System.out.println("こうげきを、はじいた!");
        }
        return attack > deffence ? deffence - attack : 0;
    }
}

じゃんけんゲームから比べてみると、コード量が増えたように見えます。がビビることはありません。

ポイントはメソッド単位で処理を見ることです。
そうすれば、12〜16行くらいなもんです。物により長大なものもありますが。。。

そして、気をつけなければいけないのが、フィールド変数と以下のクラスです。

スーパークラス(親クラス)

今回の実装では、PlayerとMonsterクラスが似たような処理だったので、同じ処理はスーパークラスで管理することにしました。
TextRpgGame#init()でインスタンスを取得している。2つのクラスが実装しています。
具体的には、スーパークラス(親クラス)のCharactorクラスを継承して実装している。ということです。

そして、ネーミングが悪いのもあるのですが、CharactorクラスはJavaのライブラリの中にもありますのでちょっとだけ注意です。

PlayerクラスとMonsterクラスはデータを保持するクラスです。戦闘して互いのHPを削り合う形でゲームは進むので、ほぼデータクラスです。
「たたかう、ぼうぎょ」などのコマンドはそれぞれのクラスに実装します。PlayerとMonsterでは攻撃方法が違うからです。

PlayerクラスとMonsterクラス

フィールド変数とGetter, Stterを主軸に実装したクラスです。
しかし、HPなどのフィールドはスーパークラスのCharactorクラスへ移動しました。

public abstract class Charactor {
    /** 名前 */
    protected String name;
    /** HP */
    protected int hp;
    /** MP */
    protected int mp;
    /** Level */
    protected int level;
    /** 攻撃力 */
    protected int atack;
    /** 防御力 */
    protected int defence;
    /** 武器 */
    protected Wepons wepons;
    /** 防具 */
    protected Armors armor;

    /** 抽象メソッド: 攻撃 */
    public abstract int attack();

    /** 抽象メソッド: 防御 */
    public abstract int deffence();
 ・
 ・
 ・
}

このように、スーパークラスでHPなどは管理しています。
これを継承するPlayerは下のようにコンストラクタとスーパークラスの抽象メソッドをオーバーライドします。

public class Player extends Charactor {

    /** コンストラクタ */
    public Player(int hp, int mp) {
        this.hp = hp;
        this.mp = mp;
    }

    /** コンストラクタ */
    public Player(int hp, int mp, int level, String name) {
        this.hp = hp;
        this.mp = mp;
        this.level = level;
        this.name = name;
        // 装備を行う
        setArms();
    }

    /**
     * 装備を行う。
     */
    private void setArms() {
        this.wepons = new Wepons("ひのきのぼう", 5);
        this.armor = new Armors("ぬののふく", 5);
    }
    /**
     * 攻撃コマンドのメソッド。
     * 武器の攻撃力を返却する。
     * @return 武器の攻撃力
     */
    @Override
    public int attack() {
        this.atack = wepons.getAttackPoint();
        return this.atack;
    }

    @Override
    public int deffence() {
        this.defence = armor.getDeffencePoint();
        return this.defence;
    }
}

そして、setArms()というメソッドでは、武器と防具クラスを生成して、Playerクラスのフィールドに設定しています。
名前の通りに、Weponsは武器、Armorsは防具を示しそれぞれ攻撃力と防御力を算出します。
現段階では、攻撃力と防御力がそのまま設定されていますが。。。

とりあえずは、こんな感じで作っています。
GitからPULLして遊んでみてください。
やり方は、こちらの動画にもあります。

記事もあります。
Eclipse GitからPULL

下の方に、関連ページの一覧がありますのでそちらもどうぞ



関連ページ

Git関連

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜

<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout-key="-6t+ed+2i-1n-4w"
data-ad-client="ca-pub-7367785927150581"
data-ad-slot="3284986237">

関連ページ一覧

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

Java Basic一覧

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す