Java Bassic アプリケーション作成 〜サンプルRpgMainクラス〜

イントロダクション

昔作成したもので、現在(2023-03-18)では、こちらの方を実装しています。

JavaプログラミングのサンプルとしてテキストRPGを作成しようと思います。
文字のみのRPGゲームを考えております。

アプリケーション作成

まだ、ゲームの内容が決まっていないので、処理フロー部分のみ
の実装になりますが、何かしらの「動くもの」を作ることはプログラマーとしてスキルアップの近道であると思います。
JVM = Javaを起動する仮想マシン、JavaVirtualMachine

ソースはこちらになります。

< テキストRPGの処理フロー >
1. 初期処理: リソースの読み込み、ゲームのセットアップ
2. ゲームループ: 入力→描画、データの更新など各処理を行う
3. 終了処理: ゲームを終了する

クラスのアウトライン(RpgMainクラスのプロパティ)

RpgMainのフィールド変数

    /** フィールド変数で自信を管理 */
    private static RpgMain game;
    /** 定数: AP終了コマンド */
    public static final String TERMINATE_GAME = "bye";
    /** 入力を受付るオブジェクト */
    private BufferedReader read;
    /** 画面状態管理オブジェクト */
    private static ViewStatus status;

RpgMainクラスのコンストラクタ

    /**
     * ぶっちゃけてここで初期化(init)処理をやっても良い</br>
     * 最終的にプログラムの設計者の判断に委ねられる</br>
     */
    public RpgMain() {
        // メンバメソッドなのでコンストラクタで呼び出す
        initialize();
    }

コンストラクタでは、initialize()メソッドを呼び出しています。

初期化処理

    /**
     * 入力、出力のためのオブジェクトを生成</br>
     * RpgMainクラスが存在しないならば使用できない様にするので</br>
     * このメソッドはメンバメソッドにしてある</br>
     */
    public void initialize() {
        // 入力受付クラス
        read = new BufferedReader(new InputStreamReader(System.in));
        // *** titleの表示 *** //
        // ViewStats生成
        status = new TitleView();
    }

initialize()では、ゲームに必要な以下のクラスを生成します。

  1. 標準入力クラス: JavaAPIで提供されるクラスBufferedReader
  2. 初期画面クラス: ViewStatusクラスの子クラス

※今後作成していく段階で必要なクラスを全てここで作成します。
現在は、初期画面と1ステージ画面を「new」しています。
イマイチな実装なので、今後修正予定です。※作り直すことにしました。。。

処理を行うメソッド一覧

  • main(): メインメソッドです、以下のメソッドを呼び出します。

    /** 
     * ゲームを起動する </br>
     * 標準入力の受付、「bye」コマンドでAPを終了する</br>
     * 
     * @param args プログラム引数
     */
    public static void main(String[] args) {
        // 初期化処理
        init();
        try {
            // ゲーム起動(GameLoop開始)
            gameLoop();
        } catch(IOException ie) {
            ie.printStackTrace();
            System.exit(-1);
        }
        // リソースの解放
        terminated();
    }

    main()

    上記の様に初期処理〜終了処理を行います。
    もし、想定外のエラーがあった場合、例外のレポートを行います(printstackTrace()メソッドを使用)
    そして、アプリケーションを強制終了します。→System.exit(-1); // 異常終了ステータス「-1」を渡します。

  • init(): 初期処理、RpgMainクラスのインスタンスを生成します。

    /**
     * このゲームでは初期化は必ず1回なのでstaticをつける</br>
     * static -> 静的メソッド=> クラス内にあるがJVMから直で参照される
     * ※JVM => Java Virtual Machine
     */
    private static void init() {
        // mainメソッドと同様にクラスをnewする必要あり
        game = new RpgMain();
    }

    init()

    初期処理を行います。
    RpgMainクラスのコンストラクタを起動します。
    コンストラクタでは、Rpgクラスをインスタンス化してフィールド変数「game」に設定(代入)します。
    ※staticメソッド内では、クラスの内部にあるメソッドでも、クラスをnewする必要があります。

  • gameloop(): ゲームのループ(入力→描画など)

    /**
     * この処理もinit()と同様に必ず1回なのでstaticをつける</br>
     */
    private static void gameLoop() throws IOException{
        /*
         *  <ゲームループ> 
         *  1.入力
         *  2.データ更新、
         *  3.レンダリング(今回はコマンドなので文字出力)
         *  4.「bye」コマンドでゲームを終了する
         */
        while(true) {
            // 1. 入力を受け取る
            String command = game.listenInput();
            // command変数がnullになる可能性があるため定数.equals()の形にする
            if(TERMINATE_GAME.equals(command)) {
                break;
            }
            // 2-1.処理を実行する(タイトル、その他初期表示する
            status = game.execute(command);
        }
    }
  • terminated(): 終了処理、読み込んだリソースを解放します。

    /**
     * ゲームのリソースを解放する
     */
    public static void terminated() {
        // クラスの解放を行う
        game = null;
        System.out.println("This game terminated!, See you next time!!");
    }

