イントロダクション
昔作成したもので、現在(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()では、ゲームに必要な以下のクラスを生成します。
- 標準入力クラス: JavaAPIで提供されるクラスBufferedReader
- 初期画面クラス: 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"が入力された時に
ループを抜けます。→終了処理へ
ループ処理は以下の順で処理を行います。
- RpgMain#listenInput()でユーザーの入力を受け付けます。
- 入力値が"bye"の時にはループを抜けます。
- 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にて作成中です。
コマンドプロンプトでの起動するバージョンは一応作成しました。※納得いってない形です。。。