JAVAプログラミング講座
宇宙のJAVAさん


くま先生の ノベルゲームをつくっちゃお(全?回)

第5回 たまには真面目にやろう


エボ・クマ みなさん、こんばんは! グレート・クマです。

エボ・クマ 前回はフラグ処理をやりましたので、今回は前回のフラグを利用した「分岐処理」を作ります。

みゃあ あれ? 宇宙刑事JAVAN は??

エボ・クマ JAVAN?? なんですか? それは?
多分悪い夢でも見ていたのでしょう・・・

みゃあ そうかみゃ〜?

エボ・クマ 分岐処理画面では、次のようになります。

その時、クマ先生は悩んでいた。
JAVAの脅威はすぐそこまで迫っていたが、いま変身すると
自分の正体がばれてしまう。
しかし、仲間のピンチだ!

どうする?

変身する
逃げる

エボ・クマ このように文章中に選択肢が出てきて、マウスクリックで選択できるようにします。
たとえば、「変身する」を選んだら「hensin.txt」シーンファイルが読み込まれ、ゲームが続きます。
また、「逃げる」を選んだら「nigeru.txt」シーンファイルが読み込まれ、ゲームが続くようにします。
これで、ユーザーの選択によって物語が変化するノベルゲームが作れます。

うし君 なるほども。 ということは、タグを増やすのかも?

エボ・クマ そうです。「選択文を表示する為のタグ」を増やします!
タグは「IF」タグにします。
では、早速作っていきましょう!

エボ・クマ まず、昔設定した screen[] 変数おぼえていますか?

みゃあ もちろんだみゃ〜
たしか画面に表示する15行分の文章を入れておく変数だみゃ。

エボ・クマ  screen[] は表示文章を収納する変数でしたが、こんどは「クリックした時に移動するシーンファイル名」を収納する変数を作ります。

エボ・クマ 変数名は jump[] です。 次のシーンファイル名を入れておくので、String型にします。
グローバル変数に jump[] を追加します。

// グローバル変数

String scene[];
String screen[];
int now_line;
Image img;
boolean flag[];
String jump[];

うし君 当然、init() で初期化だも〜?

エボ・クマ そうです。画面表示文字列 screen[] と同じで jump[15] で初期化します。

