2011年4月30日土曜日

AndroidのLineメソッドを使って格子を描画する

AndroidのLineメソッドを使って、格子を描画する。

格子は、幅8マス、高さ8マスの格子。
1マスは32ドットで設定。






















定数でマスのサイズを決める
①マスのサイズ
private static final int GridSize=32

②マスの数
private static final int MASU=8;

②格子の大きさ
今回描画するの縦8マスが8個、横も8マスが8個の全体で正方形の格子なので
幅・・・
private static final int WIDTH=GridSize*MASU
高さ・・・
private static final int HEIGHT=WIDTH

描画処理
縦線を引くのと、横線を引くのをそれぞれにfor文を使って繰り返し処理を行う
縦線
for(int i=1;i<MASU;i++) {
canvas.drawLine(i*GridSize,0,i*GridSize,HEIGHT,paint);
}
横線
for(int i=1;i<MASU;i++) {
canvas.drawLine(0,i*GridSize,WIDTH,i*GridSize,paint);
}

androidのLineメソッドの引数は、(startX, startY, stopX, stopY, paint)。
縦線の場合、GridSize=32でそれが8個分
横線の場合、GridSize=32でそれが8個分
と言う意味になる。

そして、最後の外枠の部分はdrawRectを使用して、描画する。

完成図





















完成図では、成るべく真ん中ぐらいに描画する為に、それぞれ、25をプラスしている。

2011年4月29日金曜日

Androidでゲーム ブロック崩し編                 12回目:数字画像を使って機数の表示と設定

機数の設定を行う。

ボールが画面の下に落ちたら、機数を1減らす。

大まかな流れ
ボールが画面の下に落ちる

カウント変数を1減らす

ボールが初期位置に出てきて、移動を開始

機数の表示は、文字列では無く数字画像を使用する。

数字画像の表示方法や設定情報は
Androidでゲーム ブロック崩し編 9回目:数字画像を使って点数の表示
でも、扱っている。

初期設定値は3。
コンストラクタの中身には
count=3;
と、記述。

Ballを設定しているクラスファイルの描画メソッドの中に、数字画像の表示と、
配列の中身に桁の計算を記述する。

こんな感じ
※機数の表示は2桁の表示としたい。
なので、0だけの画像は2個、横に連なっている画像を表示させる

//0が2個の画像
canvas.drawBitmap(img2,264,100,null);

//数字画像の呼び出し
//数字画像のよびだしも2桁分のみの設定。
//配列の中身は、1桁目が9の時、10に表示が変わる時の1上がる計算
canvas.drawBitmap(img3[count%10],280,100,null);
canvas.drawBitmap(img3[count/10],264,100,null);

次に、ボールの移動制御を設定しているメソッド内で、ボールが画面下に落ちたら、
機数を減らす設定とボールの初期位置に出てきて、移動を開始する設定を作る。

画面下に来た場合の条件式の中に機数を減らす設定と、
ボールを初期位置に戻す設定を記述する。

こんな感じ
down_Count(1);
//スタート時のボールの位置はx=150,y=250に設定している
setPos(150,250);

down_Count()メソッドは
public void down_Count(int count) {
//thisを忘れると、カウントしてくれない。
this.count-=count;
}

初期位置に戻すメソッドsetPos()は、
public void setPos(float x,float y) {
this.x=x;
this.y=y;
}

と、設定を作っておいた物。

ただ、このまま機数を減らして0よりも小さくなってしまったら、
「Sorry!」の警告ダイアログがでてしまうので、これを回避する設定を作る。

作るといっても、count変数が0よりも小さくなってしまったら、ゲームを止めるように設定するだけ。

Ballを設定しているクラスファイルの中で、ゲームオーバーになった時のメソッドを作成する。
そして、そのブロック内に設定情報を記述する。

今回の設定内容では、countが0よりも小さくなってしまったら、ボールを初期位置に戻して、
移動を止めて、ゲームオーバーの文字列を表示させるだけのものを作成する。

全体の流れは以下の通り




















コードはこんな感じ
public void gameOver() {
//countが0よりも小さくなってしまったら
if(count<0) {
//カウントに0を代入
count=0;
//移動を止める為、移動設定をしている変数に0を代入
move_x=0;
move_y=0;
//ボールを初期位置に戻す
setPos(150,250);
//0よりも小さくなってしまったらフラグをtrueに設定する
flg=true;
}
}

描画メソッドは、条件式にてフラグがtrueの時に、文字列を表示するように設定する。
こんな感じ
//フラグがtrueの場合
if(flg==true) {
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setTextSize(25);
canvas.drawText("ゲームオーバー",75,300,paint);
}

