ラベル Android ゲーム シューティング の投稿を表示しています。 すべての投稿を表示
ラベル Android ゲーム シューティング の投稿を表示しています。 すべての投稿を表示

2011年5月14日土曜日

Androidでゲーム シューティングゲームっぽい物。      その5:敵の攻撃設定

敵の攻撃を設定する。
敵は、1体のみの設定で、画面右端から移動してきて、座標値X=300付近で
敵の移動を停止し、弾を発射する。

専用のクラスファイルを作り、その中で設定したこと。
変数の設定
座標値x,y
移動値move_x,move_y;
画像サイズsize
画像イメージの変数img
保管場所の設定
(定数)
private static final PointF point=new PointF(画面に描画されない場所);

コンストラクタの中身
画像の読み込み
保管場所から敵弾を呼び出してセットする。

移動設定メソッド
ここでは、弾を移動させるだけの設定と、画面左端に弾が到達したら
保管場所に移動するメソッドの呼び出しを行う。

描画メソッド
画像の描画のみ

その他
SurfaceViewを設定しているクラスファイルで呼び出すために作ったメソッドと、
同じクラスファイルの中で使用するメソッドの設定

敵の弾の位置を返す
public PointF getPos() {
return new PointF((int)x,(int y));
}

敵の弾の位置をセットする
public void setPos(float x,float y) {
this.x=x;
this.y=y;
}

敵の弾を保管場所に移動させるメソッド
保管場所にあるかどうかのチェックをするメソッド

次にSurfaceViewを設定しているクラスファイルでの設定。
設定する事は、複数処理を施すこと、連射機能をつける事。
この2つに絞って作って見る。

①複数処理について
変数の設定
複数処理は、配列の要素に複数処理用の変数を入れるので、その為の定数を作る。
private static final int NUM_ATTACKS2=5;

敵の弾を作ったクラスファイルの呼び出し
ファイルの名前は、E2_Shot.java
private E2_Shot[] attack2;

コンストラクタでは、配列の初期化を行う
attack2=new E2_Shot[NUM_ATTACKS2];
for(int i=0;i<NUM_ATTACKS2;i++)
attack2[i]=new E2_Shot(this);

描画メソッドの呼び出し
for(int i=0;i<NUM_ATTACKS2;i++)
attack2[i].draw(canvas);

敵弾の移動専用のメソッドを作成して、その中で移動メソッドを呼び出した
public void attack_Move() {
for(int i=0;i<NUM_ATTACKS2;i++)
attack2[i].move();
}

②連射機能について
連射機能は、時間を取得し、最初に発射した弾と次に発射した弾の時間を比較し、
比較した結果で次の弾を発射できるようにする設定を行う。
変数の設定
//次の発射までの時間
private static int attack2_interval=500;
//最後に発射した時間
private long attack2_lastTime;

③敵の弾の発射制御メソッドの作成
このメソッドの中身では、敵の弾が保管場所にある場合、弾をセットして1発発射したら
抜けるという仕組みのメソッド。

こんな感じ
public void tryToAttack() {
// 前との発射間隔がshot_interval以下だったら発射できない
//発射できるかどうかチェックする
//発射できない場合・・・return
if(System.currentTimeMillis()-shot_lastTime<shot_interval)
return;

//最後に発射された時間を取得する
//shot_lastTimeに入れる
shot_lastTime=System.currentTimeMillis();

for(int j=0;j<NUM_ATTACK2;j++) {
if(attack2[j].isInStorage()) {
//弾が保管庫にあれば発射できる
//弾の座標を敵の座標にセットすれば発射される
if(enemy2.flg2==true) {
//敵の位置の取得
PointF enemy2_Pos=enemy2.getPos();
//取得した敵の位置を弾の位置にセットする
attack2[j].setPos(enemy2_Pos.x+16, enemy2_Pos.y+16);
//一発発射した抜ける
break;
}
}
}
}

④runメソッドで呼び出す
①で作った、attack_Move()メソッドと、③で作ったtryToAttack()メソッドをrun()メソッドで呼び出す。

その他、シューティングゲーム関連



2011年5月10日火曜日

Androidでゲーム シューティングゲームっぽい物。      その4:弾と敵が衝突したら、爆発エフェクトを動作させる

爆発エフェクトを付けてみる。

androidのアニメーション処理に関するAPIとかを使わないで、配列とカウント変数、
それからフラグ変数を使用しての作成。

参考になるのが、サンプルコードのJetBoy。
でも、JetBoyのサンプルコードよりはシンプルに考えて見たいと思って作った。