処理概要

RpgMainクラスのコンストラクタ

initialize()メソッドで初期処理に必要なリソースの読み込む
クラスの生成などを実行します。※今後増える予定

標準入力と初期画面クラスを生成します。初期画面クラスはフィールド変数に代入(設定)します、この変数(プロパティ)は画面の状態(初期画面、1ステージ画面)など)を表します。

gameloop(): ゲームループ処理を行います。

無限ループを行います。入力にフィールド変数
TERMINATE_GAME="bye"が入力された時に
ループを抜けます。→終了処理へ
ループ処理は以下の順で処理を行います。

  1. RpgMain#listenInput()でユーザーの入力を受け付けます。
  2. 入力値が"bye"の時にはループを抜けます。
  3. RpgMain#execute()を起動しViewStatusを取得します。

ViewStatus(画面状態)は「execute」メソッドを持っていて
コマンドに対応する処理(execute)の後にViewStatus(画面状態)
を返却します。
フィールド変数のViewStatusクラス(画面状態)が切り替わり
ゲームが進行します。

全体的な説明。※ソース

「フィールド変数」

このクラスで使用するプロパティ(フィールド変数)です。
game: このクラス、自分自身になります。
TERMINATE_GAME: ゲーム終了コマンドです。
read: ユーザーの入力を受け付けるクラスです。
status: 画面状態クラスです。タイトル、1ステージetc...

「メインメソッド(main)」:staticメソッドです。

プログラムを初期化してゲームを起動する。最後に終了処理(メモリの開放など)

インスタンス・メソッド→RpgMainクラスに呼ばれる
とスタティック・メソッド→JVMに呼ばれる
を区別するために両方実装しました。

「初期処理メソッド(init)」: staticメソッドです。

RpgMainクラスのコンストラクタを呼び出します。
コンストラクタは、initializeメソッドを実行します
このメソッドはゲームで実行するリソースの読み込み
使用するクラスのインスタンス取得などを行います。

「ゲームループ(gameloop)」: 入力→データの更新→描画を行います。

フィールド変数の標準入力よりユーザーの入力を受けます。
「bye」が入力された時にループを抜ける。
画面状態の「execute」メソッドを実行する。
また戻って同じ処理を行う。


とりあえず、表面的な処理を説明しました。
詳細は今後作りながら解説していきます。

余談

テキストRPGは、バージョンアップ中です。(2023-03-18)
現状としては、Githubにて作成中です。
コマンドプロンプトでの起動するバージョンは一応作成しました。※納得いってない形です。。。

Java Basic ミニゲーム作成 〜コンソールゲーム〜

イントロダクション

コマンドプロンプト(Windows), ターミナル(Mac, Linux)で文字ベースでのゲームを作成しようと試みました。結局ゲームの内容までは届きませんでしたが、入力〜出力までの一連の流れを実装しました。

つまり、ゲームのイメージがあればこのまま完成まで行けるのでは?

別物ですが、こんなものも作ってみました。

Console app sanple....

Introduction

I will create a text based game on terminal or command prompt. But I implemented only from Input to output.

I mean if you have idea then you can implement game?

 

実際に作ったもの

作成したJarファイルはこちらです。ダウンロードして「java -jar ファイル名」の形でコマンドをたたいて動かすことができます。
コマンドプロンプトから起動してください。

Macの場合はターミナルです。コマンドは下のように使います。コマンドの実行例です。
ダウンロードしたディレクトリに移動

  1. cd ダウンロードしたディレクトリ
  2. java -jar ./CmdRpg.jarで起動することができます。
  3. GitからプロジェクトをそのままPullしてきてもおっけ
    プロジェクトのPull方法を参照してください。(Java Git clone in Eclipse 〜サンプルの取得〜)

