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


にいさん・・・

にいさん・・・

にいさ〜ん

・・・

・・

 

- 10年前 -

 

スーパー・くま なにやってるんだ、グレート! こっちだ!

スーパー・くま

スーパー・くま (当時12歳)

後のワルグマ将軍

ぐれーと まってよ〜 にいさん!

ぐれーと

グレート・くま (当時6歳)

後のくま先生(宇宙刑事JAVAN)

 

スーパー・くま じゃ、今日は FileDialogクラスの勉強だ!
FileDialogを使うと、簡単に入出力ファイル名をJAVAプログラムに渡せるぞ。

ぐれーと はい!

い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い、い・・・

悪 いんた、ぷりたぁ〜

悪 JAVA Beans 全盛のこのご時世に、 FileDialogクラスか?
スーパー・くまよ!

スーパー・くま お、おまえは、悪のJAVA大王!

悪 スーパー・くまよ。 おまえの実力ならJAVAで天下を取れる。
私と組んで、軟弱なOSをリソース不足で固めないか?

スーパー・くま 断る! JAVAは正しく使ってこそ、優秀な言語だ!

悪 ほほう。 この私に逆らうとはな・・・

ゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴゴ・・・

スーパー・くま 逃げろ、グレート!

ぐれーと でも、にいさん・・・

スーパー・くま いいから行くんだ!

悪 ふ、ふ、ふ。

 

悪 SwingConstants フラッシュ!

ぐれーと わぁ〜

スーパー・くま グレート!

 

どぎゃ〜ん!

 

スーパー・くま だ、大丈夫か? グレート?

ぐれーと にいさん! 血が!

スーパー・くま 大丈夫だ。 俺は奴と決着をつける。
今すぐ逃げろ、グレート!

ぐれーと でも・・・

スーパー・くま いいから行くんだ!

ぐれーと ・・・ わかったよ、にいさん。


悪 最後に聞くが、私と手を組む気はないか?

スーパー・くま くどい! OSは落としても、心まで売るつもりは無い!

悪 そうか、残念だ・・・

 

