出てくる「モグラ」をクリックして得点を稼ぐゲームを作ります。このプログラムを作るにあたって、 http://bitarts.jp/tech/java/mogura/に掲載されているソースを参考にさせていただきました。
「もぐら叩き」ゲームは画像や効果音など視覚、聴覚にかかわる要素が大きな役割を持ちます。したがって、画像を変更すれば、クリックするものをモグラではなく箱から出てきた宝石や爆弾にしたりもっと独特な生き物にしたりすることも可能です。
今回は開いた宝箱の中に入ってきた宝石をクリックすると加点し、爆弾をクリックすると減点するゲームをつくりますから、途中のアニメーションとあわせて3×3=9種類の画像を用意します。(下図参照、48×48px)
以下のファイルを読み込みます。getImage()とgetAudioClip()を使います。画像の読み込みにはMediaTrackerもセットします(簡単のため、0番のファイルのみチェックします)。
gra = getGraphics(); //画像の用意 imgbox0 = getImage(getDocumentBase(), "box0.gif");//閉まっている箱 mt.addImage(imgbox0, 0); imgbox1 = getImage(getDocumentBase(), "box1.gif");//開きかけの箱1 mt.addImage(imgbox1, 0); imgbox2 = getImage(getDocumentBase(), "box2.gif");//開きかけの箱2 mt.addImage(imgbox2, 0); ...... //効果音の用意 atari = getAudioClip(getCodeBase(),"Pikari.au");//当たりの音 // atari = getAudioClip(getCodeBase(),"tone1.au"); hazure = getAudioClip(getCodeBase(),"Dokan.au");//はずれの音 batan = getAudioClip(getCodeBase(),"Batan.au");//現在未使用
画面右に残り時間、最高得点、現在の得点を表示する文字盤を用意します。ここでは、文字のサイズ、表示位置を指定して描画しています。文字枠は背景を黒とし、文字を白で表示します。また、setFont()で文字のフォントとサイズを指定します。
//文字枠を用意する g.setColor(Color.black);//背景色 g.fillRect(Width,0,300,Height); g.setColor(Color.white); //文字色 g.setFont(new Font("TimesRoman", Font.PLAIN, 20));//時間のフォント指定 g.drawString("Time : ", Width + 10, 30); g.setFont(new Font("TimesRoman", Font.PLAIN, 14));//得点のフォント g.drawString("HiScore : ", Width + 15, 60); g.drawString("Score : ", Width + 15, 80); ..... //ボタンの案内 if (run_mode == 0) { g.setColor(Color.yellow); g.setFont(new Font("MS ゴシック", Font.PLAIN, 11)); g.drawString("- ボタンを 押してください -", Width + 10, 100); }
これらの表示は、ゲームが進行すると順次書き換えられていきます。なお、ここでの Width、Heightはゲーム画面(宝箱が表示される領域)の幅と同じ数値になるよう設定されています。
画面上には3×3=9個の箱があります。この箱の状態記憶に matrix[] を使います。この値が負のときは、閉まっている状態です。各箱がまずそれぞれに乱数
Math.random() によって発生した乱数によって開く/開かないを決定します。
さらに開くことになった箱はその表示時間を乱数によって決定します。この乱数設定によって当たりと外れの比率、宝箱が開く頻度が変化します。箱の中身(宝石/爆弾)は
state[] で記録します。箱の中身が1種類の場合は2つ目の if ステートメントは不要です。
int pos = (int)(Math.random() * 1000 % (matsplash * matsplash)); if (matrix[pos] <= 0 && (int)(Math.random() * 100) > Boxes) { //Score:得点で寿命の値を変更する matrix[pos] =1 + (int)(Math.random() * 1000 % SpeedLen + SpeedMin);//寿命設定 state[pos] = 0; if( 31 <= (int)( Math.random() * 100) && (int)( Math.random() * 100) <= 40) { state[pos] = 1; }//爆弾の箱にする // System.out.println(String.valueOf(matrix[pos])); gra.drawImage(imgbox1, matsize_x*(pos%matsplash), matsize_x*(pos/matsplash), this); continue; }
開いた箱はmatrix[pos]の値が1以上になります。この値が箱の中身が表示される時間となり、開いている内は少しずつ減っていきます。値が0になると箱は閉じて、また開く/開かないの判定を始めます。これを制限時間の間くり返します。
for (int i=0,ly=0; ly < matsplash; ly++) { for (int lx=0; lx < matsplash; lx++, i++) { if (matrix[i] > 0) { matrix[i]--; if (matrix[i] > 1) { if (matrix[i] % 8 == 0){ drawbox = imgboxA1;//中身画像1 if (matrix[i] % 8 == 0 && state[i] == 1) drawbox = imgboxB1;} else { drawbox = imgboxA2;//中身画像2 if(state[i] ==1) {drawbox = imgboxB2;} } } else { if (matrix[i] == 0) drawbox = imgbox0; else drawbox = imgbox1; drawbox = imgbox2; } } else if (matrix[i] == -1) { drawbox = imgboxA3;//クリック画像宝石 if (state[i] == 1){ drawbox = imgboxB3;}//クリック画像爆弾 matrix[i] = 0; } else { drawbox = imgbox0; } gra.drawImage(drawbox, matsize_x*lx, matsize_x*ly, this); } } } } }
マウスクリックがあった場所の値が0以上であれば(開いていれば)、点数処理を行います。単純に1点ずつ増えていくものであれば、3つ目の if は要らず「Score++;」の1文で済みます。今回は(爆弾の場合)減点するので2択になります。減点が重なってもマイナス点を発生させたくなければ、0点以下になったときの処理が必要です。
最後に算出された点数を文字盤に表示します。gra.setColor 以下の記述です。背景と同じ色の四角形で塗りつぶしてから新しい点数を表示させないと、文字が見えなくなります。
public boolean this_mousePressed(MouseEvent e) { //マウス押し下げ処理 int x = (e.getPoint()).x; int y = (e.getPoint()).y; //System.out.println("pressed:"+x+":"+y); if (run_mode == 1 && x <= Width) { int mx = x / matsize_x; int my = y / matsize_y; //System.out.println("pressed:"+mx+":"+my); if (matrix[mx+my*matsplash] > 0){//得点処理 int i = mx+my*matsplash; matrix[mx+my*matsplash] = -1; if(state[i] == 0){ Score = Score + 1;//加点 atari.play();}//効果音 else { Score = Score - 2;//減点 hazure.play();//効果音 } //得点表示 gra.setColor(Color.black); gra.fillRect(Width+60, 65, 150, 30); gra.setFont(new Font("Helvetica", Font.PLAIN, 18)); gra.setColor(Color.white); gra.drawString(String.valueOf(Score), Width + 75, 80); if (Score >40) {Boxes = 95;} } } return true; }ソースはこちらを参照してください。画像、音ファイルはこちらです(ダブルクリックで解凍します)。
こんな感じです。画面が小さいので難易度はかなり低いです。環境によっては音も出ます。爆弾を1つくらい取ってしまっても、宝石を集めていけば40点くらいはいきます。