import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;
import java.util.*;
//弾幕避けゲーム(キャンバス)
class DanmakuCanvas extends GameCanvas
implements Runnable {
//シーン定数
private final static int
S_TITLE =0,//タイトル
S_PLAY =1,//プレイ
S_GAMEOVER=2;//ゲームオーバー
//システム
private int init=S_TITLE; //初期化
private int scene; //シーン
private int keyEvent; //キーイベント
private int keyState; //キー状態
private Graphics g; //グラフィックス
private Image[] image=new Image[4];//イメージ
private Random rand =new Random();//乱数
//ゲーム
private int score;//スコア
//自機
private int myX;//X座標
private int myY;//Y座標
//弾幕
private static int[] balX=new int[64];//X座標
private static int[] balY=new int[64];//Y座標
//コンストラクタ
DanmakuCanvas() {
//キーイベントの抑制
super(false);
}
//実行
public void run() {
int i;
long sleepTime=0L;
//グラフィックスの取得
g=getGraphics();
//画像ファイルの読み込み
Image[] image=new Image[2];
try {
for (i=0;i<2;i++) {
image[i]=Image.createImage("/"+i+".png");
}
} catch (Exception e) {
System.out.println(e.toString());
}
while (true) {
//シーンの初期化
if (init>=0) {
//タイトルの初期化
if (init==S_TITLE) {
score=0;
myX=120;
myY=220;
for (i=0;i<balY.length;i++) {
balX[i]=rand(240);
balY[i]=rand(240);
if (balY[i]>180) balY[i]=-999;
}
}
//共通の初期化
scene =init;
init =-1;
keyEvent=-999;
}
//タイトルの処理
if (scene==S_TITLE) {
//キーイベントの処理
if (keyEvent==FIRE) init=S_PLAY;
}
//プレイの処理
else if (scene==S_PLAY) {
//スコア加算
score+=10;
//キー状態の処理(自機の移動)
keyState=getKeyStates();
if ((UP_PRESSED &keyState)!=0) myY-=5;//上キー
if ((DOWN_PRESSED &keyState)!=0) myY+=5;//下キー
if ((LEFT_PRESSED &keyState)!=0) myX-=5;//左キー
if ((RIGHT_PRESSED&keyState)!=0) myX+=5;//右キー
if (myX< 10) myX=10;
if (myX>230) myX=230;
if (myY< 10) myY=10;
if (myY>230) myY=230;
//弾幕の処理
for (i=0;i<balY.length;i++) {
//発射中
if (balY[i]!=-999) {
balY[i]+=5; //移動
if (balY[i]>=300) balY[i]=-999;//非表示へ
//衝突判定
if (calcLen(myX,myY,balX[i],balY[i])<12*12) {
init=S_GAMEOVER;
}
}
//非表示(10/100の確立で発射)
else if (rand(100)<10) {
balX[i]=rand(240);
balY[i]=-24;
}
}
}
//ゲームオーバーの処理
else if (scene==S_GAMEOVER) {
//キーイベントの処理
if (keyEvent==FIRE) init=S_TITLE;
}
keyEvent=-999;
//描画の処理
g.setColor(25,25,50);
g.fillRect(0,0,getWidth(),getHeight());
g.drawImage(image[0],myX-12,myY-6,g.LEFT|g.TOP);
for (i=0;i<balX.length;i++) {
if (balY[i]!=-999) {
g.drawImage(image[1],balX[i]-6,balY[i]-6, g.LEFT|g.TOP);
}
}
if (scene==S_TITLE) drawBold("弾幕避けゲーム");
if (scene==S_GAMEOVER) drawBold("ゲームオーバー");
g.setColor(255,255,255);
g.drawString("スコア "+score,5,5,g.LEFT|g.TOP);
flushGraphics();
//スリープ
while (System.currentTimeMillis()<sleepTime+100 &&
System.currentTimeMillis()-sleepTime<100);
sleepTime=System.currentTimeMillis();
}
}
//キープレスイベント
public void keyPressed(int keyCode) {
if (keyCode==0) return;
if (getGameAction(keyCode)==FIRE) keyEvent=FIRE;
}
//太字の描画
private void drawBold(String str) {
int x=getWidth()/2;
int y=getHeight()/3;
g.setColor(120,120,120);
g.drawString(str,x-1,y-1,g.HCENTER|g.BASELINE);
g.drawString(str,x ,y-1,g.HCENTER|g.BASELINE);
g.drawString(str,x+1,y-1,g.HCENTER|g.BASELINE);
g.drawString(str,x-1,y ,g.HCENTER|g.BASELINE);
g.drawString(str,x+1,y ,g.HCENTER|g.BASELINE);
g.drawString(str,x-1,y+1,g.HCENTER|g.BASELINE);
g.drawString(str,x ,y+1,g.HCENTER|g.BASELINE);
g.drawString(str,x+1,y+1,g.HCENTER|g.BASELINE);
g.setColor(255,255,255);
g.drawString(str,x,y,g.HCENTER|g.BASELINE);
}
//乱数の計算
private int rand(int num) {
return (rand.nextInt()>>>1)%num;
}
//距離の2乗の計算
private int calcLen(int x0,int y0,int x1,int y1) {
return (x0-x1)*(x0-x1)+(y0-y1)*(y0-y1);
}
}
|