悪 synchronized void mousePressed(MouseEvent event・・・
public void mouseClicked(MouseEvent event)・・・
public void mouseReleased(MouseEvent event) ・・・
public void mouseEntered(MouseEvent event)・・・

 

スーパー・くま !? 新マウスイベントモデルか! しかも複数!
そうか、JARで固めて一気に来るきか!!

悪 そのとおり! さらばだ、我が永遠のライバル!

悪 JAR -cvf hello.jar *.class アタック!

スーパー・くま ち!
processRequest(HttpServletRequest request) フラッシュ!


 

ぐれーと (はっ、はっ、はっ)

ぐれーと だいぶ離れたぞ。 しかし、大丈夫かな? にいさん・・・

ぐれーと とにかく今は急いで、このことを森のみんなに知らせなきゃ!

 

ギバーーーーーーーーーーーーーン!

 

ぐれーと うわーーーーーーーーーー

ぐれーと な、なんだ!

ぐれーと あ、さっきまでいた山がなくなっている!

ぐれーと そんな・・・

ぐれーと にいさ〜ん!

ぐれーと にいさ〜ん!

ぐれーと にいさ〜ん!

・・・

・・

 

こうして兄と生き別れになったグレート。

そしてこれより10年後、驚くべき再会をはたす。

JAVANなったグレート・クマ、そしてワルグマ将軍。

今再び、森に緊張が走る!

次回、宇宙刑事JAVAN 第4話 「刻(とき)の行方」。

君も JAVAを語るプログラマーとなれ!

 

  − 続く −


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

第6回 見栄えを良くしよう


エボ・クマ こんにちは、みなさん!

みゃあ うし君 こんにちは、くま先生!

エボ・クマ さていよいよ「ノベルゲームをつくっちゃお」の最終回です!
本来なら2000年中に最終回を迎える予定でしたが、馬鹿がいきがった挙句、間に合いませんでした!

うし君 さすがは、だめも〜爆裂健!

エボ・クマ さて前回で一通りプログラムは最低限のプログラムは終わりましたが、見栄えがあまりにへっぽこです。

みゃあ そうだみゃ〜

エボ・クマ そんな訳で見栄えを良くして行きましょう。

エボ・クマ まず最初は、IF分選択文を選ぶ時のマウスカーソルです。
選択文の上にマウスカーソルを持っていくと、カーソルが変わるようにしましょう!

うし君 それはいいかんがえだも〜

エボ・クマ マウスボタンが押されたり、離されたりするのは、MouseListener というリスナーの中にプログラムをします。

この講座で使っている JAVAアプレットの雛型 には、最初からMouseListener は書いてあります。

ソースプログラムの下のほうに、

// マウス処理クラス(MouseAction Class)
class MouseAction extends MouseAdapter{

と書いてある部分がそうです。

このリスナーの中に「マウスボタンが押された時のプログラム(マウスダウンイベント)」「マウスボタンが離された時のプログラム(マウスアップイベント)」を書きます。

今回のノベルゲームでは、マウスダウンイベントの方しか使ってませんが・・・

エボ・クマ さて、「マウスカーソルが動いて、選択文の上に来たらカーソルを変更」という場合は、
「マウスダウンイベント」でも「マウスアップイベント」でもありません!

うし君 どうするのかも?

エボ・クマ 「マウス移動イベント」になります。
マウス移動イベントには、 MouseMotionListener にプログラムをします。
あまりゲームで使わないと思って、雛型には MouseMotionListener を書き込んでません。

そんな訳で、マウスモーションリスナー(MouseMotionListener)を追加します。

マウスリスナー(MouseListener)の下にプログラムを追加します。

public void mouseReleased(MouseEvent e) {
  // マウスアップイベント

  } // mouseReleased()

} // MouseAction

// -----------------------------------------------------------
// マウス移動処理クラス(MouseMotionAction Class)
class MouseMotionAction extends MouseMotionAdapter{

  public void mouseMoved(MouseEvent e){
  // マウス移動イベント

  } // mouseMoved()

} // MouseMotionAction

// ===============================================================
} // End of Class

// マウス移動イベント

と書いてある文の下に「マウスが移動した時に実行されるプログラム」を書きます。

ちょっとでもマウスが動いたら実行されるので、かなりしょっちゅう実行される命令になります。

エボ・クマ で、このリスナーを登録します。

init() の一番下にマウスリスナー(MouseListener)を登録している1行があります。
その下に マウスモーションリスナー(MouseMotionListener)を登録するプログラムを追加します。

  // マウス処理アクションリスナー定義と登録
  addMouseListener(new MouseAction());
  // マウス移動処理アクションリスナー定義と登録
  addMouseMotionListener(new MouseMotionAction());

} // init()

 

エボ・クマ これで、マウスを動かした時にプログラムを実行させるのが可能となりました。

エボ・クマ 次に実際のプログラムです。

エボ・クマ マウスカーソルの形を変えるのは、setCursor() という命令です。

 setCursor(new Cursor(Cursor.HAND_CURSOR))

この命令でマウスカーソルが手の形になります。

 setCursor(new Cursor(Cursor.DEFAULT_CURSOR))

この命令でマウスカーソルが標準(矢印)の形に戻ります。

エボ・クマ さて、問題です。
前回つくった選択文(IF文)と、普通の文章の違いは何ですか??

みゃあ むずかしいみゃ〜

エボ・クマ 前回、選択文だけ水色にする時にやりましたよ。

うし君 そうだも。 jump[] に次のシーンファイル名が入っているのが選択文だも!
普通の文章は、jump[] に null が入っているんだも!

エボ・クマ そうです! そこで、マウスが動いたら、今のマウスカーソルの場所を計算します。
そして、マウスカーソルの場所の行が選択文だったら、マウスカーソルを手の形にします。
普通の文章上だったら、矢印にします。