Ballクラスで設定したgameOverメソッドをMainSurfaceViewを設定しているクラスファイルの、
runメソッド内で呼び出して
記述するだけ。


動画は機数の初期設定を3ではなく、1で設定している。



その他のブロック崩し関連

2011年4月28日木曜日

交差判定 その3-2:矩形同士の交差判定

矩形同士の交差判定で前回とちょっと違った方法で判定する。

JavaのRectangleを使用して、contains()と言うメソッドを呼び出して判定する。

このcontains()メソッドは、『指定された位置 (x,y) にある点を含むかどうかを判定する』
と、Javaの説明に有る。

どういうことかと言うと、矩形の中に指定した矩形の点が入っていたらtrueを返す仕組み。



















今回はキー操作で動かす矩形を矩形1、動かさない矩形を矩形2として、
矩形2の中に矩形1が入ったら、trueを返す仕組みを作ってみる。


【trueを返す時にどの位置が入った時に返すか】

矩形2の左上、左下、右上、右下の4角に矩形1の4角が入ったらtrueを返すように設定する。
そして、左上、左下、右上、右下の4角を定数で設定しておく。
また、入っていない時の状況も考慮して、入っていない時の定数も合わせて作る。
設定する定数
入っていない時:NO_COLLISION=0
左上:UP_LEFT=1
左下:DOWN_LEFT=2
右上:UP_RIGHT=3
右下:DOWN_RIGHT=4

矩形の4角、それぞれの座標位置
4角の座標位置は以下の通り
左上:X,Y
左下:X,Y+HEIGHT
右上:X+WIDTH,Y
右下:X+WIDTH,Y+HEIGHT












最初に設定するものは、動かない矩形1の矩形の設定を行い、contains()メソッドを
使ってどの位置に入ったか、返す条件式を作成する
また、X,Y,WIDTH,HEIGHTをそれぞれしゅとくして変数に代入する

こんな感じ
Public int collision(Rect1 rect1) {
//動かない矩形2の設定
Rectangle rect=new Rectangle(X,Y,WIDTH,HEIGHT);
//X,Y,WIDTH,HEIGHTをそれぞれしゅとくして変数に代入
//型がint型だが、座標値を他の型で設定していてもキャストすれば問題ない
int rect1_X=rect1.getX();
int rect1_Y=rect1.getY();
int rect1_W=rect1.getWIDTH();
int rect1_HEIGHT=rect1.getHEIGHT();

//矩形2の左上から矩形1の右下が入ってきた場合
if(rect1.contains(rect1_X+rect1_W,rect1_Y+rect1_H)) {
return UP_LEFT;
}

//矩形2の左下から矩形1の右上が入ってきた場合
if(rect1.contains(rect1_X+rect1_W,rect1_Y)) {
return DOWN_LEFT;
}

//矩形2の右上から矩形1の左下が入ってきた場合
if(rect1.contains(rect1_X,rect1_Y+rect1_H)) {
return UP_RIGHT;
}

//矩形2の右下から矩形1の左上が入ってきた場合
if(rect1.contains(rect1_x,rect1_Y)) {
return DOWN_RIGHT;
}
//何にも無かった場合
return NO_COLLISION;
}














次に、位置を求めるメソッドを作成する。
switch文を使ってそれぞれの4角に対しての位置を求める。
こんな感じ
public void collisionDetection() {
//上記で作ったメソッドの返りを取得して
//変数に代入し、switch文で使用する
int collidePos=collision(rect1);
//NO_COLLISION以外の場合
if(collidePos!=NO_COLLISION) {
swicth(collidePos) {
case UP_LEFT:
//この中に入っていた時にどうするかの
//動作を記述する
break;

case UP_RIGHT:

break;

case DOWN_LEFT:

break;

case DOWN_RIGHT:

break;

default:
break;
}
}
}

これで、一通り完成。
今回は、一致した場所に交差したら、文字列を出力するようにした。

この作り方はAndroidでも利用できる。

Java Rectangleクラス
android reference rectクラス:containsメソッド




その他の交差判定
交差判定 その1:線と線
交差判定 その2:点と円の交差判定と円同士の交差判定
交差判定 その3-1:矩形同士の交差判定

その他の交差判定関連
Androidでゲーム ブロック崩し編 5回目:ボールと板の交差判定
Androidでゲーム ブロック崩し編 6回目:ボールとブロックの交差判定

交差判定 その3-1:矩形同士の交差判定

矩形同士の交差判定

2つの矩形があり、この2つの矩形を図のように交差させてみた時の
交差判定

2つの矩形








これを重ねる。