問題は画像で、JetBoyを見ると、動作ごとに画像が1枚ずつ存在していて、1枚の画像に複数の
画像を個別に読み出す仕組みにはなっていない。
どちらかと言うと、そっちの方が楽。でも、Androidでそれが出来るのかどうかわからない。

なので、画像は各動作ごとに1枚ずつ用意した。
全部で16枚。
爆発エフェクトを作成するフリーのソフト発色弾を使用し、そこから出力された物を
ペイントソフトで全て手作業で分割。
※ペイントソフトは、背景の透過処理がきちんと行えるものであれば何でもOK。
因みに使ったソフトはGIMP2です。
なにか、いい方法があればなって考えてみたけれども、思いつきません。

最初に、エフェクト用のクラスファイルを作る。
配列を作り、その配列をカウント変数で呼び出す仕組み。
フラグ変数は、敵画像に弾画像が当たったらtrueにするフラグ変数で、これは、カウント変数を
動かす為の変数、もう1つは、
画像の枚数文呼び出したら、countの値を0(この場合、配列のインデックス番号を0番)
にするフラグ変数で、このフラグはリセットを行う。

属性で必要な物は
画像を読み込む為の変数、
複数処理用に変数を定数で設定、
こんな感じ
//爆発イメージ枚数
private static final int NUM_IMAGES=16;

爆発する位置を決める為の座標値、
画像のサイズの変数、
画像を出力する為に必要な枚数を数えるカウント変数、
カウント変数を動かす為のフラグ変数、
リセットを行う為のフラグ変数。

コンストラクタでは、
配列の初期設定を行い、配列に画像ファイルを読み込む設定、
こんな感じ
/**
 * コンストラクタ
 */