エボ・クマ では、やっていきましょう。
当然先ほどの マウスリスナー(MouseListener) にプログラミングします。

// -----------------------------------------------------------
// マウス移動処理クラス(MouseMotionAction Class)
class MouseMotionAction extends MouseMotionAdapter{

  public void mouseMoved(MouseEvent e){
    // マウス移動イベント

    int no = e.getY()/22;
    if (no>14) return;

    if ( jump[no] != null ) {
      setCursor(new Cursor(Cursor.HAND_CURSOR));
    } else {
      setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }

  } // mouseMoved()

} // MouseMotionAction

エボ・クマ マウスを押した時と同様に、

e.getY() 命令で、今のマウスのY座標を取ります。
その値を 22 で割ると、マウスカーソルが文章の何行目の上にあるかわかります(文字の縦の間隔が22ドットだから)。

そして、その行の jump[] が null じゃない場合選択文なので、マウスカーソルを手の形にします。
jump[] が null の場合は、普通の矢印のマウスカーソルにします。

エボ・クマ これで、おしまいです。
ついでにマウスカーソルが上に来た場合、選択文の色を変えましょう。

エボ・クマ 選択文は水色ですが、マウスカーソルが選択文の上に来たら赤にするようにしましょう。
先ほどのプログラムの下に追加します。

// -----------------------------------------------------------
// マウス移動処理クラス(MouseMotionAction Class)
class MouseMotionAction extends MouseMotionAdapter{

 public void mouseMoved(MouseEvent e){
  // マウス移動イベント

  int no = e.getY()/22;
  if (no>14) return;
  if ( jump[no] != null ) {
    setCursor(new Cursor(Cursor.HAND_CURSOR));
  } else {
    setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
  }

  Graphics g = getGraphics();
  g.setFont(new Font( "Dialog", Font.BOLD, 17 ));
  for ( int i=0; i<15; i++ ) {
    if( jump[i]!=null ){
      if( i==no ) g.setColor( Color.red );
      else g.setColor( Color.cyan );
      g.drawString( screen[i], 3, (i*22)+22);
    }
  }
  g.dispose();


 } // mouseMoved()

} // MouseMotionAction

エボ・クマ 作画関数 paint() 以外の関数で作画するときは、getGraphics() という命令でグラフィックコンテクスト(GC)という、まぁキャンバスみたいなものを取得します。
paint() の中では、必ずキャンバス(GC)は渡させるのでこの命令は必要ないです。

うし君 大昔、「作画はすべて paint() でやる」って言ってなかったかも〜?

エボ・クマ そのとおりです。 paint() 以外の場所で描かれた画像は、再作画のときに消える可能性があるのです。 このことは、第一部 裏画面編 で説明しています。

ですから、ノベルゲーム画面はちゃんと paint() で作画しています。
WWWブラウザが最小化されたり、他の Window などに隠れてまた出てきても、ノベルゲーム画面が消えることはありません。
このマウス移動関数では、選択文を赤色で上から描きこんでいるだけです。
paint() の方にも選択文の作画プログラムが書いてあるので、問題ないのです。

うし君 なるほども。

エボ・クマ 今回のプログラムは paint() の文章を描く処理(プログラム)とまったく同じです。
15行を上から描いていっているだけです。
だたし、paint() の時と違い、選択文のみ作画しています。
そして、マウスカーソルの場所と、選択文が一致した場合は、水色(cyan)ではなく赤色(red) で選択文を作画しています。

エボ・クマ 早速動かしてみましょう。
適当なシーンファイルを作ります。

マウスカーソルが変更されるか実験しよう。


IF 0 まうすをこの行にあわせてごらん end.txt
IF 0 ほら!マウスカーソルが変わったでしょ! end.txt
IF 0 色も変わるよ! end.txt

END

エボ・クマ 実行してみてください!  

ちなみに選択文をクリックしても次のシーンには行きません!
だって、「end.txt」を用意してなんですから(笑)

うし君 ほんとだ! マウスカーソルが上に来ると、カーソルの形がかわるも!