ゲームの処理概要としては以下の様になります。ソースはこちら

/**
 * ゲームを起動する </br>
 * 標準入力の受付、「bye」コマンドでAPを終了する</br>
 *
 * @param args プログラム引数
 */
public static void main(String[] args) {
   // 初期化処理
   init();
   try {
      // ゲーム起動(GameLoop開始)
     gameLoop();
   } catch(IOException ie) {
      ie.printStackTrace();
   }
   // リソースの解放
   terminated();
}

このクラスは、どんどん拡張(追加で実装)できる様に
筆者なりに考えて作成いたしました。
これを土台にするもしないも自由にやってもらって結構です。

一応、記載しておきます。余計であれば読み飛ばしてください。

【考え方】

起動するメインメソッド→ゲームを起動する部分だけを記述したい。

Execute main method → I would like to write olnly game execution.

  1. メインメソッドから呼び出したい(処理の範囲を切り分け)
    処理を「staticメソッド」で定義。
  2. 処理を「初期化」
  3. 「ゲームループ」
  4. 「終了(リソース解放)」とカテゴリ分けをする。
  5. 静的メソッド(メインメソッドを含む)とメンバメソッドを切り分ける→
    staticが付いているものとそうでないものを使用方法のサンプルとして記述

Static method is called by main method → separates implementation as “init”, “game loop”, “terminated”.

Separates static and member method→as sample for use these.

staticはメインメソッドから直接呼べる

メンバメソッドはインスタンスを作ってからでないと呼べない。

 

フィールドとか、クラスなど、実際にはどの様に使うの?
って部分をソースの方に記載しています。
※わかりずらかったらゴメンなさい

private static void gameLoop() throws IOException{
   // mainメソッドと同様にクラスをnewする必要あり
   game = new RpgMain(); // コンストラクタで入力部品を生成
   /*
    *  <ゲームループ>
    *  1.入力
    *  2.データ更新、
    *  3.レンダリング(今回はコマンドなので文字出力)   
    *  4.「bye」コマンドでゲームを終了する
    */
    while(true) {
        String command = game.listenInput();
        // command変数がnullになる可能性があるため定数.equals()の形にする
        if(TERMINATE_GAME.equals(command)) {
             break;
        }
    System.out.println("コマンド入力値: " + command);
    }
}

プログラムの内容

ゲームを起動して、入力→「コマンド:入力値」を表示する
というシンプルなゲーム?です。
「bye」と入力するとゲーム終了となります。
ここで、コンストラクタを開設いたします。
コンストラクタ→newした時に起動する処理を定義する
メソッドの時と同じ様に引数を与えることができる。

詳細はおいおい理解していきましょう。

今回使用しているのは、
フィールド→staticのものとメンバフィールドがあります。
メソッド   →フィールドに同じ、newしてから使用するのが「メンバ」
メインメソッドから呼ばれているのがstaticです。

ソースに細かいコメントなどをつけております。
参考になればと思います。

カスタムするなら

上記のソース赤字の部分を修正してどの様に入力を受けて何を表示するか?

を自分で考えて作成するのも1つの方法です。

ちなみに、簡単なコンソールゲームを作って見ました。
余計な音が入っています。

プラスαの一覧

JavaDoc

    1. Java Doc 読解〜System.out〜
    2. JavaDoc 読解 〜 Filesクラス 〜
    3. Java Doc読解 BufferedReader
    4. Java Doc 読解〜BufferedWriter〜
    5. Java Doc 読解 List 〜JavaDocList その1〜
    6.  Java Doc 読解 Map

Java Discord

  1. IntelliJ IDEA Discord Botを作る〜Gradle環境のセットアップ〜
  2. Java Discord セットアップ〜Hello Discord〜
  3.  Java Discord ピンポン〜Discordプログラム〜
  4. Java Discord Listener実装〜コマンドを好きなだけ追加しよう〜

JavaFX

  1. Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
  2. ステップアッププログラミング〜Java FxでHelloWorld解説〜
  3. Java StepUpPrograming〜JavaFX で四則計算〜
  4. Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
  5. Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
  6. Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
  7. Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
  8. Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine〜

JUnit関連

  1. Java Basic JUnit 〜テストスイートの作り方〜

Git

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

Java Game作成 〜ゲームの処理フロー〜