考えること。
XとYをそれぞれ個別に見て、そして、

①X1とX2+WIDTHの対角を比較する

条件式は
X1<=X2+WIDTH

②X2とX1+WIDTHの対角を比較

条件式は
X2<=X1+WIDTH

③Y1とY2+HEIGHTの対角を比較

条件式は
Y1<=Y2+HEIGHT

④Y2とY1+HEIGHTの対角を比較
Y2<=Y1+HEIGHT

これらの式をまとめると
if(X1 <= X2+WIDTH && X2 <= X1+WIDTH) &&
  (Y1 <= Y2+HEIGHT && Y2 <= Y1+HEIGHT) {
   //この中に、条件が一致した時の内容を記述する。
}

となる。




その他の交差判定
交差判定 その1:線と線
交差判定 その2:点と円の交差判定と円同士の交差判定
交差判定 その3-2:矩形同士の交差判定


その他の交差判定関連

2011年4月26日火曜日

Androidでゲーム ブロック崩し編                 11回目:ブロックに複数回ぶつけたら壊れるようにする

複数回、ボールをぶつけたら壊れるブロックを作る。

大まかな流れ

ボールとブロックがぶつかる

カウント値が1減少

カウント値が0になったら、ブロックの保管場所に移動






















複数回ぶつけたら壊れるブロックのクラスファイルに、count変数を設定。

他に設定する事
ぶつかった時に、カウント値が減るメソッドの作成
カウント値が0になったらtrueを返すメソッド

SurfaceViewを設定しているクラスファイルでは、
交差判定処理内に、まず、カウント値を減らす処理を記述し、
また、カウント値が0になった場合に保管場所に移動する処理と、
点数加算の処理を記述しておく。

こんな感じ
※ブロックは複数処理を設定しているものとする
for(int i=0;i<NUM_BLOCK;i++) {
if(block[i].collideWith(ball)) {
//ボールの移動方向を反転させる
省略

//カウント値を減らす
block[i].down_Count;

//ブロックのカウント値が0だった場合
if(block[i].isCount()) {
//ブロックを保管場所に移動させる
block[i].die();
//点数を加算
count.count(5);
}
//1つ壊したら抜ける
break;
}
}


その他のブロック崩し関連

2011年4月25日月曜日

Androidでゲーム ブロック崩し編                 10回目:ブロックが壊れたらアイテムが出て来る

ブロックを壊したらアイテムを出すようにする。

大まかな流れ
ブロックにボールがぶつかる

アイテムの保管庫からアイテムを呼び出し、
ぶつかったブロックの位置にアイテムをセットする

アイテムが降ってくる

板とアイテムが接触

点数が入る

アイテムを保管庫に戻す。

取り合えず、アイテムを一個だけ出てくるようにする。
複数処理は行わない。

属性の設定
アイテムのクラスファイルを作成する。
ブロックを壊したら、ブロックの位置にアイテムをセットするので、アイテムの座標値を設定する。

あと、交差判定処理に使用する為のアイテムのサイズを設定する。
今回のアイテムサイズは26ドット(幅と高さ同じ物)


今回使用した画像


画像のイメージ変数の作成

保管庫を作らないといけないので、Pointクラスを呼び出す。
定数で設定する。
こんな感じ
private static final Point Storage=new Point(-50,-50);

あと、フラグを用意する。
フラグは、ブロックを壊したら、アイテム画像を表示する為のもので、
ブロックを壊したら、trueする。初期状態はfalse。

それと、アイテム画像が画面下まで行った時、保管庫に行くために画面のサイズを
取得する必要があるので、SurfaceViewを設定しているクラスファイルを呼び出すための
変数を作る。

こんな感じ
private MainSurfaceView panel;


コンストラクタの中身
○コンストラクタは、まず、イメージ画像の呼び出し
○保管庫から呼び出してアイテムの座標値にセットする
○アイテムを移動するための設定
○フラグの初期化

を、それぞれ記述する
こんな感じ
public Item1(MainSurfaceView panel) {
this.panel=panel;

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

//保管庫から呼び出して、画像の座標値に設定する
x=Storage.x;
y=Storage.y;

//移動値の設定
//移動するときは、垂直に降りてくる
move_x=0;
move_y=3;

//フラグ変数
//初期状態はfalse
flg=false;
}

移動用メソッド
○移動用メソッドの中身は、
○移動するときの設定
○画面下に出た時の設定

こんな感じ
x+=move_x;
y+=move_y;

//画面下に出た時の処理
if(y>panel.getHeight()) {
//画面下に出たら保管庫に移動する
Store();
//フラグをfalse
flg=false;
}