みゃあ 選択文の色も変わるみゃ!

エボ・クマ 成功です!

 

エボ・クマ あとは、タグを少し増やすことにします。

エボ・クマ まずは、すべてのフラグを倒す「FRESET タグ」
Flag RESET です。
ゲームオーバーの再ゲーム時に、最初のシーンにもどる直前に使ってください。

タグのプログラムは当然、SetText( ) の中に書きます。
前回作った「NIFタグ」プログラムの下に書きます。

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

// 「FRESET」タグ処理
if( st1.equals("FRESET")) {
  for (int m=0; m<30; m++) flag[m] = false;
  flag[0] = true;
  System.out.println("フラグリセット\n");
  continue;
}

エボ・クマ ただ30個すべてのフラグを倒す(false)だけです。
ただし、初期状態でフラグ0は立っているというこのプログラムのルールがありますので、フラグ0は立たせます(true)。

エボ・クマ つぎに強制的にページを切り替える「PAGEタグ」をつくります。
いまの FRESETタグのしたにプログラムを書いていいます。

// 「PAGE」タグ処理
if ( st1.equals("PAGE")) {
  return line+i+1;
}

エボ・クマ なんとこれだけです。
SetText( ) の戻り値は次の文章の行番号になっているので、「PAGE」という行が出てきたら今の行に1を足して return します。
これで、これ以降の文章は、15行の表示を待たず、次のページに持ちこします。

エボ・クマ つぎに一時的に文章を止める「WAITタグ」をつくります。
これも簡単です。

// 「WAIT」タグ処理
if( st1.equals("WAIT")) {
  scene[line+i]="#";
  return line;
}

エボ・クマ 「WAIT」という1行が scene[] で出てきたら、その行を「#」に変えてコメント行とします。
これで次はこの WAIT行には引っかかりません。
そして、行番号を増やさずに return します。
これだけでOKです。

エボ・クマ だいぶタグが増えました。
さしあたりこの講座でのプログラムはこれでおしまいです。
あとはあなたが自由にタグを増やしてください。

エボ・クマ さて、私のミスについてお話しましょう。
SetText() では、「タグ処理」「通常文章処理」「行数オーバーかどうか?」の順番で処理をしています。
タグ処理の IF文では「continue」しているので、まず無いとは思いますが、もし数行のIF文がページをまたぐようなことがあると、行数が15行をオーバーしてエラーになります。
これは IF文の中に15行チェックを入れれば解決します。
IFタグを作るときに、入れるべきでした・・・(~_~;)
それと、NIFタグにも同様に追加します。

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

 

エボ・クマ ついに完成です!!!
では、動かしてみましょう!

 

新感覚長編ミステリー 「孤動」   - BakuretuKen -

   

 

うし君 やっと講座がおわったも!

みゃあ あまりの面倒さに、この講座を始めたことに途中で後悔している爆裂健が目に浮かぶようだったにゃ。

 

エボ・クマ ではみなさん! また次の講座でお会いしましょう!

みゃあ ばいばいにゃ!

うし君 も〜!

 

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


# (コメント)        ・・・  コメント用タグ
CG (画像ファイル名)  ・・・  画像表示タグ
CGOFF           ・・・  画像を消すためのタグ
FUP (番号)        ・・・  番号のフラグをONにする
FDOWN (番号)      ・・・  番号のフラグをOFFにする
END             ・・・  テキスト(文章)ファイルの最後に必ず書く
FRESET           ・・・  すべてのフラグをOFFにする
PAGE            ・・・  ページ切り替え
WAIT             ・・・  文章の一時停止(クリック待ち)

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

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

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

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

 

 

仕 様

フラグは 0〜29 まで、
初期状態ではフラグ0を除くすべてのフラグがOFF。

シーンファイルは最大1000行。
ゲーム画面には最大15行表示される。

 

- ノベルゲームをつくっちゃお END -


宇宙のJAVAさん (C) BakuretuKen 2000

戻る