LWJGLのチュートリアル: ゲーム処理の流れについて

LWJGLでのゲームプログラム処理フローについてまとめます。
参考にしたサイトは上記のリンクより観れます。

全体として実行する処理は2種類に分かれていました。
・ゲームを起動する準備と終了処理(ループしない)
・ゲーム中の無限ループ処理(ループする)

処理の概要

1. メインメソッド→ゲーム(処理)の起動
2. リソース読み込み
※ゲームに必要なプログラムやイメージファイル、3Dモデルなど)
3. ゲームの終了処理
4. ゲームループ処理(ゲームをプレーしている時の処理)
4-1. 入力に対する処理
4-2. データなどの更新処理
4-3. 画面のレンダリング
4-4. プログラムのスピードが早いのでスピートの調節処理
5. ゲームの終了処理

ソース実行: 前提としてLWJGLのセットアップが完了していること

上の画像は実行結果です。処理フローを流しただけのプログラムになります。
LWJGLは何も使用しておりません
メインメソッドを起動して処理の概要を順番に標準出力へと出力しています。
ちゃんと実装するのは各メソッドの中にTODOコメントを記載しています。
TODOコメントは今後実装する部分、FIXMEは不適切な処理が実装してあるので
それを修正する必要がある部分です。

/**
* チュートリアル1
* ゲームのプログラム的な動きを理解する
*
* @author takunoji
* @see https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Game-loops
*/

public class GameFlow_1 {
/**
 * 起動フラグ
 * 起動中はTRUE
 * 終了するときに FALSE
 */
privatebooleanrunning = false;
/**
 * チュートリアル1を起動する
 * 「LWJGLの基本的な処理フロー」
 * 1. init(): 初期化処理、ウィンドウの作成〜リソースの読み込み
 * 2. gameLoop(): 入力→データなどの更新→画面のレンダリング
 * 3. dispose(): ゲームで使用した全てのリソースを解放する
 * @param args プログラム引数
 */
public static void main(String[] args) {
System.out.println("1: メインメソッド起動");
GameFlow_1 flow = new GameFlow_1();
// ゲームのスタート
flow.startGame();
}
/**
 * ゲームの開始処理
 */
public void startGame() {
System.out.println("2: ゲームを開始します");
init();
gameLoop();
dispose();
}
////////////////////////////////////////////
// <<ゲームの外枠の処理>>
// 1. 初期化
// 2. ゲームのループ処理
// 3. 終了処理
////////////////////////////////////////////
/**
 * 初期化処理、以下の処理を行う
 * 1. ウィンドウの作成
 * 2. リソースの読み込み
 */
public void init() {
System.out.println("3: ゲームを初期化します");
// ゲームを起動するので起動フラグをTRUEにする
running = true;
// TODO-[初期化処理を実装する]
}
/**
 * 終了処理
 */
public void dispose() {
// TODO-[ゲームで使用したリソース全てを解放する(終了処理)]
}

/**
 * ゲーム起動中の処理
 * ゲーム起動中は無限ループしている中で
 *
 * 以下の処理を繰り返す
 * 1. 入力を受ける
 * 2. データなどの更新
 * 3. 画面を更新する
 */
public void gameLoop() {
System.out.println("4: ゲームループを開始します");
long sleepTime = 1000L / 60L;
// ゲーム起動中は無限ループする
// FIXME-[ここは修正する必要があるときに使用する]
// 起動した後にFALSEに戻す処理がないので止まらなくなる
while(running) {
input();
update();
render();
// プログラムはものすごいスピートで
// 処理をしているので処理休憩する時間を作る
sleep(sleepTime);
// FIXME-[間違って実行したとき用]
running = false;
System.out.println("9: ゲームループをぬけます");
}
}

////////////////////////////////////////////
// <<ゲームのループ処理>>
// 1. 入力を受け対応する処理を行う
// 2. データなどの更新処理
// 3. 画面のレンダリング処理
// 4. 処理を少し止める(スピートの調節)
////////////////////////////////////////////

/**
 * 入力に対する処理
 */
public void input() {
System.out.println("5: 入力処理を実行します");
// TODO-[入力に対応する処理を実装]
}

/**
 * データなどの更新処理
 */
public void update() {
  System.out.println("6: ゲームデータなどの更新処理を行います");
// TODO-[更新の処理を実装する]
}
/**
 * 画面のレンダリング処理
 */
public void render() {
System.out.println("7: ゲーム画面をレンダリングします");
// TODO-[画面のレンダリングの実装]
}

/**
 * 16ミリ秒の固定スリープ時間があるため、ゲームは毎秒62.5回更新されます。
 * ※サイトより引用
 * @param time
 */
publicvoid sleep(long time) {  System.out.println("8: 処理が早すぎるのでスリープします");
// TODO-[スリープ処理を実装する]
}
}