public Explosion(MainPanel panel) {

/*イメージ関連の読み込み*/
//イメージファイルの数分だけ配列に入れる
img=new Bitmap[NUM_IMAGES];

Resources r=panel.getResources();

/*読み込む画像*/
img[0]=BitmapFactory.decodeResource(r,R.drawable.e1_0);
img[1]=BitmapFactory.decodeResource(r,R.drawable.e2_0);
img[2]=BitmapFactory.decodeResource(r,R.drawable.e3_0);
img[3]=BitmapFactory.decodeResource(r,R.drawable.e4_0);
img[4]=BitmapFactory.decodeResource(r,R.drawable.e5_0);
img[5]=BitmapFactory.decodeResource(r,R.drawable.e6_0);
img[6]=BitmapFactory.decodeResource(r,R.drawable.e7_0);
img[7]=BitmapFactory.decodeResource(r,R.drawable.e8_0);
img[8]=BitmapFactory.decodeResource(r,R.drawable.e9_0);
img[9]=BitmapFactory.decodeResource(r,R.drawable.e10_0);
img[10]=BitmapFactory.decodeResource(r,R.drawable.e11_0);
img[11]=BitmapFactory.decodeResource(r,R.drawable.e12_0);
img[12]=BitmapFactory.decodeResource(r,R.drawable.e13_0);
img[13]=BitmapFactory.decodeResource(r,R.drawable.e14_0);
img[14]=BitmapFactory.decodeResource(r,R.drawable.e15_0);
img[15]=BitmapFactory.decodeResource(r,R.drawable.e16_0);

画像サイズの指定、
フラグ変数の初期状態の設定、
一応、カウント値の初期状態の設定。

描画メソッドでは、
カウント変数を動かす為のフラグ変数がtrueの場合に、
画像を呼び出す設定をする。
こんな感じ
/**
* 描画
*/
public void draw(Canvas canvas) {
/*画像の出力*/
//カウント変数を動かす為のフラグ変数がtrueの場合
//カウントしたぶんだけ出力する
if(flg1==true) 
canvas.drawBitmap(img[count], x,y,null);
}

弾画像が敵画像に当たって爆発エフェクトが表示される場所の設定を行うメソッドを作る
ここで、設定する事は、敵画像の中心に爆発画像が来るように設定する。
こんな感じ
/**
* 爆発場所の設定
* 敵の中央になるように設定する
*/
public void play(float x,float y) {
/*爆発する場所を中央になるように設定*/
//x
this.x=x-size/2;
//y
this.y=y-size/2;
//カウント変数を動かす為のフラグ変数をtrueにする
flg1=true;
}

カウントを回すメソッドの作成。
ここで設定する事は、
カウント変数を動かす為のフラグ変数がtrueの場合に、カウント変数をインクリメントし、
そして、カウント変数と複数処理用に変数を定数で設定した枚数(今回読み込む画像枚数は16枚)と、
カウント変数の値が同じになったら、カウント変数を動かす為のフラグ変数をfalseにして、
リセットを行う為のフラグ変数をtrueにする。
こんな感じ
/**
* カウントをするメソッド
*/
public void count_Up() {
//カウント変数を動かす為のフラグ変数がtrueの時
if(flg1==true) {
//countをインクリメント
count++;
}

//カウント変数の値と枚数が一致した場合
if(count==NUM_IMAGES) {
//カウント変数を動かす為のフラグ変数をfalse
//カウント変数を動かす為のフラグ変数をfalseにして、countのインクリメントを止める
flg1=false;
//flg2をtrue
//flg2をtrueにして、リセットの準備態勢に入る
flg2=true;
}
}

カウントをリセットする為のメソッドの作成。
この中で設定する事は、
リセットを行う為のフラグ変数をtrueの場合、カウント変数の値を0にして、
各フラグ変数を初期状態のfalseにする。
/**
* カウントをリセットする
*/
public void reset_Count() {
//リセットを行う為のフラグ変数がtrueの時に
if(flg2==true) {
//countに0を代入
//カウント開始時の状態に戻る
count=0;
//フラグを初期状態にする
flg1=false;
flg2=false;
}
}

そして、これらを弾と敵が衝突した時に動作をするように設定をする。
弾と敵の交差を検出した時のメソッド内に、
敵の位置を取得する設定と、弾画像が敵画像に当たって爆発エフェクトが表示される場所の
設定を行うメソッドを呼び出す。
こんな感じ
//敵の位置取得
PointF enemy1_Pos=enemy1.getPos();
//爆発アニメーション
explosion.play(enemy1_Pos.x+16, enemy1_Pos.y+16);

その他、シューティングゲーム関連


2011年5月9日月曜日

Androidでゲーム シューティングゲームっぽい物。      その3:弾と敵の衝突判定

発射された弾が敵にぶつかった時の処理について
前回、前々回とタッチしたときにdrawCircle()メソッドを使って描画した円を
使っていたが、今回から弾画像を用意して、その画像を使って
処理することにした。

弾の画像はこれ


弾画像と敵画像がぶつかった時の処理は
①画面の端に来た場合、弾画像を消す処理
②敵とぶつかった時、弾画像を消す処理
③弾画像とぶつかった時、敵画像を消す処理
④弾画像とぶつかった時、敵画像をもう一度画面右端に戻す処理
の4つを行った。

①について
弾画像を消すにはフラグを使って消すと考えることになるが、それだと、
目に見える部分が消えているが実際は、弾画像と敵画像がぶつかった
ポイントに弾画像の座標値が残ってしまい、次に出てくる敵画像がその座標値に
来た時、弾画像が無いのに敵画像が消えるという不思議なことが起きてしまうので、
これも考慮した考えで行う。
タッチしたときに弾画像を、弾が発射されるスタート位置にセットする。
弾画像を設定しているクラスファイルのコンストラクタにて、設定しておく。
こんな感じ
属性を決める
private static final PointF point=new PointF(-100,-100);
コンストラクタでは
public Ball(MainPanel panel) {
//弾画像の読み込み
Resources r=panel.getResources();
img=BitmapFactory.decodeResource(r,R.drawble.弾画像の名前);
//タッチしたときに弾画像をセットする
x=point.x;
y=point.y;
//弾が発射されるスタート位置
x=-10;
y=-10;
//画面に弾画像があるかどうかのフラグ
//初期状態は無いのでfalse
used=false;
}
次に作るのが、弾画像が敵画像とぶつかった時と弾画像が画面の端に行ってしまった時の処理を施す
public void Store() {
x=point.x;
y=point.y;
}
もう1つが、弾画像がpoint=new PointF(-100,100);の中にあるかどうか
見るための物を作る
public boolean isInStorage() {
//あるかどうかチェックする
if(x==point.x&&y==point.y) {
//ある場合はtrueを返す
return true;
}
//無い場合はfalseを返す
return false;
}
設定したものを今度は、移動を設定しているメソッドで使用する
public void move() {
if(isInStorage())
return;
//画面の端に来た場合
if(x<0||x>panel.getWidth()||y<0||y>panel.getHeight()) {
//画面からなくなるのでfalse
used=false;
//Storeに移動させる
Store();
}
これで、画面の端に来た時の処理は終わり。
②と③について
②と③は、衝突判定処理を設定をして、それぞれの画像についての処理を行う。
弾画像と敵画像の衝突判定処理を設定する。
衝突判定処理はRectクラスを使い、intersectメソッドで設定を行う。
ブロック崩しや矩形同士の交差判定にもintersectメソッドを使用した交差判定処理を記述している。
ブロック崩しの交差判定処理
矩形同士の交差判定処理
敵画像を設定しているクラスファイルにて、衝突を検出したらtrueを返すメソッドを作成する。
こんな感じ
/**
* 自機弾との衝突検出
*/
public boolean collideWith(Ball ball) {
//敵1の矩形
Rect rect_enemy1=new Rect((int)x-size/25,
(int)y-size/25,
(int)x+size,
(int)y+size);
//自機弾の位置の取得
PointF ball_Pos=ball.getPoint();
//自機弾の矩形
Rect rect_ball=new Rect((int)ball_Pos.x-ball.getHeight()/25,
(int)ball_Pos.y-ball.getWidth()/25,
(int)ball_Pos.x+ball.getHeight(),
(int)ball_Pos.y+ball.getWidth());
//交差したらtrueを返す
return rect_enemy1.intersect(rect_ball);
}
衝突を検出する設定を作ったので、今度はSurfaceViewを設定しているクラスファイルで使用する
SurfaceViewを設定しているクラスファイルで設定する事は、弾画像と敵画像が交差したのを検出した時に
どうするか?と言う設定を行う。
設定する事は、弾画像の設定と敵画像が弾画像とぶつかった時に敵画像を画面右端に戻す設定を行う。
こんな感じ
/**
* 弾と敵の交差を検出した時の設定
*/
public void enemy_CollisionDetection() {
/*弾と敵1*/
for(int i=0;i
if(enemy1.collideWith(ball[i])) {
/*弾のフラグをfalse*/
ball[i].used=false;
/*弾画像を移動させる*/
ball[i].Store();
//④の部分
//弾に当たったら初期位置に戻すために
//敵画像のフラグをfalseにする。
enemy1.flg1=false;
//弾が1つぶつかったら抜けるようにする
break;
}
}
}
④について
④は、敵画像のフラグがfalseの時(初期状態)に画面右端に戻された、敵のクラスファイルを設定している
移動メソッドが呼ばれ、その中で、以下のような設定をしている。
if(flg1==false) {
x=533//画面の右端
y=rand.nextInt(250)
}
と、設定している。
enemy_CollisionDetection() メソッドをrun()メソッド内で呼び出したら
使用できるようになる。
その他、シューティングゲーム関連

2011年5月8日日曜日

Androidでゲーム シューティングゲームっぽい物。      その2-2:敵1体をランダムに出現させる。                  setSeed()メソッドを使う

前回のランダムの方法とは別に、今度はsetSeed()メソッドを使った方法を作ってみる。

Javaの説明では、setSeed の一般規約では、シードとして引数 seed を使って作成されたばかりの状態と同じになるように、この乱数ジェネレータオブジェクトの状態を変更します。

と、ある。
与える種(この場合、nextInt()メソッドにある引数)の範囲を出現するたびに初期化するメソッド。

このsetSeed()メソッドの引数にSystem.currentTimeMillis()を入れて、時間的に初期化を行う
用に設定した。

設定方法は簡単。
敵クラスのコンストラクタ内で、Randomクラスのインスタンスを記述した真下に記述。
こんな感じ
rand=new Random();
rand.setSeed(System.currentTimeMillis());

これだけ。


その他、シューティングゲーム関連

2011年5月7日土曜日

Androidでゲーム シューティングゲームっぽい物。      その2:敵1体をランダムに出現させる

敵の出現する位置をランダムに設定して出現させる。


















設定する場所は、敵クラス。

Randomクラスを呼び出す。

private Randam rand;

コンストラクタの中身は
インスタンスを生成
rand=new Random();

敵の出現させる場所は、座標値のXは画面右端で固定。
座標値のYに対して、ランダム計算を行う。
こんな感じ
y=rand.nextInt(250);

nextInt()メソッドの引数の中身250とは、Y軸上の何処かから出現してもらう為の範囲を入力。

移動メソッドは、画面左端に行ったら、また、元の画面右端に戻ってもらう時に、
ここでもランダム計算を行い、出現する時のY軸上の出現箇所のみをランダムに設定する。
if(x<0) {
   x=533//画面右端の座標値
   y=rand.nextInt(250);
}

nextInt()メソッドの使い方
nextIntは、0~n-1の戻り値を返す。
(nは引数)
例えば、今回のnextInt(250)の場合、0~250-1の値を返すことになるのでY軸上の出現位置は、
Y=0~Y=250-1の範囲の何処かから出現することになる。

また、範囲の開始の0では、嫌だなあって時は、
例えば、20~n-1の範囲にしたいって時は、こんな感じにすると出来る。
nextInt(250)+20;

こうすると、範囲20~250-1の何処かから、出現する事になる。

その他、シューティングゲーム関連
Androidでゲーム シューティングゲームっぽい物。 その1:敵を1体出現させる
Androidでゲーム シューティングゲームっぽい物。 その2-2:敵1体をランダムに出現させる。setSeed()メソッドを使う
Androidでゲーム シューティングゲームっぽい物。  その3:弾と敵の衝突判定
Androidでゲーム シューティングゲームっぽい物。その4:弾と敵が衝突したら、爆発エフェクトを動作させる
Androidでゲーム シューティングゲームっぽい物。 その5:敵の攻撃設定

その他、ランダム設定関連
ランダムクラスを使って色の変更を行う

Java クラス:Randomについて
android reference クラス:Random

2011年5月6日金曜日

Androidでゲーム シューティングゲームっぽい物。      その1:敵を1体出現させる

タッチした方向に描画した円を発射するを使って、シューティングゲームっぽい物を作ろうと思う。

まずは、敵を1体出現させる。弾を撃ってぶつける対象物がいないと始まらない。

敵クラスを作り、そこで設定する内容は、敵画像の座標値と移動値、それから敵のイメージ変数。

そして、出現させる敵画像はこれ。



ただの丸の画像です。

コンストラクタの設定は、今回1体のみなので、座標値と移動値を設定。
こんな感じ

public Enemy1(MainPanel panel,float x,float y,float move_x,float move_y) {
  ブロックの中身
  this.x=x;
  this.y=y;
  this.move_x=move_x;
  this.move_y=move_y;
  this.panel=panel;

  //イメージの読み込み
  Resources r=panel.getResources();
  img=BitmapFactory.decodeResource(r,R.drawble.test1);

}

移動の仕組みを作る
移動の仕組みを作っているメソッドを作る。
今回の敵は、1体だけ現れる。動きは、画面右端から直進して画面左端へ移動
左端にいったら、右端に又現れる。
弾をぶつけたりするわけではないので、唯ひたすら移動し続ける設定。
こんな感じ
public void move() {
   //移動設定
   x+=move_x;
   y+=move_y;

   //画面左端に行ったら、又右端に戻る
   if(x<0)
      x=533;
}

描画設定
描画は、canvasクラスのdrawBitmap()メソッドを呼び出す
こんな感じ
public void draw(Canvas canvas) {
   canvas.drawBitmap(img,x,y,null);
}

今回の敵クラスの設定はこれで終了。後々、弾と衝突した時の処理や何かを設定していく。

次に、この敵クラスを呼び出すクラスでの設定。

SurfaceViewを使って、今回のゲームっぽい物を作ろうと思っているので、その、SurfaceViewを
設定しているファイルを作成する。
ファイルの名前はMainPanel.java

敵クラスの変数を作成する
変数は
private Enemy1 enemy1;

コンストラクタでの設定
今回、敵クラスの呼び出しには、敵クラスを呼ぶ際には、引数の中に値を入力する必要がある。
こんな感じ
enemy1=new Enemy1(this,533,50,-3,0);
x座標値には、画面の右端の値、y座標には画面上端から50行ったところが、出現するポイントで、
-3は画面右端から画面左端に移動する、0は今回直進させるので、移動値yには0を入れている。


描画を呼び出す。
敵クラスから描画メソッドを呼び出す。
public void draw(Canvas canvas) {
   /*敵クラス*/
   enemy1.draw(canvas);
}

移動設定したメソッドを呼び出す。
こんな感じ
public void move() {
   //敵クラス
   enemy1.move();
}

そして、これらの描画メソッドと移動設定メソッドをrunメソッドにて呼び出す。

その他、シューティングゲーム関連
Androidでゲーム シューティングゲームっぽい物。 その2:敵を1体をランダムに出現させる
Androidでゲーム シューティングゲームっぽい物。 その2-2:敵1体をランダムに出現させる。setSeed()メソッドを使う
Androidでゲーム シューティングゲームっぽい物。  その3:弾と敵の衝突判定
Androidでゲーム シューティングゲームっぽい物。その4:弾と敵が衝突したら、爆発エフェクトを動作させる
Androidでゲーム シューティングゲームっぽい物。 その5:敵の攻撃設定