イントロダクション
前回は、Java Swingを使用して画面作成を行いました。下のような画面です。
この状態は、表示するための領域があるだけですので、これに表示するもの(内容)を出力する部品が必要になります。
もちろん、出力する内容はテキストRPGの「RPG」の部分です。そのためにまずはタイトルを表示することを考えます。
RpgStoryクラスの作成
ストーリーを表示するための画面を作成したので、今度はストーリーを出力(文字列を読み込んだり)するクラスを作成します。
まとめると、ゲーム進行を開始、実行するクラスです。
ちなみに、現状のクラスは下のようになっています。
RpgStoryクラスの設計
クラスを作成するために、まずは設計を行います。何から考えるか?
1. 目的(役割)を考える
作成するクラスの名前は「RpgStory」という名前に決めました。なのでこのクラスの役割(目的)を考えます。
やりたいことは次の通りです。フローチャートにしてみました。
とりあえず、下のような形で処理を進める形で作りたいと考えています。
- ゲーム開始
- タイトル表示(これもシーンとして扱う)
- 各シーンを表示
-
- Storyの表示
-
- 入力を受ける
-
- 結果の表委
-
- 次のシーンへ移動
-
- Escが押下されたとき、終了シーンに移動したときゲームを終了
こんな感じの処理フローを考えています。これを実現するために頭をひねります。
そして、上記の処理を実現する役割のクラスが「RpgStoryクラス」になりますので、下のようにクラスを作成します。
RpgStoryクラスの実装
まずは、クラスを作成します。Storyや結果などを表示する必要があるのでこのクラスのフィールドにテキストエリアをフィールド変数にセットします。
package jp.zenryoku.rpg;
/**
* クラス RpgStory の注釈をここに書きます.
*
* @author (Takunoji)
* @version (1.0)
*/
public class RpgStory
{
private RpgTextArea view;
/** コンストラクタ */
public RpgStory(RpgTextArea view) {
// ここに実行するための準備を実装する
this.view = view;
}
/**
* テキストRPGのシーンを呼び出し実行する。
* プログラムのメイン処理フローを実装。
*/
public void run() {
// - 1. Storyの表示
// - 2. 入力を受ける
// - 3. 結果の表委
// - 4. 次のシーンへ移動
}
}
そして、ここから考えている処理を実現するための仕組みを考えていきます。そのためにクラスとクラスの関係を作成します。
このクラス同士の関係を作るために必要になる知識が以下のものになります。
クラス関係を作るための知識
「基本」という言葉で丸め込まれることが多いですが、以下のようなものです。
- 通常のクラスの書き方
- クラスの継承の仕方
- インターフェース・クラスの作り方
- 抽象クラスの作り方
すでに、クラスの作り方は学んでいるので大丈夫だと思います。が、作り方がわかっても使うのに慣れていないと、「理解した」というところに、たどり着かないので。。。
クラスを使ってみよう
Javaプログラミングを行うときにはJDKというものを使用してプログラムを使っています。
このJDKにはJavaプログラムを作成した人々が用意しているAPIというものを使うことができます。まずはこのAPIを使い
クラスの扱い方を理解しましょう。
次は、タイトルを表示するために「Story.txt」ファイルを読み込み、それを表示するプログラムを作成します。
ファイルの読み込み
テキストRPGを起動して、初めにタイトルを表示します。このタイトルはRPGを作成するユーザーが作るものなので「固定」ではなく「動的」に作ります。
「動的」とは
上記の通り「固定」ではなく「動的」という言い方がわかりやすいと思うのですが、
固定的に実装
固定的に実装するというのを、初めのプログラムハローワールドを例にして考えてみます。
ハローワールドのプログラムを思い出してみてください。下のように実装しました。
public class Kotei {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
これは固定的で出力する文字列が必ず「Hello World」です。
動的に実装
上記のプログラムを動的に変更します。動的になると必ずしも「Hello World」ではない文字列が出力できます。
でわ、動的なプログラムに修正しましょう。
public class Kotei {
public static void main(String[] args) {
if (args.length != 0) {
System.out.println(args[0]);
} else {
System.out.println("Hello World");
}
}
}
上記のような形で実装すると動的に文字列を表示できます。
このような形で、実装すると表示する文字列を動的に出力することができます。
ファイルを読む形だと?
ファイルを読み込む形にすると、プログラムは全く同じでも、出力する文字列は、ファイルの中身に依存しますので、動的に表示するタイトルを表示することができるというわけです。別な言い方をすると「プログラムの修正をしなくても出力する文字列を変更できる」ということです。
ファイルの読み込み処理
ここで注意が一つあります。本来であれば、ファイルコントロール用のクラスを作るのが、通常のやり方ですが、今回はクラスを作成する一歩前の学習を目的としているので、メソッドを追加する形で実装します。
追加するのは下のようなメソッドです。
private void readFile(String fileName) throws FileNotFoundException, IOException {
File f = new File(fileName);
BufferedReader buf = new BufferedReader(new FileReader(f));
String line = null;
while((line = buf.readLine()) != null) {
System.out.println(line);
}
buf.close();
}
ポイント
throws FileNotFoundException, IOException
の部分は「例外を呼び出し元に投げますよ」という意味です。
具体的には、例外があったときに、上記のメソッドを呼び出しているメインメソッドに例外が投げられます。
Scanner scan = new Scanner(System.in);
System.out.print("入力してください: ");
String in = scan.next();
try {
if (in.equals("test")) {
System.out.println("*** Testing now! ***");
} else if ("file".equals(in)) {
main.readFile("resources/FirstStage.txt");
}
} catch (FileNotFoundException e) {
System.out.println("*** No File! ***");
} catch (IOException e) {
System.out.println("*** What's up!? ***");
}
このコードでは、以下のような処理を行っています。
- 標準入力を受けとる
- 入力した値が「test」の場合は、「* Testing now! *」を表示する
- 入力した値が「file」の場合は、「resources/FirstStage.txt」のファイルを読み込み表示
ここで使用しているメソッドは引数に「resources/ファイル名」を渡しています。つまり、プロジェクト直下にある「resources」フォルダ内にある「FirstStage.txt」ファイルを読み込んで表示します。
このような、「引数にファイル名(パスも含める)」を渡してやれば、ファイルを読み込むようなメソッド、そのような役割を持っているメソッドを作ってやればこのメソッドは、いろんな場面で使用することができます。
このような役割を持たせてメソッドを作ることを練習してできるようになったら、次はクラスにその役割を持たせるように実装します。
メソッドと違いクラスの場合は、もっと大きな役割を持たせることができます。詳細は後々に説明します。まずは、メソッドを作れるようになりましょう。
サンプルの説明
上記に書いた処理を実行していますが、プログラムが動いている部分を見る方が理解が早いと思います。