Since 1/15'97
第9回 Bird SAMPLE
最新 Bird SAMPLE
※(97.4/5)JDK Ver.1.1.1で再コンパイルするとマウスのイベント処理が拡張されたのでより最適化するには、提供するDocumentを読むようにというWarningが出るが、コンパイルは正常に終わる。Document はまだ読んでいない。
また、インターラクティブなオブジェクトは導入したいがプログラミングはどうもという人に最適なJava作成ソフトも出てきています。詳細は分かりませんが、自動的にプログラム化してくれるようです。
この本は、Javaアプレットの概要説明と簡単なプログラムの例題による説明からなっていて、ページの大半は出来上がったフリーやシェアウエアのアップレット紹介にとどまっていて、これを持って開発するというにはちょっと無理がある。Javaアプレットとは、どんなもので、何が出来るかを知る読み物と思った方がいいかもしれない。参考書(2)・・・Javaプログラミング講座(Sun Microsystems,Inc.:アスキー出版)
付属CD-ROMには、JDK1.01と多くのアプレットが収録されている。
※JDK = Java Developer's Kit
これも入門書であるがプログラムの作成を主眼に置いている。全体を通してプログラムの概要説明と用語のリファレンスとなっている。しかし、用語(や、コマンド)の詳しい説明が省かれているので、これだけで一から作っていくには無理があるかもしれない。コンパイラ・・・JDK1.02
付属CD-ROMには、JDK1.02と例題となるソースが含まれている。
※ノートン・ファイルマネージャーはファイル名の大文字小文字を正確に表示しないので必ずしもお勧めするものではありません。JDKのコンパイラはDOSプロンプト上で行う。秀丸エディタで作成し、DOSプロンプトに入り、ソースのあるフォルダにカレントを移動し、コンパイルを行う。
※ファイルマネージャを使わなくても、エクスプローラから好みのフォルダに簡単に移動して、DOSプロンプトに入ることができる DosPromptFromHere というプログラムがある。これは、マイクロソフトの PowerToy というフリーソフトのユーティリティ集の中にある。・・・後日入手したこのファイルマネージャで気を付けないといけないのは、ファイル名の表示が全て小文字を使っていても、先頭大文字で表示され、サーバーのように大文字小文字を区別する環境でファイルが読めないといったトラブルが起こりうる。
※DOSKEYに関しては、Windowsでは無用であるがメモリ上に常駐するので、AUTOEXEC.BATから現在は外している。必要な時にDosPrompt上で、doskey /insert とタイプすれば常駐する。 ※(6/26)もっと簡単な方法は、command.comまたはDosPromptのショートカットのプロパティで、プログラム・タブのバッチ ファイルに doskey を書き込んでおけば、DOSプロンプト起動時に常駐する。残念ながら、/insert は書き込めない。常駐後、insert KEY を押せばよい。(詳しくは、Windowsディレクトリにある Tips.txt を参照のこと)
当初、ホームページ(表紙)に wav形式の小鳥の声を入れていたが、これは IE ( Internet Explorer Ver.xx )でしか、聞くことが出来ない。
これが NN ( Netscape Navigater ) でも聞けないかということから Javaの実験が始った。IEもVer3.0になってJavaに対応した。Javaであれば、最もポピュラーなブラウザの標準機能で動作する。
Javaでサウンドを発生するには、wav形式では扱えない。まず、wavの音をau形式に変換しなくてはならない。変換ソフトとして、取り敢えず、Coolを使う。Win95用にはCool95を使う。シェアウェアであるが、一定の試用期間がある。ただ、全て英語のため使い方がよく分からない。とにかく編集したいサウンドデータをCool95.exeか、そのショートカットにドラッグ&ドロップするとデータを読込んで起動する。
起動すると波形が表示されるので、音の一部だけを切り取りたい時には、切り取りたい音の始点から終点までをドラッグすると色が反転するので、メニューのEditでCopy。FileのNew Instanceを選ぶともうひとつCool95が起動するので、これにPasteする。
これをSave Asでau形式(Next/Sun(*.au,*.snd))を選択してSaveする。但し、ここで単にSaveしてau形式のファイルが出来てもJavaで使える音にはならない。
読込んだwavデータのSample Rateは、11025であった。実際に音の出るau形式データのSample Rateを調べると皆、8000となっている。
メニューのEditにAdust Sample Rateという項目があるので、ここで8000にする。これを保存すると見事音が出た。もちろん、ここで音を出すためには、音を出すためのJava Appletが出来ていなくてはならない。
その時のソースは// Bird1.java import java.applet.*; public class Bird1 extends Applet { AudioClip cuck; public void init() { cuck = getAudioClip(getDocumentBase(), "sounds/bird.au"); } public void start() { cuck.play(); } }となる。これは、ほとんど例題から、サウンドに関係ない部分を削除しただけのソースである。ファイル名は Bird1.java とする。
Bird1.java のあるディレクトリをカレントにしてDOSプロンプトで javac Bird1.java と打てば、同じディレクトリに Bird1.class という実行ファイルができあがる。
もちろん、このコンパイルの前に、JDKをインストールしておく必要がある。いよいよ、HTMLファイルにJavaを実行させるための1行を記入する。
<applet code="Bird1.class" width=100 height=50></applet>この1行で、実行できるはずである。但し、これでは、画面に幅100ドット、高さ50ドットのグレーの穴があいてしまう。
音を出すだけなので、こんな枠は要らない。ということで、<applet code="Bird1.class"></applet>とした。これをIEでローカルな環境で試すと、見事、小鳥の声がして成功だ。すぐさまアップしようと思った時に、ひとつ忘れていたことに気がついた。
NNでまだ試していない。NNで試すと、なんと、ホームページの真ん中にぽっかりグレーの穴があいている。
解説書をよくよく見るとwidth=100 height=50は省略できないとある。ここは、width=0 height=0としなければいけないのだ。
ここでも、IEは間違いを見逃す方向に、NNは間違いをより顕著に表示するという原則が生きていた。果たして、どちらが親切なのか。
// Bird1.java// に続く文はコメントとなり、行の最後まで、何を書いてもコンパイルには影響しない。通常、タイトルや作成日付などを書いておく。署名などでもよい。
import java.applet.*;全てをはじめからプログラムしなくてもいいように、通常コンパイラには、ライブラリというコードを用意している。この import で、必要なライブラリを取込む宣言をする。java.applet.* は、java.applet.Applet を含むライブラリ(パッケージとも言うようだ)を取込むことになる。HTML文書で利用するには必ず必要となる。
この他に、画像を扱うには java.awt.Graphics や java.awt.Image などがあるが、これもimport java.awt.*;などとしておけばいい。public class Bird1 extends Applet {ここから、プログラムの本文に当たる部分を書くことになるが、この1行も決まり文句と思ってよさそうだ。Bird1 が、Appletの名前ということで、勝手に決めてよい。大文字小文字は区別されるので、気を付けたい。AudioClip cuck;AudioClip は、オーディオを扱う時の変数を宣言する決まり文句で、cuck が変数ということで、kakou でも、chun でもよい。
ただし、何を変数にしてもよいわけではない。予約語というものがあり、変数(識別子ともいう)に使ってはいけない言葉(キーワード)もある。例えば、if、do、default、const やベーシックで有名な goto その他があるが、このうち const と goto は、実際には使われないが、識別子として使ってはいけない。public void init() { cuck = getAudioClip(getDocumentBase(), "sounds/bird.au"); }このルーチンはHTMLが読込まれる時に、一度だけ実行される。cuck という変数に実際の音のファイルを代入するということになる。
HTMLを置いたディレクトリの下の sounds というディレクトリにある bird.au というサウンドファイルを代入する。
データの初期化作業を行う。
cuck と sounds/bird.au 以外は、決まり文句と思って間違いない。public void start() { cuck.play(); }音を出すルーチンで、public void start() は、このHTMLが表示される度に、実行される。従って、別のページに行って、また戻ると実行され。小鳥が声を出すことになる。
//によるコメントは、どこに置いてもよく、人が読んで分かるように書くというのが鉄則のようである。
事実、趣味でC言語をやっていた時、結構大きなプログラムを書いていたことがあった。書いている時にはなにもかも頭にあり忘れることはないと思いがちである。が、しばらくして見ると、なぜそうしたかを、すっかり忘れていることがある。
コメントは、いくらかいても Applet のサイズには影響しない。
作成中に、人に分かるように書いておけば、後で読み返した時に、他の人が分かるように、自分も分かるということになる。
明日の自分は今日の自分とは違う。人のためが、実は自分のためになる。
今回は画像の表示。先ず表示したい画像を作成する。そのために画像の大きさの決定。大きすぎず、小さすぎずということで、背景を横400ドット縦30ドットとした。これを元に、HTMLファイルに加える1行は、<applet code="Bird2.class" codebase="./java/" width=400 height=30></applet>となる。
大きさは、width=400 height=30 で指定する。今回は第2回ということで、Bird2.javaというファイル名でソースを作成するので、code="Bird2.class"とする。しかも、Bird2.classをHTMLファイルのあるディレクトリの下のjavaというディレクトリの下に置くので、codebase="./java/" と書く。
これがなかなか分からなかった。
通常、code="java/Bird2.class" とすれば、出来そうな気がするが、これではだめ。codebase="java/" も、試してみたが、これもだめ。
参考書の説明は全て、THMLとAppletが同じディレクトリにあるという前提で書かれていて、codebase= を使った例題がない。
ともかく、これで、HTML側の設定は出来た。
この背景に置く小鳥のサイズは縦30ドット、横30ドットとする。PaintshopProを使ったが、Windows標準のPaintでも出来る。但し、背景を透明にしたいので、透過GIF用の変換ツールは必要だろう。PaintshopProであれば、変換ツールは必要ない。
実は、作成過程でソースを残しておかなかったので、作成時のものとは違うが、次のようなソースとなる。// Bird2.java import java.applet.*; import java.awt.*; public class Bird2 extends Applet { AudioClip cuck; Image im; int MouseX = 50, MouseY = 0; public void init() { im = getImage(getDocumentBase(), "java/images/Bird.gif"); cuck = getAudioClip(getDocumentBase(), "java/sounds/bird.au"); } public void start() { cuck.play(); } public void paint(Graphics g) { setBackground(Color.white); g.drawImage(im, MouseX, MouseY, this); } public boolean mouseDown(Event evt, int x, int y) { MouseX = x+20; MouseY = 0; repaint(); cuck.play(); return true; } }
import java.awt.*;これはグラフィック関係のライブラリを使用するということで、宣言する。必要に応じて awt.* でなく、import java.awt.Graphics; import java.awt.Event; import java.awt.Image; import java.awt.Color;というように、選択的に並べてもよいが、awt.* で全てを含んでしまう。Image im; int MouseX = 50, MouseY = 0;im という変数をイメージデータ用に宣言する。
int は0から始る整数を宣言する。MouseX は変数で、MX でも構わない。MouseX とした方が分かりやすい。
イメージデータの座標は左上が(0.0)で、
Javaのグレーの枠も左上が、(0.0)となる。
ここでは、MouseXとMouseYの初期値が、左から50ドット、上から0ドットとしている。im = getImage(getDocumentBase(), "java/images/Bird.gif");これは変数 im に Bird.gif というイメージデータをセットする決まり文句。java/images/Bird.gif はHYMLからの相対パスで記入する。public void init()の中にあるので、最初の1回だけ実行される。public void paint(Graphics g) { setBackground(Color.white); g.drawImage(im, MouseX, MouseY, this); }ここで画像を表示する。setBackground(Color.white)は、背景すなわちグレーの部分をWhiteにする。g.drawImage(im, MouseX, MouseY, this)により、MouseX, MouseYの位置に、小鳥を表示する。
MouseX, MouseYは、次のpublic boolean mouseDown(Event evt, int x, int y) { MouseX = x+20; MouseY = 0; repaint(); cuck.play(); return true; }により、マウスが押された位置を取得する。
int x, int yにクリックした時のマウスの座標値が入る。int x とあるのは x が整数であることを宣言している。MouseX = x+20とあるが、MouseX = x とするとマウスの位置の左に小鳥が表示されてしまうので、20ドットずらしている。
ここでは、マウスを枠内でクリックする度に座標がセットされ、repaint()により、paint(Graphics g)とcuck.play()が実行される。ひとつ気がつくことがあるかもしれない。MouseY が 0 以外の値を持っていない。実は、MouseY は、ここでは不要であった。
int MouseX = 50;でよく、こうした場合、g.drawImage(im, MouseX, 0, this);とし、MouseY = 0;は削除しておくこと。
削除の代わりに// MouseY = 0;でもよい。
実は、開発途中のソースは保存していなかったので、HISTORYに従ってソースを再現する。第3回Java applet実験では小鳥の数を増やす。Lineを引く。第4回Java applet実験では小鳥の向きを変える。背景のImageを置く。とある。
Lineを引くというのは、小鳥が跳ねる緑のグランド部分をLine関係の関数で描いたということで、public void paint(Graphics g) { setBackground(Color.white); g.drawImage(im, MouseX, MouseY, this); }に、以下の2行を挿入してg.setColor(Color.green); // 次に描くグラフィックを緑に g.fillRect(0,20,400,10); // int x int y int width,int height public void paint(Graphics g) { setBackground(Color.white); // 背景を白に g.setColor(Color.green); // 次に描くグラフィックを緑に g.fillRect(0,20,400,10); // int x int y int width,int height g.drawImage(im, MouseX, MouseY, this); // 小鳥を描く }とする。fillRectを、次のようdrawRectに置き換えると、中抜きの四角形になり、drawLineに置き換えると、対角線になる。
( x1 y1 は始点、x2 y2 は終点 )g.drawRect(0,20,400,10); // int x1 int y1 int width,int height g.drawLine(0,20,400,10); // int x1 int y1 int x2 int y2第4回では、これを次のように、imageに置き換えた。背景のimageデータは予めサイズ400ドット*10ドットで java/images/bird_BG.gif として作成しておく必要がある。
背景の上の部分(0,0,400,20)は、背景色の白をそのまま表示する。AudioClip cuck; Image im; Image img_BG; // 背景の変数の宣言 int MouseX = 50, MouseY = 0; public void init() { im = getImage(getDocumentBase(), "java/images/Bird.gif"); img_BG = getImage(getDocumentBase(), "java/images/bird_BG.gif"); // 背景の変数にimageファイルを代入する cuck = getAudioClip(getDocumentBase(), "java/sounds/bird.au"); } public void paint(Graphics g) { g.drawImage(img_BG, 0, 20, this); // 背景を描く g.drawImage(im, MouseX, MouseY, this); }小鳥の数を増やすというのは、同じ小鳥のimageを左端にも配置するということでpublic void paint(Graphics g) { g.drawImage(img_BG, 0, 20, this); // 背景を描く g.drawImage(im, 0, 0, this); // 左端の小鳥( x=0 y=0 に固定) g.drawImage(im, MouseX, MouseY, this); // 移動する小鳥 }とするだけでよい。
今回はアニメする小鳥に変身する。アニメするために3つの右向きの変化する小鳥の画像(カット)を用意する。左向きもあるので、ペインとソフトでそれぞれ反転させてさらに3つ、合わせて6つの画像(カット)を用意する。
画像は多ければ多いほどスムーズにアニメするが、作成が面倒である。というより、通信時間も考慮する必要がある。あまり多くすると画像を表示するまで、我慢できない待ち時間となる。
画像のファイル名は、右向きを bird_00.gif , bird_01.gif , bird_02.gif 左向きを bird_10.gif , bird_11.gif , bird_12.gif とする。ポイントは各ファイルを数字で識別できるようにすること。
初めの 0 ,1 が右および左向き、次の 0 , 1 , 2 が各変化するカットを表す。変数は2次元配列を使う。2次元配列は「Javaプログラミング講座」には、例題も解説もない。C言語の入門書でも通常は配列までで2次元配列の解説は実習書からということになるので、ちょっと難しいかもしれないが、ここではこのように使うという点にとどめ詳しい解説はここでも省略します。
とにかく、変数の宣言は
(以前利用したC言語の解説書は、入門C言語、実習C言語、応用C言語:三田典玄著、アスキー出版局)Image img[][] = new Image[2][3];となり、決まり文句とする。ただし、img は適当に付けた変数の名前で、[2]には 0 ,1 が、[3]には 0 , 1 , 2 がはいる。
img[0][0] , img[0][1] , img[0][2] , img[1][0] , img[1][1] , img[1][2]という6つの変数となる。
imageの代入はpublic void paint(Graphics g) { for(i = 0; i < 2; i++){ // 右向き(0)と左向き(1) for(j = 0; j < 3; j++){ // 右左それぞれ3つのカット img[i][j] = getImage(getDocumentBase(), "java/images/bird_"+i+j+".gif"); } }となるが、ここには変数 i , j があるので、予め int i,j で宣言しておく。int で整数を宣言。
for というのは、ベーシックでも有名。i++ は、i に 1を加えるという意味。"java/images/bird_"+i+j+".gif"は、Javaでは i や j が数字であっても、文字列に変数を + で結ぶと文字列になるという規則があり、java/images/bird_00.gif などに置き換えられる。
従ってimg[0][0] = getImage(getDocumentBase(), "java/images/bird_00.gif"); img[0][1] = getImage(getDocumentBase(), "java/images/bird_01.gif"); img[0][2] = getImage(getDocumentBase(), "java/images/bird_02.gif"); img[1][0] = getImage(getDocumentBase(), "java/images/bird_10.gif"); img[1][1] = getImage(getDocumentBase(), "java/images/bird_11.gif"); img[1][2] = getImage(getDocumentBase(), "java/images/bird_12.gif");と i , j という変数を使わず直接数字を書込んでもimageの代入結果は同じになる。
描画ルーチンはどうなるかというとpublic void paint(Graphics g) { setBackground(Color.white); g.drawImage(img_BG, 0, 20, this); g.drawImage(img[0][sr], 0, 0, this); //左端に右向きの小鳥 g.drawImage(img[rl][ss], MouseX, 0, this); // 移動する小鳥 g.drawImage(img[1][sl], 370, 0, this); //右端に左向きの小鳥 }rl,sr,ss,sl は整数で、次の mouseDown で指定する。public boolean mouseDown(Event evt, int x, int y) { if( MouseX > x-15 ){ // マウス位置が小鳥よりも右か左かを判定している。 // -15は幅30ドットの画像の中央から左端に補正するため // 次はマウスが小鳥より左なら左を向くように rl に 1 を代入、 // そうでなければ右を向くように 0 を代入 rl = 1; }else { rl = 0; } // 次は小鳥のカットを順次変更するための仕組み、 // SS++ によって順次 1 づつ増えていく。 sl = sr; sr = ss; ss++; if( ss > 3 ){ ss = 0; } // 小鳥がスクリーンをはみ出さないための仕組み if( x<15 ) { MouseX = 0; } else if( x > 385 ){ MouseX = 370; } else { MouseX = MouseX+(x-15-MouseX)/4; } repaint(); snd.play(); return true; }
これで一応アニメするようになったが、ハードディスク内のローカルな環境では問題ないものの通信環境では画像の読込が遅いので、初めのマウスクリックで一旦小鳥が消えるという現象が起こってしまう。
その説明の前に、左右の小鳥もその場でアニメするだけでなく、移動を試みる。public void paint(Graphics g) { setBackground(Color.white); g.drawImage(img_BG, 0, 20, this); g.drawImage(img[0][sr], 0, 0, this); //左端に右向きの小鳥 g.drawImage(img[rl][ss], MouseX, 0, this); // 移動する小鳥 g.drawImage(img[1][sl], 370, 0, this); //右端に左向きの小鳥 }であったが、public void paint(Graphics g) { setBackground(Color.white); g.drawImage(img_BG, 0, 20, this); g.drawImage(img[0][sr], 0+MouseX/20, 0, this); //置換個所1 g.drawImage(img[rl][ss], MouseX, 0, this); g.drawImage(img[1][sl], 370-MouseX/20, 0, this);//置換個所2 }まあどうということはなく、中央の小鳥よりも20分の1だけ移動するようになっている。いよいよ、通信環境での遅い画像の読込に対処するために、MediaTracker というのを使う。これは、画像を全て読込むまで、画面表示を待つというもの。
この部分のソースは
MediaTracker を使わないと、最初の小鳥の画像は表示されるが、次の画像は、次のクリックがあった後にサーバーから画像を読込もうとするので、クリックしても、一瞬小鳥が消えたようになってしまう。一瞬か長い時間かは、通信速度にもよる。public class Bird extends Applet { AudioClip snd; Image img_BG; Image img[][] = new Image[2][3]; int i, j, k, MouseX = 100,rl = 0, ss = 0, sr = 1, sl = 2; MediaTracker mt; // mt という変数の宣言 public void init() { mt = new MediaTracker(this); // MediaTrackerオブジェクト mt の作成 img_BG = getImage(getDocumentBase(), "java/images/bird_BG.gif"); mt.addImage(img_BG, 0); for(i = 0; i < 2; i++){ for(j = 0; j < 3; j++){ img[i][j] = getImage(getDocumentBase(), "java/images/bird_"+i+j+".gif"); mt.addImage(img[i][j], 0); } } snd = getAudioClip(getDocumentBase(), "java/sounds/bird.au"); } ...................(途中省略).......................... public void paint(Graphics g) { if( ! mt.checkID(0)){ g.drawString("Wait ...", 10,20); try{ mt.waitForID(0); }catch(InterruptedException e){} g.setColor(Color.white); g.fillRect(0,0,200,20); } setBackground(Color.white); g.drawImage(img_BG, 0, 20, this); g.drawImage(img[0][sr], 0+MouseX/20, 0, this); g.drawImage(img[rl][ss], MouseX, 0, this); g.drawImage(img[1][sl], 370-MouseX/20, 0, this); }
public void init() { mt = new MediaTracker(this); // MediaTrackerオブジェクト mt の作成までは、決まり文句と思って下さい。
mt.addImage(img_BG, 0); と mt.addImage(img[i][j], 0); で、読込みを監視するイメージデータを指定する。最後の 0 は、整数で指定される ID で、ここでは ID に 0 を指定して画像をグループ化する。1 を指定すれば別のグループとして監視できる。if( ! mt.checkID(0)){ // (1) g.drawString("Wait ...", 10,20);// (2) try{ // (3) mt.waitForID(0); // (4) }catch(InterruptedException e){}// (5) g.setColor(Color.white); // (6) g.fillRect(0,0,200,20); // (7) }(1)の ! は次に続く条件式を否定する。mt.checkID(0)は ID が 0 のグループが読込まれていれば、false を返す。! が付くことで falseでない=true(真)となる。すなわち、画像が読込まれていない時に、次の行を実行する。
(2)は読込みおわるまで、Wait ...を表示する。
(3)〜(5)が、読込終了まで待機状態になるための指定で、決まり文句と思って下さい。ただし、mt.waitForID(0)で ID を 0 にする。
(6),(7)は、Wait ...を消すためにあるだけ。これで、画像アニメはスムーズになった。しかし、初めに画面が表示されるまでしばらく待たされることになった。
IE3.0では、なぜか、ページが再表示される度に、しばらく Wait ... が表示されるようになった。NN2.02 でも事情は同じだが、NN3.01ではページの再表示でも即座に画像表示に移る。
このあたりの理由はよく分からないのだが。
ここで、一気に最終ソースを掲載する。
注意点は、小鳥の画像は3個であるが、画像を表示する順序を変化させるために、image[][]の変数は6個用意する。
この6個をセットしているのは、(注2)の部分でswitch( j ){ //(注2)j の値により k を 0〜2 の範囲にする。 case 1: k = 1; break; case 4: k = 2; break; default: k = 0; }小鳥のファイル名の後半の数字になる。bird_ik の k の部分。
switch( j ){
case 1: k = 1; ・・・というのは、j の値が 1 の時、k を 1 にする。ということで、if文に置き換えることができるが、この場合は、switch文の方が表現がすっきりする。
default: k = 0; ・・・は、それ以外は k は 0 にする。となる。
ただし、switch文が使えるのは、j が個々の値を持つ時だけで、j > 0 といった範囲を指定することは出来ない。// Bird.java import java.applet.*; import java.awt.*; public class Bird extends Applet { AudioClip snd; Image img_BG; Image img[][] = new Image[2][6]; int i, j, k, MouseX = 100,rl = 0, ss = 0, sr = 1, sl = 2; MediaTracker mt; // ここで、イメージとサウンドの変数をセットする。 public void init() { mt = new MediaTracker(this); setBackground(Color.white); img_BG = getImage(getDocumentBase(), "java/images/bird_BG.gif"); mt.addImage(img_BG, 0); for(i = 0; i < 2; i++){ for(j = 0; j < 6; j++){ switch( j ){ //(注2)j の値により k を 0〜2 の範囲にする。 case 1: k = 1; break; case 4: k = 2; break; default: k = 0; } img[i][j] = getImage(getDocumentBase(), "java/images/bird_"+i+k+".gif"); mt.addImage(img[i][j], 0); } } snd = getAudioClip(getDocumentBase(), "java/sounds/bird.au"); } public void start() { snd.play(); } public void paint(Graphics g) { if( ! mt.checkID(0)){ g.drawString("Wait ...", 10,20); try{ mt.waitForID(0); }catch(InterruptedException e){} g.setColor(Color.white); g.fillRect(0,0,200,20); } setBackground(Color.white); g.drawImage(img_BG, 0, 20, this); g.drawImage(img[0][sr], 0+MouseX/20, 0, this); g.drawImage(img[rl][ss], MouseX, 0, this); g.drawImage(img[1][sl], 370-MouseX/20, 0, this); } public boolean mouseMove(Event evt, int x, int y) { if( MouseX > x-15 ){ rl = 1; }else { rl = 0; } sl = sr; sr = ss; ss++; if( ss > 5 ){ // ss は 0〜5 までなので、5 を超えたら 0 にする。 ss = 0; } if( x < 15 ) { MouseX = 0; } else if( x > 385 ){ MouseX = 370; } else { MouseX = MouseX+(x-15-MouseX)/4; } repaint(); snd.play(); return true; } }このソースをそのまま javac でコンパイルすれば、実行できる applet が生成されるはずである。
これを実行させるための htmlファイルには、<applet code="Bird.class" codebase="./java/" width=400 height=30></applet>
を置けばよいが、codebase="./java/" により、Java Applet の置くディレクトリを指定する。これは、htmlファイルのあるディレクトリの下の java というディレクトリに Java Applet を置くということを示す。
一般の解説書には、この例題がないので、これが分かるのに苦労した部分である。
小鳥の画像データは java/images に、小鳥のサウンドデータは java/sounds に置くようになっているが、これは、ソースファイルの方で指定する。
ここまで読んでいただいた方には、改めて感謝いたします。