描画用メソッド
○メソッドの中身は
○フラグがtrueの時、画面に表示されるように設定する

交差処理
○板とアイテムが接触したらtrueを返すメソッドを作成する

SurfaceViewを設定しているクラスファイルで呼び出すためのメソッドの作成をする。
○ブロックを壊したら、trueにするメソッド
○板とアイテムが接触したらfalseにするメソッド
○ブロックにセットするメソッド
○アイテムを取得又は、画面下から出た時に保管庫に移動するためのメソッド


SurfaceViewを設定しているクラスファイルでの設定

設定する内容は、
○描画処理
○移動処理
○ボールとブロックの交差処理
○アイテムと板の交差処理

ボールとブロックがぶつかったら、アイテムをセットする
こんな感じ
//位置のセット
item1.setPos(block_Pos.x,block_Pos.y);
//フラグをtrue
item1.Flg();

この中で注意することは、ブロックの位置を取得する時の記述場所に注意しないといけない。
item1.setPos()の上に記述するとアイテムはセットされない。
ブロックとボールの交差判定を呼び出している条件式の中に記述してもアイテムは出てこない。

ブロックは複数処理を行っているので、
for(int i=0;i<NUM_BLOCK1;i++) {
Point block_Pos=block1[i].getPos();

//ブロックとボールの交差判定条件
if(block[i].collideWith(ball)) {
以下省略

//位置のセット
item1.setPos(block_Pos.x,block_Pos.y);
//フラグをtrue
item1.Flg();
}

と記述した方がいい。
Point block_Pos=block1[i].getPos();
item1.setPos(block_Pos.x,block_Pos.y);
では、アイテムは出てこない。

アイテムと板の交差判定処理
アイテムと板の交差判定条件と、アイテムを取得したら保管庫に移動するメソッド、
アイテムを取得したら、フラグをfalseに設定。
点数を加算する処理。
を設定する。


※ブロックとボールの交差判定の調整や、ボールの動き等は調整していない。
ブロック1個壊したら、50点入るようにしている。
アイテムを取得したら、点数が1000点加算される


その他のブロック崩し関連

2011年4月24日日曜日

Androidでゲーム ブロック崩し編                 9回目:数字画像を使って点数の表示

点数のカウントに数字画像を使って表示する

用意するものは、0~9の10個の数字画像と、0を10桁分表示している画像の計11枚。

まず、10個の画像を配列に入れる。
インデックス番号[0]~[9]を作成して、引数は、画像が入っているフォルダーを指定する
ファイル名の名前が可笑しいのは、打ち間違えた。
img1=new Bitmap[10];
img1[0]=BitmapFactory.decodeResource(r,R.drawable.cout00);
img1[1]=BitmapFactory.decodeResource(r,R.drawable.cout01);
以下省略

次に、描画処理をしているメソッドで、呼び出しと、桁上がりの計算を行うものを記述する
こんな感じ

//10桁の0だけの表示がされている画像を呼ぶ
canvas.drawBitmap(img0,10,100,null);

//動作する部分の表示設定
canvas.drawBitmap(img1[count%10],138,100,null);
canvas.drawBitmap(img1[count/10%10],122,100,null);
canvas.drawBitmap(img1[count/100%10],106,100,null);
canvas.drawBitmap(img1[count/1000%10],90,100,null);
以下省略

0だけを10桁分表示している画像の上に動作する部分の画像が重なるように
座標値の設定を行う。
そうしないと、ずれてしまう。

最後に、ブロックを壊したら、点数が加算するように設定する。
こんな感じの呼び出し用メソッドを作成した
public void set_count(int count) {
 this.count+=count;
}

そして、このメソッドを当たり判定処理のメソッドで呼び出せば使える。


※ブロックとボールの交差判定の調整や、ボールの動き等は調整していない。
ブロック1個壊したら、50点入るようにしている。


その他のブロック崩し関連

2011年4月23日土曜日

交差判定                               その2:点と円の交差判定と円同士の交差判定

点と円の交差判定と円同士の交差判定

①点と円の交差判定

点を移動させて、円の中に入ったら交差していると判断する

点の座標をX0,Y0

円は、中心座標CX1,CY1
半径をr1とする。














交差しているかいないかの条件は、
円の中心座標と点の座標との距離が、円の半径以下なら交差と判断する。

この距離を求める方法が、三平方の定理を使ってX方向とY方向のそれぞれの距離を求める。

三平方の定理は
平面幾何学において直角三角形の斜辺の長さを c とし、その他の辺の長さを a, b とした時、




になる関係が、成立するという幾何学の定理。学校で習った物です。

点の座標と円の中心座標の距離をこの三平方の定理で求めると
(CX1-X0)*(CX1-X0)+(CY1-Y1)*(CY1-Y1)=r*r













と、なる。


交差判定なので、距離が半径以下となったら、交差していると判断するので
このようになる。

(CX1-X0)*(CX1-X0)+(CY1-Y1)*(CY1-Y1)<=r*r


②円同士の交差判定
円を2つ作って1つを移動させて、もう1つの円の中に入ったら交差していると判断する。

円同士の交差判定も、①で使った三平方の定理を使って判定を行う。

円1
中心座標:CX0,CY0
半径:r0
円2
中心座標:CX1,CY1
半径:r1














円1の中心座標と円2の中心座標の距離が円1の半径と円2の半径の
和以下なら交差していると判断する。

条件式に表すと
(CX1-CX0)*(CX1-CX0)+(CY1-CY0)*(CY1-CY0)<=(r1+r0)*(r1+r0)
と、なる。

条件式が成立していない時


















条件式が成立している時




















点と円の交差



円同士の交差


その他の交差判定
交差判定 その1:線と線
交差判定 その3-1:矩形同士の交差判定
交差判定 その3-2:矩形同士の交差判定


その他の交差判定関連

2011年4月22日金曜日

Androidでゲーム ブロック崩し編                 8回目:点数の文字列表示

ブロックを壊したら、点数をカウントする。

取り合えず、ブロック1個50点としたい。

作る時の大まかな流れ
カウントをするクラスファイルを作成
               ↓
SurfaceViewを設定しているクラスファイルにある
交差判定処理の中にカウント計算をするメソッドを呼び出す。
               ↓
SurfaceViewを設定しているクラスファイルにある
描画処理メソッドでカウントの描画処理メソッドを呼ぶ。


SurfaceViewを設定しているクラスファイルにて直接作らない理由は、
のちのち、数字画像を使って、点数を表示する仕組みを作るための
前準備として。


最初は、テストとして文字列で点数をカウントしたい。
なので、必要な物はPaintクラスを使用する。

AndroidのPaintクラスを呼んで、アンチエイリアスを有効にして、テキストサイズを決めて
表示する文字の色を決めておく。
メソッドは
アンチエイリアス・・・setAntiAlias()
テキストサイズ・・・・・setTextSize()
文字の色・・・・・・・・・setColor()

こんな感じ
paint.setAntiAlias(true);
paint.setTextSize(15);
paint.setColor(Color.CYAN);


事前にPaintクラスのインスタンスを作っておく必要がある。

そして、CanvasクラスのdrawText()メソッドを呼び引数に設定する。
こんな感じ
canvas.drawText("点数:"+count, 10, 200, paint);

次は、SurfaceViewを設定しているクラスファイルに、Countを設定してクラスファイルを
呼び出すようにしなければならない。

どういう時に点数のカウントを行わないといけないか?
と言う話になるのだが、もちろんブロックにボールがぶつかった時、
点数が加算されるという仕組みにしなければいけない。

と、なると、何処にCountのクラスファイルで作ったカウントの計算をするメソッドを
呼び出すかと言うと交差したらどういう処理を行うかと、設定を行っているメソッドの
中に記述しなければいけない。

一例として
/**
 * ボールとブロックの交差処理
 */
public void block_collisionDetection() {
for(int i=0;i<NUM_BLOCK1;i++) {
if(block1[i].collideWith(ball)) {
ball.move_x=-ball.move_x;
ball.move_y=-ball.move_y;

//ボールとブロックがぶつかったら
//ブロックを消す
block1[i].die();

//点数のカウント
//ブロック1個:50点
count.count(50)
}
}
}

てな感じ。他にも色んな方法があるはず。

計算する為の仕組みまでは出来たので、最後に、描画処理を行えば
画面に点数が表示される。

android reference:Paint
android reference:Canvas


※ボールの動きやボールとブロックがぶつかった時の細かい処理は行っていない

その他のブロック崩し関連

2011年4月21日木曜日

Androidでゲーム ブロック崩し編                 7回目:同じブロック画像を複数並べる

ブロックを沢山並べる。

流れは、
定数を作り
      ↓
配列に入れる
      ↓
描画メソッドで設定
      ↓
runメソッドで呼ぶ

SurfaceViewを構成しているクラスファイルに、ブロックを設定しているクラスファイルを呼び出す。
インスタンスを作る変数を設定し、コンストラクタで以下のような物を作る。

複数処理用の定数を作る
private static final int NUM_BLOCK1=10;

インスタンスの変数
private Block1[] block1;

コンストラクタ内
block1=new Block1[NUM_BLOCK1];

そんで、for文を使用して、さらに設定をする
for(int i=0;i<NUM_BLOCK1;i++)
block1[i]=new Block1(10+(i%9)*32,50+(i/10)*16,this);

この、block1[i]=new Block1(10+(i%9)*32,50+(i/10)*16,this);
の引数はBlock1のコンストラクタに引数を設定して、
Xに何個、Yに何個並べるよって計算だけども、

このようなやり方じゃなくても、並べることが出来る。
for文を書かないで、インデックス番号を指定して配列を記述。
また、この場合、定数はいらない。
block1[0]=new Block1(50,50,this);
block1[1]=new Block1(100,100,this);
以下省略・・・・

ただ、今記述している定数は、10で済んでいるが、
これが30やら50となったら、目も当てられない。

これ以外にも、やり方はあるが、ステージ設定をしているわけでもないので、
今回はこれだけで行っている。

生成したところで、今度は描画メソッドに記述する。
ブロックを設定しているクラスファイルで作っている、描画メソッドを呼ぶ。
for(int i=0;i<NUM_BLOCK1;i++)
block1[i].draw(canvas);

あとは、runメソッドに描画メソッドを呼び出せば、画面に表示される。

完成画像























その他のブロック崩し関連

Androidでゲーム ブロック崩し編 1回目:画像の表示
Androidでゲーム ブロック崩し編 2回目:ボールの移動
Androidでゲーム ブロック崩し編 3回目:板画像のタッチ操作
Androidでゲーム ブロック崩し編 4回目:タッチ操作が出来る範囲と出来ない範囲を作る
Androidでゲーム ブロック崩し編 5回目:ボールと板の交差判定
Androidでゲーム ブロック崩し編 6回目:ボールとブロックの交差判定
Androidでゲーム ブロック崩し編 8回目:点数の文字列表示
Androidでゲーム ブロック崩し編 9回目:数字画像を使って点数の表示
Androidでゲーム ブロック崩し編 10回目:ブロックが壊れたらアイテムが出て来る
Androidでゲーム ブロック崩し編 11回目:ブロックに複数回ぶつけたら壊れるようにする
Androidでゲーム ブロック崩し編 12回目:数字画像を使って機数の表示と設定

2011年4月20日水曜日

交差判定 その1:線と線

Androidの、線と線の交差判定について。
Androidに限らず、考え方は同じだと自分は思っている(経験上)


交差判定の前にAndroidの線について
Androidの線はCanvasクラスのgrawLine()メソッドを呼ぶ。

drawLineの引数は
drawLine(int x0,int y0,int x1,int y1,Paint paint)

引数の説明
x0・・・始点のX座標
y0・・・始点のY座標
x1・・・終点のX座標
y1・・・終点のY座標



今回、交差させる為に2本の線を描画し、1本はキー操作で移動させ、もう1本は、動かさないで固定させておく。






        

















                                        ルール




青い線と赤い線を用意する
青い線・・・Line_1
赤い線・・・Line_2
それぞれの始点終点の座標
始点X0,Y0
終点X1,Y1

とする。




こんな感じで交差したら、trueを返すようにしたい












交差判定は、どれとどれを比較して、それよりも大きいか、また、小さいかを見て判定する

それでは、比較する対象を列挙する
Line_1の始点とLine_2の始点
Line_1の終点とLine_2の終点

線同士の交差判定はこれだけでこれ以上は必要ない。

出来る限り解りやすくしたいから、細かい考え方は省略する。
ベクトルがどうとかなんて書きません。3Dじゃないので。

列挙した物をもう少し細かくして見る。
Line_1の始点はX0,Y0
Line_2の始点はX0,Y0

Line_2の終点はX1,Y1
Line_2の終点はX1,Y1

それでは、比較してみようと思う。
最初に比較する物は、Line_1の始点はX0,Y0とLine_2の始点はX0,Y0

図で、動かないLine_2の線と動くLine_1の線に対しての位置関係を考えると、
Xの場合は
Line_1の始点X0は、Line_2の始点X0の位置関係を見ると、座標値の大きさは
Line_1の始点X0の方が大きい
Yの場合は
Line_1の始点Y0は、Line_2の始点Y0の位置関係を見ると、座標値の大きさは
Line_2の始点Y0の方が大きい

と言うことが解る。
これを演算にして見ると
Line_1.X0>Line_2.X0
Line_1.Y0<Line_2.Y0
になる。

それで、同じ要領で、終点について考えてみると
Line_1の終点X0は、Line_2の終点X0の位置関係を見ると、座標値の大きさは
Line_2の終点X0の方が大きい
Yの場合は
Line_1の終点Y0は、Line_2の終点Y0の位置関係を見ると、座標値の大きさは
Line_1の終点Y0の方が大きい

と言うことが解る。
これを演算にしてみると
Line_1.X0<Line_2.X0
Line_1.Y0>Line_2.Y0
になる。

これを条件式にして見る。

と、その前に、どういうときに交差しているのか?
と言うことについて考えると、

上記の比較で得た内容全てが一致した時に交差していると判断したいので
この場合、演算子はANDを使う。

ANDは1と1の時、1を返し、それ以外は0を返す。

と言うことで、今度こそ、条件式にして見る。

if(((Line_1.X0>Line_2.X0)&&(Line_1.Y0<Line_2.Y0))&&((Line_1.X0<Line_2.X0)&&(Line_1.Y0>Line_2.Y0))) {
そして、交差したらtrueを返すようにフラグ変数にtrueを代入する内容を書く
}

これで、完成。

android reference:Line

Androidでゲーム ブロック崩し編                 6回目:ボールとブロックの交差判定

今度は、ボールとブロックの交差判定。

前回、板とボールの交差判定を行ったので、前回と同じような方法を使って
矩形同士の交差判定を行う。

大まかな流れは

boolean型のメソッドを作る
 ↓
交差した時の処理を作る
 ↓
呼び出す

大まかな流れも特に変更は無い。

最後の、run() メソッドでcollisionDetection()
を呼ぶところも変わらない。

但し、public boolean collideWidth(Ball ball) {}の記述するクラスファイルは、
ブロックの設定を行っているクラスファイルの中に記述した。

だがしかし、ここからがちょっと厄介なことになる。

ボールとぶつかったブロックをどうするか・・・。

ぶつかったら、ブロックは消えるだろうと思っていたら、そう簡単には消えてくれない。

それでは、フラグでも立てればいいのか?
と思っても、駄目。
見えている部分は消えても、座標値は生きているから。

ではどうするか。

2通り思いつくが、簡単に作りたいと思っているので、簡単な方を考える。
ArrayListを呼び出しての方は使わない。

Androidのメソッドには、Pointというメソッドがある。これは、Javaにもあった物。
使い方は、Javaと変わらない。
画像の呼び出しのように原型とどめて無いじゃんってくらい変わられると困る(私が・・・)。

Blockを設定したクラスファイルに
まず、ぶつかったら何処かに隠しておく場所を定数で作る
その次に、ボールとぶつかったら、その隠し場所に移動するためのsetterを作っておき、

最後にpublic void collisionDetection() {}
のブロック内に作ったsetterを呼べば、
なんてことでしょう、先ほどまで其処にあったブロックが何処かに
行ってしまいましたってことが出来る。

参考
android reference:Point


















その他のブロック崩し関連

2011年4月18日月曜日

Androidでゲーム ブロック崩し編                 5回目:ボールと板の交差判定

交差判定・・・。

それは、ゲーム製作で1番の難敵かもしれない(自分)

交差判定には色々ある。
矩形同士、円形同士、点と線など色々。

今回は、そんな数ある中で選ばれた矩形同士の交差判定を使って、
ボールと板の衝突を演出する。

矩形同士の交差を図に表すと

















Androidには、Rectと言うメソッドが存在する。

if(ごちゃごちゃごちゃりんこ<ごちゃお||ごちゃみ>ごちゃりんこ&&・・・・){
反発するぞ!!
}
など使わなくてもこのRectメソッドを使えば、いとも簡単に反発してくれる。

そもそも、JavaにはRectangleなる物があり、このRectangleを使用して
矩形同士の交差を判定するのだが、
Androidには、RectangleではなくRectとなっており、
使い方はJavaの時と同じ用に使えばいい。

大まかな流れ

boolean型のメソッドを作る

交差した時の処理を作る

呼び出す

流れが出来た所で作り方の一例

今回使用するのは、ボールと板なので、取り合えず、板を設定しているクラスファイルに
boolean型のメソッドを作る。

public boolean collideWidth(Ball ball) {
}

そして、ブロックの中身は
まず板の矩形
Rect rect_boar=new Rect()
引数の中身は、Androidで矩形を描画する時の引数と同じで
一応
int left,int top,int right,int bottom

次に、ボールの位置座標を取得
この時、ボールを設定しているクラスファイルでgetterを作っておく
Point ball_Pos=ball.getPos();

そして、ボールの矩形
Rect rect_ball=new Rect()
引数の中身は、Androidで矩形を描画する時の引数と同じで
一応
int left,int top,int right,int bottom

最後、boolean型なので、返さないといけない
この場合、返す条件は板とボールが交差したらtrueを返すというふうにしなくてはいけない。

交差のメソッドを呼び出す
interset()と言うものがあり、これを使う。

return rect_board.intersect(rect_ball);

そして、ここは、終了。

次に、メインのクラスファイルで、交差したらどうするかのメソッドを作る。
public void collisionDetection() {

ブロックの中身は
if(board.collideWidth(ball)) {
このブロックの中に、交差したら、
どうするかの内容を記述する。
}

最後、run() メソッドで
collisionDetection()
を呼べば、反発してくれる。

参考
android reference:Rect





その他のブロック崩し関連

2011年4月17日日曜日

Androidでゲーム ブロック崩し編                 4回目:タッチ操作が出来る範囲と出来ない範囲を作る

板の操作時に画面のあっちこっちを触って板を動かすより、板の真下あたりで、
板が指に隠れないようにして操作したい場合。



















onTouchEvent()メソッドの中に条件式で引数の中にタッチ操作を行いたくない
範囲を記述する。


例えば
if(touchX>0&&touchX<370&&touchY>0&&touchY<388) {
}

上記の例だと、座標値x=0~x=370、y=0~y=388の範囲の座標を指定、



















そして、この条件式のブロックにタッチしたら、フラグをtrueにする
フラグ変数を使用し、flg=falseで記述しておく。

あとは、moveメソッドで
if(flg==true) {
}
と記述し、そのブロック内にボードの座標値にタッチ座標を代入するコードを記述すればいい。


その他のブロック崩し関連

2011年4月16日土曜日

Androidでゲーム ブロック崩し編                 3回目:板画像のタッチ操作

板をタッチ操作で動かす

板を動かさないと動いているボールをはじく事が出来ない。

まずは、板をタッチ操作で動かすことからはじめる

タッチイベントは、ViewクラスでonTouchEvent() {}を呼び出す。

今回必要な設定は、タッチしたとき、タッチして動かしている、
画面から離れた時の3つの設定を使う。

変数でtouchX,touchY,touchActionを作成、それぞれ型はint型とする。

作った変数にそれぞれタッチイベントのX座標とY座標を代入し、またtouchActionには
アクション種別の取得を行う

touchX=event.getX();
touchY=event.getY();
touchAction=event.getAction();

次に、条件式でMotionEventクラスのアクション種別の定数を呼び、
それを、touchActionと同じかどうか判断する
if(touchAction==MotionEvent.ACTION_DOWN)
if(touchAction==MotionEvent.ACTION_MOVE)
if(touchAction==MotionEvent.ACTION_UP)

これらの条件が一致した時に板の設定をしているクラスから、
板のX座標値とY座標値を呼び出し、代入してあげる。

どういうときに、代入するかと言う話になるので、一致したらフラグを立てるようにしてあげる。

例えば、
if(touchAction==MotionEvent.ACTION_DOWN)
//タッチしたらフラグはtrue
flg=true;
if(touchAction==MotionEvent.ACTION_MOVE)
//MOVEしたら、フラグはtrue
flg=true;
if(touchAction==MotionEvent.ACTION_UP)
//離したら、フラグをfalseにする
flg=false;

flgがtrueの時に板の座標値に代入してあげるようにする
if(flg==true)

代入する値は、タッチしたときの座標値XとYを代入する
board.setX(touchX);
board.setX(touchY);

どのメソッドで処理するか
MainSurfaceViewのクラスファイルにmove()メソッドを作成しこのブロックの中に
if(flg==true) {
board.setX(touchX)
board.setY(touchY)
}

後は、板クラスで作った移動制御メソッドを呼び、run()メソッドの中に記述すれば
動かすことが出来る

板の移動範囲
板を移動させる時に、このままだと、画面を縦横無尽に動き回る。
これを、決められた範囲で動かしたい。




左の図で、水色部分の範囲だけで板が
動くようにするには、板を設定しているクラスファイル
にmoveメソッドを作り、その中に、
移動を制限するコードを記述するばいい。















例えば、
public void move() {
x+=move_x;
y+=move_y;

//移動範囲の設定
//x=0~x=320
//y=380~y=380
//上
if(y<380) {
y=380;
move_y=-move_y;
}
//下
if(y>380) {
y=380;
move_y=-move_y;
}
//左
if(x<0) {
x=0;
}
//右
if(x>320-img.getWidth()) {
x=320-img.getWidth();
}
}
見たいな感じで作る。





その他のブロック崩し関連
Androidでゲーム ブロック崩し編 1回目:画像の表示