public void init() { // 初期処理

scene = new String[1000];
screen = new String[15];
now_line = 0;
img = null;
flag = new boolean[30];
jump = new String[15];

エボ・クマ さて、やはり画面表示文字列 screen[] と同じで、新しい文字(文章)が画面に表示されるときには jump[] も null で初期化します。
関数 SetText()screen[] と同様、jump[] null で初期化します。
null という文字は、JAVAでは特別な意味があって「何にも入っていない」ってことです。

public int SetText( int line ) {

for ( int i=0; i<15; i++ ) {
 screen[i] = null;
 jump[i] = null;
}

みゃあ つぎはどうするみゃ?

エボ・クマ 選択文を表示する「IFタグ」を作ります。
タグ処理はすべて 関数 SetText() に書くので、ここに追加します。
前回作った FDOWNタグ プログラムの下に書きます。

// 「FDOWN」タグ処理
if( st1.equals("FDOWN")) {
 int no = Integer.parseInt( st2 );
 flag[no] = false;
 System.out.println("フラグ"+no+"番ダウン\n");
 continue;
}

// 「IF」タグ処理
if ( st1.equals("IF")) {
  int no = Integer.parseInt( st2 );
  if ( flag[no] ){
    screen[crt_line] = st3;
    jump[crt_line] = st4;
    crt_line++;
  }
  continue;
}

みゃあ なんか、難しいみゃ〜

エボ・クマ IFフラグは、

IF フラグ番号 表示文章 移動先シーンファイル名

という具合に使います。
間は半角スペースであけてください。
例えば、

IF 0 にげる nigeru.txt

の場合は、もしフラグ0が立っていたら「にげる」という文章を画面に表示します。
そして、「にげる」という文章をマウスでクリックしたら、nigeru.txt という名のシーンファイルを読み込んで、次のシーンに移ることにします。
マウスクリックで次のシーンに移るプログラムは、これから書きます。

うし君 えーと、先生の例でプログラムを考えると・・・
st2 変数に「0」が入るも〜
st3 変数に「にげる」が入るも〜
st4 変数に「nigeru.txt」が入るも〜

で、もし flag[0]ture だったら(立っていたら)、現在の画面行番号の screen[] に「にげる」 、jump[] に「nigeru.txt」が入るわけなんだも〜

エボ・クマ そうです。
次のようなシーンファイルがあったとします。

その時、クマ先生は悩んでいた。
JAVAの脅威はすぐそこまで迫っていたが、いま変身すると
自分の正体がばれてしまう。
しかし、仲間のピンチだ!

どうする?

IF 0 変身する hensin.txt
IF 0 逃げる nigeru.txt

その場合、このシーンファイルが読み込まれると screen[] と jump[] は次のような値になります。

screen[0] その時、クマ先生は悩んでいた。 jump[0]  null 
screen[1] JAVAの脅威はすぐそこまで迫っていたが、いま変身すると   jump[1]  null 
screen[2] 自分の正体がばれてしまう。 jump[2]  null 
screen[3] しかし、仲間のピンチだ! jump[3]  null 
screen[4]   jump[4]  null 
screen[5] どうする? jump[5]  null 
screen[6]   jump[6]  null 
screen[7] 変身する jump[7] hensin.txt
screen[8] 逃げる jump[8] nigeru.txt

ちなみに、フラグ0が立っていない場合は、

screen[0] その時、クマ先生は悩んでいた。 jump[0]  null 
screen[1] JAVAの脅威はすぐそこまで迫っていたが、いま変身すると   jump[1]  null 
screen[2] 自分の正体がばれてしまう。 jump[2]  null 
screen[3] しかし、仲間のピンチだ! jump[3]  null 
screen[4]   jump[4]  null 
screen[5] どうする? jump[5]  null 
screen[6]   jump[6]  null 
screen[7]   jump[7]  null 
screen[8]   jump[8]  null 

となり、選択文は表示されません。

エボ・クマ screen[] にセットされた文章は、paint() 関数で上から順に画面に表示されます。

エボ・クマ さて、IFタグは「指定されたフラグが立っている時に表示される」ですね。
どうように、「指定されたフラグが『立っていない時』に表示されるタグ」も作ってみましょう。

タグ名は NIF とします。

NIF 7 そろそろねるか neru.txt

上のような1行があったときは、フラグ7が倒れている時のみ「そろそろねるか」という文章が表示されます。
あまり使わないタグだとは思いますが、あると便利だとおもいますので追加です。
プログラムは簡単です。 先ほどの IFタグ処理プログラムとほぼ一緒です。

// 「IF」タグ処理
if ( st1.equals("IF")) {
 int no = Integer.parseInt( st2 );
 if ( flag[no] ){
  screen[crt_line] = st3;
  jump[crt_line] = st4;
  crt_line++;
 }
 continue;
}

// 「NIF」タグ処理
if ( st1.equals("NIF")) {
 int no = Integer.parseInt( st2 );
 if ( ! flag[no] ){
  screen[crt_line] = st3;
  jump[crt_line] = st4;
  crt_line++;
 }
 continue;
}

エボ・クマ 唯一の違いは、if ( flag[no] )flag[no] の前に「!」 が付いていることです。

 

エボ・クマ さていよいよマウスクリックで次のシーンに移るプログラムです。
プログラムの流れは次のようになります。

(1)クリックされた場合、クリックされたマウスのY座標から、何行目の文章がクリックされたか調べます。

(2)クリックされた行番号の jump[] をチェックします。

(3)もし jump[]null でなかった場合は、jump[] の中には入っているシーンファイル名を呼び出して、次のシーンに移ります。

うし君 なるほども。 IFタグ以外の文章をクリックしても、何もおきないんだも〜

エボ・クマ そうです。 では早速作りましょう。
さてプログラミングする場所は、どこでしょうか? 

みゃあ マウスクリックで処理が始まるから、マウスダウンイベントだみゃ〜

エボ・クマ 正解です。マウスダウンイベントの mousePressed() にプログラムを追加します。
ここには「マウスクリックしたら次の文章を表示するプログラム」がすでに書いてあると思います。
これです。

public void mousePressed(MouseEvent e) {
// マウスダウンイベント

  if( now_line==9999 ) return;
  now_line = SetText( now_line );
  repaint();

} // mousePressed()

これにプログラムを追加します。

public void mousePressed(MouseEvent e) {
// マウスダウンイベント

  int no = e.getY()/22;
  if (no>14) return;
  if ( jump[no] != null ) {
    LoadScene( jump[no] );
    now_line = SetText( 0 );
    repaint();
    return;
  }


  if( now_line==9999 ) return;
  now_line = SetText( now_line );
  repaint();

} // mousePressed()

エボ・クマ では、説明します。

(1) e.getY() 命令でクリックされた場所の Y座標が取れます。それを 22 で割って 変数 no に保存します。
1行と1行の文章の間隔が22ドットなので、22で割ることで「文章の何行目でクリックされたか」が判ります。

(2)つぎに、もし no が15以上だった場合、画面の下の方の文章の無い部分をクリックされたことなので、何もしないでマウスダウン処理から抜け出します。

(3)もし jump[no] が null 出なかった場合、jump[no] にはシーンファイル名が入っているので、そのシーンファイルを LoadScene() 関数を使って呼び出します。 これによりシーンが変わります。

(4)最後に repaint() で再作画をして、新たに呼び出したシーンの文章やCGを画面に表示します。

以上です。

もし、jump[no] が null だったら、クリックした文章は「IFタグの文章」ではなく「ただの文章」なので、次の15行分の文章を表示する処理をします(前回作ったプログラムです)。

 

うし君 プログラムで見ると簡単なのに、説明されると余計に複雑に感じるも〜

エボ・クマ まぁ、そのとおりですね。 実際はたいした処理はしてません。

エボ・クマ あとは、表示です。
「ただの文章」「IFタグの文章」が、現在同じ色(白)です。

これだと、ゲームをやっている人は、どの文章をクリックしていいのか解らなくないです!

そこで、「IFタグの文章」を 水色 にしましょう!

表示なので paint() 関数にプログラミングします。

g.setFont(new Font( "Dialog", Font.BOLD, 17 ));
for ( int i=0; i<15; i++ ) {
  if( screen[i]!=null ){
    g.setColor( Color.black );
    g.drawString( screen[i], 3+2, (i*22)+22+1); // 文字影
    if( jump[i]==null ){
      g.setColor( Color.white );
    } else {
      g.setColor( Color.cyan );
    }

    g.drawString( screen[i], 3, (i*22)+22); // 文字
  }
 }

} // paint()

今までは文字の色は白色だけでしたが、jump[] が null の場合は白色、そうでない場合はシアン(水色)に色をセットして、文字を作画するようにしました。

 

エボ・クマ いちおうこれでゲームは完成です。
IFタグを使って次々シーンを変えれば、長編ノベルゲームも作れますし、
複数のIFタグを表示して、マルチシナリオも作れます。

エボ・クマ 今回のノベルゲームのために、友人の爆裂健がサンプルゲームを作ってくれました!!

エボ・クマ 爆裂健 初の新感覚長編ミステリー 「孤動」!

エボ・クマ 探偵となって、事件を解決してみてください!   

 

みゃあうし君 はーい!

・・・

・・

 

みゃあ ふざけるんじゃないみゃ〜!

うし君 続き書けよ〜! さすが駄目人間の頂点と異名をとる爆裂健!

みゃあ こんな中途半端なミステリー書くなら、宇宙刑事JAVANを進めるみゃ!

うし君 そうだも〜! 真面目に毎日 Web日記 更新しろよも〜!!

エボ・クマ まぁ、そう HEAT しないでください。
彼は彼なりに、精一杯がんばっているんです・・・

 

みゃあ で、いちおうプログラム完成という事は、今回でノベルゲーム講義は終わりかみゃ〜?

エボ・クマ 一応完成といいましたが、まだゲームとして見栄えが悪いので、次は見栄えの良い表示に挑戦です!
このノベルゲーム講座は、まだ続きます。

 

エボ・クマ では、またお会いしましょう!

 

 

テキストファイルのフォーマット(タグ一覧)


# (コメント)        ・・・  コメント用タグ
CG (画像ファイル名)  ・・・  画像表示タグ
CGOFF           ・・・  画像を消すためのタグ
FUP (番号)        ・・・  番号のフラグをONにする
FDOWN (番号)      ・・・  番号のフラグをOFFにする
END             ・・・  テキスト(文章)ファイルの最後に必ず書く

IF (番号) (表示文章) (シーンファイル名)

  ・・・  (番号)のフラグがONだったら、(表示文章)を表示する。(表示文章)がクリックされたら(シーンファイル名)のシーンへ移動。

NIF (番号) (表示文章) (シーンファイル名)

  ・・・  (番号)のフラグがOFFだったら、(表示文章)を表示する。(表示文章)がクリックされたら(シーンファイル名)のシーンへ移動。

 

- 第6話につづく -


宇宙のJAVAさん (C) BakuretuKen 2000

戻る