関連ページ一覧

  1.  Chapter1[セットアップ〜外枠の表示のみ]
  2. Chapter2-1〜クラスの構成〜
  3. Chapter2-2〜インターフェースの使い方と詳細〜
  4. Chapter2-3〜GameEngineクラス(サンプルクラス)〜/li>
  5. Chapter2-4〜Windowクラス(サンプルクラス)〜
  6. Chapter3〜描画処理を読む〜
  7. Chapter4〜シェーダについて〜
  8. Chapter5-1〜レンダリングについて〜
  9. Chapter5-2〜レンダリング詳細〜
  10. Chapter6Projection(投影)
  11. Chapter7-1〜Cubeを作る〜
  12. Chapter7-2〜Texture〜

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 4Boolean
  5. Java Basic Level 5If 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 8.5 Array
  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

Java ゲーム作成 〜LWJGLを学ぶ〜

イントロダクション

マインクラフトはJavaで出来ていることは多くの人が知っているかと思います。
実際にどんな風に作ってるの?という部分に足を踏み入れたいと思います。

LWJGLを学ぶ

GitからLWJGLのチュートリアルをクローン(ダウンロード)

上記のドキュメントのリポジトリにある1章(Chapter01)を参照すれば、サンプルを起動する方法がわかりす。筆者はMavenを使用して行いました。
詳細は、LWJGLの学習履歴をご覧ください。

LWJGLとは

マインクラフトよろしく、下のような3Dオブジェクトを表示したり、操作したりすることができる。いわゆるフレームワークです。
使用しているテクノロジーとしては、OpenGL、OpenALなどいろいろあります。ちょっと難しい感じの内容がありますが、表面部分であればそこまで難しくありませんでした。※サンプルを実行するだけですが。。。

下のような感じで操作ができます。その仕組みを学ぼうというところがこちらの記事にあります。


以下、古い情報です。

参考サイト: LWJGL3

上記のサイトを参考に写経しました。ソースはここからダウンロードできます。
※参考サイトからコピペもできます。初めのrun()のみ抜粋
TODOコメントをつけておくとIDE(Eclipseなど)でタスクの一覧を取得して
「あ〜直しておかないとな....」と気がつくことができる

/**
*  初期化処理<BR>
* ※間はよくわからなかったので TODOコメントをつけております。
* エラー時のコールバックのデフォルト設定<BR>
* GLFWの終了処理設定と自由呼び出しのコールバック関数指定
*/
public void run() {
   System.out.println("LWJGJL Version = " + Version.getVersion());
   // 初期化処理
   init();
   // TODO-[よくわかりませんでした。]
   loop();
   // TODO-[よくわかりませんでした。]
   // Free the window callbacks and destroy the window
   glfwFreeCallbacks(window);
   glfwDestroyWindow(window);
   // Terminate GLFW and free the error callback
   glfwTerminate();
   glfwSetErrorCallback(null).free();
}

とりあえず、参考サイトから写経しました。
実行結果は以下の通りです。
 ←バージョン名を表示しています。

とりあえずで表示しただけなので「おお〜起動したよ」ということ
以外に何もありませんが、まぁここから戦いの始まりということです(笑)

<JavaDoc:クラス(メソッド)の使い方が書いてあります>
ここのURLから参照できます。

<Wiki: ここにポイントとか色々と書いてあります>
WikiのURLはこちら

<DEMO: デモンストレーション>
Gitからソースをダウンロードしてビルド、Jarファイルを作成して実行

<その他: 実装中に困ったときに助かります。>
Memory FAQBindings FAQTroubleshooting

参考にしたチュートリアル

関連ページ一覧

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 〜テストスイートの作り方〜

Git関連

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

JavaFX関連ページ

  1. Eclipse SceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
  3. JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜
  4. Java プロコンゲーム 〜見た目の作成(SceneBuilderの使用)〜