JAVAプログラミング講座
宇宙のJAVAさん
< 某 空間 >
宇宙(そら)を落とすには、まず地球から・・・
ぶー!
行け! ぶーよ! われらの力を思い知らしめるのだぁあああああ!
ぶー!
・・・・・・・・・
・・・・・・
・・・・
・・
・
< JAVA対策本部@地球 >
JAVAが出たも〜!!
またかにゃ! どうするみゃ!
ぼ、防衛システム、全開もー!
レーダーシステム、コンパイルエラーの為、ダウン!!
JAVAレベル感知センサー、オーバーフローの為、ダウン!!
・・・
だから、あれほど「short
で宣言するな!」と言ったのに・・・
メモリー節約も、どが過ぎると嫌味だも〜
敵、有視界に入ります!
|
|

・・・
にゃ? こんなときに
くま先生 がいないみゃ?
< JAVA対策本部付近@地球 >
ふふふふふ・・・
JAVAC
!
説明しよう。
くま先生は「JAVAC」と唱えると、高速コンパイルを開始し、
地球を守る宇宙刑事に変身できるのだ。
ときどき変身時に コアダンプ することがあるが、気にしない。
速やかに「.core ファイル」を消して、無かったことにすれば良い。
宇宙刑事
JAVAN !!!
< JAVA対策本部@地球 >
くそー、どうすることもできないも〜
みゃ? あれは、誰だみゃ?
JAVAN参上!
ぶー!
ふ、あまいな。
Image、メソッド、flush() !
ぶ?
どがぁーーーーーーーーーーーん !
さらば。
突如現れた謎のヒーロー。
その正体はいったい何者なのか?
謎が謎を呼び、爆裂健は酒に逃げる。
次回、宇宙刑事JAVAN 第2話 「コンパイルエラーの秘密」。
君も JAVAを語るプログラマーとなれ!
− 続く −
くま先生の ノベルゲームをつくっちゃお(全4回)
第3回 画像を出そう
さて、前回は画面に文章を表示させました。
ノベルゲームと言えば、背景に画像が必要です。
そこで 今回は、タグで指定した画像を画面に出すプログラムに挑戦です。
JAVANの正体はいったい誰なんだにゃ?
これこれ、みゃあちゃん。 今はJAVAの講義中ですよ。
ごめんみゃ。
画像はどうやってひょうじするも?
タグで指定できるようにします。
「CG タグ」を追加しましょう。
CG kuma.gif
と文章内に書くと、 kuma.gif が表示されるようにします。
JAVAで使える画像は、gif と jpeg です。
では、実際に始めましょう。
表示画像を入れておくための変数を、グローバルで宣言します。
変数名は img です。
| // グローバル変数 String scene[]; String screen[]; int now_line; Image img; |
で、当然
init() でimg を初期化します 初期値は null です。
| public void init() { // 初期処理 scene = new String[1000]; screen = new String[15]; now_line = 0; img = null; |
当然
paint() にimg を表示するプログラムを書きます。
もし img が null だった場合は、表示しないようにします。
| public void paint(Graphics g) { // 作画処理 g.setColor( Color.gray ); g.fillRect( 0, 0, 480, 360 ); if ( img != null ) { g.drawImage( img, 0, 0, this ); } |
これで、画像を表する準備はできました。
つぎにタグの処理です。 これはかなり面倒になります。
タグ処理は SetText() 関数で行います。
前回作った SetText() 関数は、ただ scene[] から screen[] に15行コピーするだけの簡単なものでした。
今回はタグ処理プログラムを書きます。 前回の SetText() 関数の中身のほとんどを消してください。
| public int SetText( int line ) { for ( int i=0; i<15; i++ ) { screen[i] = null; } for ( int i=0; i<15; i++ ) { if (scene[line+i].equals("END")) return 9999; screen[i] = scene[line+i]; } if (scene[line+15].equals("END")) return 9999; return line+15; } // SetText() |
さて、前回はただ15行コピーしただけだったので15回ループをすれば処理が終わりました。
しかし今回は、何回ループするかわかりません。
にゃ? 15行表示だから、やはり15行ループじゃないのかみゃ?
違うんですよ。 文章は15行ですけど、文章の中にタグが入っている場合がありますね。
たとえば、
|
ある日 森の中 くまさんに出会った |
この文章が scene[] に入っているとしましょう。
文章は11行ですけど、「CG kuma.gif」という行はタグですので、文章として表示しません。
極端な話、文章が15行で、間にタグが20行入っている場合は、35回ループをしないと画面に表示する15行分の文章が取得できないのです。
にゃるほど。
ですから、ループは無限に行い、条件でループを抜けるようにします。
| public int SetText( int line ) { for ( int i=0; i<15; i++ ) { screen[i] = null; } for ( int i=0; i<1000; i++ ) { } } // SetText() |
無限じゃないも? 最大1000回だも?
便宜上無限といいましたが、
scene[] の最大行数が 1000 なので、1000回以上ループする必要はないのです。
なるほども。
つぎに「画面表示配列
screen[] の何行目まで収納されているか?」を収納する変数を宣言します。
変数名は crt_line です。 これが15に達したら、ループ終了です。
|
public int SetText( int line ) { int crt_line = 0; |
さて、ここからが今回のメインです!
おお!
「文字列の切り出し」を行います。
切り出しってなんだにゃ??
半角スペースで区切られている文字列を、ばらばらにするのです。
つまり、次のような文章が1行あったとします。
| ある日 森の中 くまさんに出会った |
この1行を「ある日」「森の中」「くまさんに出会った」に分ける処理です。
ちなみに「ある日」「森の中」「くまさんに出会った」は、半角スペースで区切られています。
文字列の切り出しには「
StringTokenizer 」を利用します。
StringTokenizer変数に文字列を入れて、nextToken() メソッドを実行するたびに、左側から文字列が切り出されます。
ちょっと参考までに、プログラムを作りましょう。
|
String s = "ある日 森の中 くまさんに出会った"; StringTokenizer st = new StringTokenizer ( s ); String a1 = st.nextToken(); |
これで文字列の切り出しができます。
さて、うし君、変数 a1、a2、a3 には何が入っているかな?
a1
には「ある日」、 a2 には「森の中」、 a3 には「くまさんに出会った」
が入っているも〜
そのとおり。 これでスペースで区切られた個々の文字列を取り出せます。
さっそく、文字列切り出しように変数宣言します。
切り出された文字列を入れるための st1〜st4 変数と、StringTokenizer を宣言します。
| public int SetText( int line ) { for ( int i=0; i<15; i++ ) { screen[i] = null; } int crt_line = 0; String st1,st2,st3,st4; StringTokenizer st; |
さて、先ほどの無限(1000回)ループの中に、文字列切り出しのプログラムを書きます。
まず、st1〜st4 を null で初期化して、scene[] の指定行を、切り出しのため StringTokenizer 変数に入れます。
|
for ( int i=0; i<1000; i++ ) { } |
で、st
に入っている文字列を、切り出します。
| for ( int i=0; i<1000; i++ ) { st1=null; st2=null; st3=null; st4=null; st = new StringTokenizer(scene[line+i]); if ( st.hasMoreTokens() ) st1 = st.nextToken(); if ( st.hasMoreTokens() ) st2 = st.nextToken(); if ( st.hasMoreTokens() ) st3 = st.nextToken(); if ( st.hasMoreTokens() ) st4 = st.nextToken(); if( st1 == null ) st1=" "; } |
hasMoreToken()
ってなんだも???
それはですね。 まだ文字列が切り出せるかどうか調べる命令です。
すでに切り出し終わっている st に st.nextToken() 命令を出すとエラーになりますので、
その前に切り出せるかどうかのチェックをしているんです。
if(
st1 == null ) st1=" "; は、なんだも???
いらないと思うも??
必要です。 リターンだけの行があった場合、切り出しは行われずに
st1〜st4 すべてに null が入ります。
これから st1 がタグかどうかのチェックをするプログラムを書きますが、null をチェックするとエラーを出すので、半角スペースを入れてやっているのです。
たとえば、
CG kuma.gif
という行が、scene[] にあったとします。
その場合は、
st1 に 「CG」
st2 に 「kuma.gif」
st3 に null
st4 に null
が、入ります。
じゃ、タグ処理プログラムを書いていきます。
タグ処理プログラムとは「st1 がタグかどうかチェックして、もしタグだったらそのタグの動作をする」というものです。
まずは、「END」タグから・・・
| for ( int i=0; i<1000; i++ ) { st1=null; st2=null; st3=null; st4=null; st = new StringTokenizer(scene[line+i]); if ( st.hasMoreTokens() ) st1 = st.nextToken(); if ( st.hasMoreTokens() ) st2 = st.nextToken(); if ( st.hasMoreTokens() ) st3 = st.nextToken(); if ( st.hasMoreTokens() ) st4 = st.nextToken(); if( st1 == null ) st1=" "; // <<タグの処理>> if ( st1.equals("END")) { return 9999; } |
END
タグがあった場合は、返り値9999 でリターンします。
なぜ 9999 なのかは、前回の講義を読んでください。
じゃ、次のタグは「#」タグです!
これは、コメントアウト用のタグにしましょう!
たとえば、
# シーン17(回想シーン)
という行があった場合、何も処理されませんし、この行が画面に表示もされません!
| // <<タグの処理>> if ( st1.equals("END")) { return 9999; } if ( st1.equals("#")) { continue; } |
「#」タグは簡単です。 何もしないで次の行を読み込むために
continue するだけです。
タグを考えるのは楽しいみゃ!
次はどんなタグを追加するみゃ???
もちろん今回の講義のタイトルのCGを表示するためのタグです。
「CG」タグとしましょう。
たとえば、
CG kuma.gif
という行場あった場合は、画像ファイル「kuma.gif」が画面に表示されます。
| // <<タグの処理>> if ( st1.equals("END")) { return 9999; } if ( st1.equals("#")) { continue; } if ( st1.equals("CG")) { img = getImage(getDocumentBase(), st2 ); continue; } |
st1
が 「CG」だった場合、st2 の画像ファイルを img に読み込みます。
それだけです。
同様に、CGを消すタグを作りましょう。
「CGOFF」タグとします。 このタグがあった場合、今表示されている画像が消えます。
| // <<タグの処理>> if ( st1.equals("END")) { return 9999; } if ( st1.equals("#")) { continue; } if ( st1.equals("CG")) { img = getImage(getDocumentBase(), st2 ); continue; } if ( st1.equals("CGOFF")) { img = null; continue; } |
これも簡単です。 img
変数に null 入れるだけです。
さしあたり、今回のタグはこれで終了です。
この要領で「音を鳴らすタグ」などが増やせます。
では、次にタグでなかった場合の処理です。
タグでない場合?? なんだみゃ??
何言ってるんですか。 タグでない場合は「文章」ですよ!
画面に表示しなくてはなりません。
そうだみゃ!!!!
これはノベルゲームだも〜 文章忘れちゃ、だめも〜
では、さっきのタグ処理プログラムの下に追加します。
|
if ( st1.equals("CGOFF")) { } |
ここいらの処理は、前回やりましたね。
scene[] の文章を 画面表示関数 screen[] にコピーします。
で、screen[] は crt_line 行まですでに文章が入っていることになってますので、新たに文章をコピーしたら crt_line
を1つ増やします。
なるほども。
あとは、15行文章を読み終わったかどうかのチェックです。
15行文章が読み終わったら、リターンで返ります。
返り値は line+i+1 になります。 次に scene[] をコピーするための行番号です。
これについても前回の講義を読んでください。
| // <<タグがない場合の処理>> screen[crt_line] = scene[line+i]; crt_line++; if (crt_line == 15) return line+i+1; |
あと、前回同様、15行読んだときにすぐ下の行が「END」かどうか調べます。
15行読み終わった後、すぐ下の行が「END」タグだった場合、一見まだ文章が続くように見えますが、事実上文章がすべて終わりだからです。
| // <<タグがない場合の処理>> screen[crt_line] = scene[line+i]; crt_line++; if (scene[line+i+1].equals("END")) return 9999; if (crt_line == 15) return line+i+1; } return 9999; } // SetText() |
それと、最後に
return 9999 を書きます。
この行が処理されることはまずないのですが、これがないとコンパイル時にエラーを出します。
これで、今回のプログラミングは終了です。
ついにこの述べるゲームも、「タグによる制御」ができるようになりました。
うごかしてみるみゃ?
では、文章ファイルにタグを書き込みます。
「#」タグ、「CG」タグ、「CGOFF」タグを書き込みましょう。
あと、「CG」タグで利用する画像も用意しましょう。
画像サイズはゲーム画面サイズと同様、 480x360 が良いでしょう。
GIF と JPEG 画像フォーマットが利用できます。
ちゃんと、画像が出てきて、次に消えるみゃ!
無事動いてるも〜 コメント行は表示されていないから、「#」タグもOKだも〜
では、次回は次のシーンへ移動するためのプログラムです。
これで、マルチエンディングも思いのまま!
やっと次回最終回だも〜
あ、それなんですが、最初に(全4回)って書きましたが、あれ嘘になりました。
も?
なんか、4回だと終わない予感が・・・
多分、「ノベルゲームをつくっちゃお」は、全5回 になると思います。
さすがは
くま先生! いいかげんだみゃ!
しかも今回は、最初の導入の馬鹿話が長い上に、プログラム説明が多かったので、爆裂健が
へろへろ になっています(今!)。
何気に作るのが大変なコーナーだったんだみゃ〜 知らなかったみゃ〜
では、次回の講座でお会いしましょう!
|
テキストファイルのフォーマット(タグ一覧)
|
|
|
- 第4話につづく -
|
宇宙のJAVAさん (C) BakuretuKen 2000 |