2011年5月5日木曜日

タッチイベントを使って、画像を回転させる

Androidの画像を回転させる方法には、RotateAnimationクラスを使用する方法や、canvasクラスを使用する方法などがあるが、今回のタッチイベントを使って画像を回転させるのは、canvasクラスのrotateメソッドを使用して回転させる。


タッチイベントのMotionEvent.ACTION_MOVEで、回転させる時の角度を計算する。
こんな感じ
double rotate

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

rotate+=Math.atan2(touchY-getHeight/2,touchX-getWidth()/2);

そして、このrotateをcanvasクラスで呼び出したrotateメソッドの引数にて使用する。

canvas.rotate((int)rotate,getWidth()/2,getHeight()/2);

この、rotateメソッドの引数は
引数(角度,回転軸のX、回転軸のY)

画像の回転で注意しなくてはいけないのは、画像が回転しているのでは無く、canvasそのものが回転している、という事で、javaの時のGraphics2Dの時と同じ。

なので、画像の中心で回転しているように見せるには、rotateメソッドの引数の回転軸XとYそれぞれ
画面の幅と高さをそれぞれ1/2したものを入れている。



その他のタッチイベント関連

2011年5月4日水曜日

タッチした方向に描画した円を発射する。その2

前回作った物をちょっと改良して、物理的な要素を加え、自由落下運動っぽいことをして
画面下に来たら反発して、ボールのような動きをやってみようと思う。





















自由落下運動とは
重力だけを受けている物体が初速0で真下に落下する運動

落下する物体の運動は等加速度直線運動で、落下しながらスピードを増していく。

今回、画面下に来たら、反発して図のような動きをさせてみる。

自由落下に必要な計算は、
vy+=g*t






















座標上、下向きに動作する場合は、Y座標なので、y方向に重力を加え、また、これに等加速度運動を入れるので、時間を掛けてあげる。

そして、反発係数をいれる。
反発係数は、画面の右端、左端、画面下側に描画した円が来た時、vx,vyにそれぞれ、0.9を掛けている。
vx*=0.9;
vy*=0.9;

画面の端に来たときの処理は、こんな感じ

        if(x<0) {
        x=0;
          //移動方向を反転
        vx*=-1;
        vx *=0.9;
        }

        if(x>panel.getWidth()-r) {
        x=panel.getWidth()-r;
        //移動方向を反転
     vx*=-1;
        vx *=0.9;
        }

        if(y<0) {
        y=0;
        //移動方向を反転
     vy*=-1;
        vy *=0.9;
        }

        if(y>panel.getHeight()-r) {
        y=panel.getHeight()-r;
        //移動方向を反転
     vy*=-1;
        vy *=0.9;
        }




その他のタッチイベント関連
タッチイベントを使って、画像を回転させる
タッチイベントで文字を書いたり絵を描く
タッチした方向に描画した円を発射する
Androidでゲーム ブロック崩し編 3回目:板画像のタッチ操作
Androidでゲーム ブロック崩し編 4回目:タッチ操作が出来る範囲と出来ない範囲を作る
ランダムクラスを使って色の変更を行う
Androidのタッチイベントを使ってアニメーションを動作させる

2011年5月3日火曜日

タッチした方向に描画した円を発射する

Androidのタッチした方向に描画した円を発射するには、発射されるスタートの座標値から
タッチした座標値を求める。
















①スタートの座標値から、タッチした座標値の角度を考える
この場合の角度を求めるには、アークタンジェントを使う。

このアークタンジェントを求めるには、Mathクラスのatan2(double y,double x)を使用する。
これに当てはめると
double angle=Math.atan2(発射位置のy-タッチした位置のy,発射位置のx-タッチした位置のx)となる。

この、atan2()メソッドは極座標に変換するするもの。













②今度は速度を求める。
角度を求めたので、今度は求めた角度を使って速度を求める。
この速度を求めるには、タッチした座標値と発射する座標値をxとyそれぞれ分けて、
それに運動量を掛けると求められる。
この考え方はベクトルの分解と言う考え方を使う。

そうすると
double 速度x=Math.cos(angle)*運動量
double 速度y=Math.sin(angle)*運動量

から、速度を求めることが可能となる。















あとは、タッチイベントの処理メソッド内で発射する座標値とタッチする座標値を
Pointクラスを使用してそれぞれ求めることで発射することが出来る。

JavaTM Platform Mathクラスのatan2メソッド
Android Reference Mathクラスのatan2メソッド


2011年5月1日日曜日

タッチイベントで文字を書いたり絵を描く

タッチイベントを使って、画面を指でなぞったら字が書けたり絵が描けたりする。

SurfaceViewを使って作ってみる。

内容は、画面をなぞったら描画できるだけに限定し、他の設定は行わない。
(他の設定:保存したら画面に描画した物を消したりする)

まず、座標の位置を保管する方法を考える。

座標の位置を保管する物を作る。
使用するのは、ArrayList。

JavaのArrayList<E>クラスは、サイズが拡張可能な配列型データ構造

ArrayListの使い方
ArrayListクラスは大きさが決まっていない配列。
ArrayListを使うには、まずArraListクラスのオブジェクトを作成する。
デフォルトは初期容量 10 で空のリストを作成。
大きさは変更可能、サイズは足りなくなれば自動的に拡張される。

J2SE5.0以降は下記のように作成
ArrayList<型> 変数名 = new ArrayList<型>();
クラスの後ろに"<"と">"に囲まれて型を指定する部分がある。
この記述方法は、J2SE5.0から新しく導入されたGenerics機能と呼ばれるもの。

画面にタッチしたら、タッチしたポイントに描画する為にもう1つ必要なことがある。
タッチした座標値をこのArrayListを使って、どのように設定するか。

設定方法
①タッチした座標値を取得する
使う物はPointクラス。
最初、event.getX()とevent.getY()で得た座標値をxとyの変数に代入
x=event.getX()
y=event.getY()

そして、このxとyをPointの引数に入れる。
Point point=new Point(x,y);

②ArrayListを作る
インスタンスの作成
ArrayList<Point> draw=new ArrayList<Point>();
タッチイベントで、Pointを作った所でadd()メソッドを呼び出し、登録する
draw.add(point)

③描画処理
描画処理内にてfor()文を使用し、繰り返し処理を行う。
for(int i=0;i<draw;i++) {
ここでも、Pointクラスを呼び出す。
ArrayListに登録されている座標値を引っ張り出す支持を設定する。
引っ張り出すメソッドはget()メソッド。

こんな感じに記述
Point point=draw.get(i);

後は、描画する図形のメソッドの引数にて使用する。
canvas.drawCircle(point.x, point.y, r, paint);
}

JavaTM PlatformStandard Ed. 6 クラス:ArrayList<E>
Android Reference ArrayList<E>




その他のタッチイベント関連
タッチイベントを使って、画像を回転させる
ランダムクラスを使って色の変更を行う
Androidのタッチイベントを使ってアニメーションを動作させる

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回目:ボールとブロックの交差判定