Let's Re⇒move -27ページ目

チーム制作 6 [ ReverseGoki ]

[ matrixの回転 ]


前回のStayGoki.javaを参考にReverseGoki.java完成。


ReverseGoki.java

---------------------------------------

public class ReverseGoki extends SuperGoki{

protected Context context;
//中心に画像を表示するための描画開始位置
protected float currentX;
protected float currentY;
//倍率
protected float scale;
//画像の中心座標
protected float centerX;
protected float centerY;
//Y軸回転する角度
protected float angleY;
//感知したタッチ位置のx座標
protected float touchedX;
//はじめにタッチした位置のx座標
protected float firstX;
//イベントフラグ
protected int eventFlg;
//裏側の画像
private Bitmap reversImage;

public ReverseGoki(Context context, GokiController gokiController) {
super(context, gokiController);
this.currentX = -100;
this.currentY = -100;
this.scale = 2.0f;
this.centerX = getBodyBitmap(0).getWidth()/2;
this.centerY = getBodyBitmap(0).getHeight() /2;
this.reversImage = BitmapFactory.decodeResource(context.getResources(),
R.drawable.ura);
this.angleY = 0;
this.firstX = -1;
this.touchedX = -1;
this.eventFlg = 0;
}

@Override
public int getID() {
return 6;
}

@Override
protected void onOuterEvent(int eventType,float x,float y) {
if(eventType==Const.EVENT_TOUCH){
if(touchedX == -1) {
firstX = x;
touchedX = x;
} else {
touchedX =x;
}

}
if(eventType==Const.EVENT_TOUCH_RELEASE){
eventFlg = 1;
}
}

@Override
public void draw(Canvas canvas) {
currentX = canvas.getWidth()/2 - centerX*scale;
currentY = canvas.getHeight()/2 - centerY*scale;

switch (eventFlg) {
case 0:
move();
Log.e("event","move");
break;
case 1:
Log.e("event","release"+(angleY));
release();
break;
}


//現在の角度に合わせて描画
if((angleY+360) % 360 < 90) {
//matrix.setScale(scale,scale);
rotate3DMatrix(matrix,(angleY+360) % 360,centerX,centerY,0);
matrix.postScale(scale, scale);
matrix.postTranslate(canvas.getWidth()/2 - centerX*scale,
canvas.getHeight()/2 - centerY*scale);

canvas.drawBitmap(getAntennaBitmap(0), matrix, null);
canvas.drawBitmap(getBodyBitmap(0), matrix, null);
} else if((angleY+360) % 360 < 270) {
//matrix.setScale(scale, scale);
rotate3DMatrix(matrix,(angleY+360) %360 - 180,centerX,centerY,0);
matrix.postScale(scale, scale);
matrix.postTranslate(canvas.getWidth()/2 - centerX*scale,
canvas.getHeight()/2 - centerY*scale);
canvas.drawBitmap(reversImage, matrix, null);

} else if((angleY+360) % 360 < 360) {
//matrix.setScale(scale, scale);
rotate3DMatrix(matrix,(angleY+360) %360 - 360,centerX,centerY,0);
matrix.postScale(scale, scale);
matrix.postTranslate(canvas.getWidth()/2 - centerX*scale,
canvas.getHeight()/2 - centerY*scale);
canvas.drawBitmap(getAntennaBitmap(0), matrix, null);
canvas.drawBitmap(getBodyBitmap(0), matrix, null);
}
}
//matrix.reset();
//rotate3DMatrix(matrix, duration, bitmap.getWidth()/2,
// bitmap.getHeight()/2, 100);
//matrix.postScale(scale, scale);
/**
* 引数のtargetMatrixを3D回転したように変更する。
* @param targetMatrix
* @param degrees 角度
* @param centerX 3D回転する際の中心のx座標?
* @param centerY 3D回転する際の中心のy座標?
* @param depthZ ?
* @return
*/
public void rotate3DMatrix(Matrix targetMatrix,
float angle,float centerX, float centerY,float depthZ){
Camera camera = new Camera();
camera.save();
camera.translate(0.0f, 0.0f, depthZ);
camera.rotateY(angle);
camera.getMatrix(targetMatrix);
camera.restore();
targetMatrix.preTranslate(-centerX, -centerY);
targetMatrix.postTranslate(centerX, centerY);

}
/*
* 画像の右端の座標を引数に距離を回転角度に変換
*/
public void lengthToAngle(float imgX) {
float moveX = touchedX - firstX;
//反転するまでの距離
float reverseLength = imgX - firstX;
//タッチ位置が画像より左から右フリック
if (firstX < imgX && moveX > 0){
angleY = moveX / reverseLength * 180;
if(touchedX > imgX) {
angleY =180;
}
//タッチ位置が画像より左から左フリック
} else if (firstX < imgX && moveX <= 0) {
angleY = 0;
//タッチ位置が画像より右から右フリック
} else if (firstX > imgX && moveX >= 0) {
angleY = 0;
//タッチ位置が画像より右から左フリック
} else if (firstX > imgX && moveX < 0) {
angleY = -(moveX / reverseLength *180);
if(touchedX < imgX) {
angleY = -180;
}
}
}

//フリックで回転
private void move() {
//真ん中より左からフリックの場合画像の右端の位置までで180度回転
if(firstX <= currentX + centerX*scale){
lengthToAngle(currentX + centerX*scale*2);
//真ん中より右からフリックの場合画像の左端の位置までで180度回転
} else /*if (firstX > currentX + centerX*scale)*/ {
lengthToAngle(currentX);
}
}

//回転して戻る
private void release() {
if(Math.abs(angleY) > 30) {
angleY /= 2;
} else if (Math.abs(angleY) > 0) {
angleY = 0;
} else {
firstX = -1;
touchedX = -1;
eventFlg = 0;
}
}

}

------------------------------------------------------


自分の分担完成+q+


なにぶん初心者の為メソッド名とかフィールド名とかの付け方はおかしいかも。




チーム制作 5 [ 分担作業(画像を裏返すクラス) ]

[ 画像の表示 ]


3Dっぽく画像を裏返すイメージ。

参考にしようと見たページでしてたのはViewを裏返し

2枚用意した画像を見える状態にするか隠すかを変更するもの。


他にも色々検索してはホームページを見る作業で数日経過+q+


どうすればいいかK氏に相談したところ同じことをMatrixに適用してはどうかということ。


そこで抜き出してくれたのが以下のようなもの


//matrix.reset();
//rotate3DMatrix(matrix, duration, bitmap.getWidth()/2,
// bitmap.getHeight()/2, 100);
//matrix.postScale(scale, scale);
/**
* 引数のtargetMatrixを3D回転したように変更する。
* @param targetMatrix
* @param degrees 角度
* @param centerX 3D回転する際の中心のx座標?
* @param centerY 3D回転する際の中心のy座標?
* @param depthZ ?
* @return
*/
public void rotate3DMatrix(Matrix targetMatrix,
float angle,float centerX, float centerY,float depthZ){
Camera camera = new Camera();
camera.save();
camera.translate(0.0f, 0.0f, depthZ);
camera.rotateY(angle);
camera.getMatrix(targetMatrix);
camera.restore();
targetMatrix.preTranslate(-centerX, -centerY);
targetMatrix.postTranslate(centerX, centerY);

}


そしてこれを見てもこのときの自分には意味不明。よくわからず。

その間にK氏は真ん中に表示するだけのクラス[ StayGoki ]を作成。


StayGoki.java

------------------------------

public class StayGoki extends SuperGoki{
protected Context context;
protected float currentX;
protected float currentY;
protected float angle;
protected float scale;
private final Matrix matrix = new Matrix();
private final Matrix inverse = new Matrix();

private int dx = 20;

// context,gokiSurfase,currentX,currentY,angle,scaleを指定する
// コンストラクタ。
public StayGoki(Context context){
super(context);
this.currentX = 30;
this.currentY = 50;
this.angle = 0;
this.scale = 2.0f;
}

// canvasのsave,restore,背景描画は、GokiSurfaceで行っており、
// ここで記述するのは、このGokiの分の絵だけ。
// このGokiは、いるだけなので、
// 現行では、現在位置を起点にして、dxだけ左右に振っているだけ。
public void draw(Canvas canvas) {
this.currentX += dx;
this.dx = -dx;

matrix.setScale(scale, scale);
matrix.postTranslate(currentX, currentY);
// matrixの逆変換をinverseに設定する(touchのため)。
matrix.invert(inverse);

canvas.drawBitmap(getAntennaBitmap(0), matrix, null);
canvas.drawBitmap(getBodyBitmap(0), matrix, null);
}

@Override
public int getID() {
return 0;
}
}

-----------------------------------------------------


これを見て表示方法は把握。

あとはこのmatrixを上記のメソッドを使用して回転を実装するだけ。

だけ・・・



チーム制作 4 [ 基本のクラス作成 ]

それぞれがその動きだけするクラスを作成。


準備状態


・髭と足をそれぞれに動かしたい為画像を分割。

・drawableフォルダにそれぞれh20.jpg、b20.jpgを準備。

・→後々はframe++することによって動きを付ける予定。


分担作業前に準備したクラス(Kさん作成)


MainActivity

---------------------------------------------

public class MainActivity extends Activity {
private GokiSurface gokiSurface;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.gokiSurface = (GokiSurface) findViewById(R.id.gokisurface);
this.gokiSurface.setGokiController(new GokiController(this));
}

@Override
protected void onPause() {
super.onPause();
gokiSurface.surfaceDestroyed(null);
}

}

---------------------------------------------


GokiSurface.java

---------------------------------------------


public class GokiSurface extends SurfaceView implements Runnable,
android.view.SurfaceHolder.Callback {
private Thread thread;
private Bitmap image;
private Paint paint;

public GokiSurface(Context context, AttributeSet attrs) {
super(context, attrs);
this.image = BitmapFactory.decodeResource(context.getResources(),
R.drawable.g20);
this.paint = null;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
holder.setFixedSize(getWidth(), getHeight());
setFocusable(true);
}

@Override
public void draw(Canvas canvas) {
canvas.save();
canvas.drawColor(Color.WHITE);
//canvas.drawBitmap(image, 100, 100, paint);
Matrix matrix=new Matrix();
matrix.setScale(2.0f, 2.0f);
matrix.postTranslate(30, 50);
canvas.drawBitmap(image, matrix, paint);
canvas.restore();
}

@Override
public void run() {
while (thread != null) {
Canvas canvas = getHolder().lockCanvas();
draw(canvas);
getHolder().unlockCanvasAndPost(canvas);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
this.thread = new Thread(this);
thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
this.thread = null;
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
}

-----------------------------------------------

GokiController.java

---------------------------------------------

public class GokiController {
private Context context;
private GokiFactory factory;
private SuperGoki currentGoki;

public GokiController(Context context) {
super();
this.context = context;
this.factory=new GokiFactory(context);
this.currentGoki=factory.create(0);
}

public void draw(Canvas canvas) {
if (currentGoki!=null) currentGoki.draw(canvas);
}

//追加
public SuperGoki getCurrentGoki() {
return currentGoki;
}
}

---------------------------------------------


GokiFactry.java

---------------------------------------------

public class GokiFactory {
private Context context;

public GokiFactory(Context context) {
super();
this.context = context;
}

public SuperGoki create(int id) {
// それぞれの担当のクラスを返す

return new ReverseGoki(this.context);
}
}

---------------------------------------------


SuperGoki.java

---------------------------------------------

public SuperGoki(Context context) {
super();
this.context = context;
this.antennaBitmap = BitmapFactory
.decodeResource(context.getResources(), R.drawable.h20);
this.bodyBitmap = BitmapFactory
.decodeResource(context.getResources(), R.drawable.b20);
}
public Bitmap getAntennaBitmap(int frame) {
return antennaBitmap;
}
public Bitmap getBodyBitmap(int frame) {
return bodyBitmap;
}
/**
* 音を出す。
* @param name: 音の名前
* @param loop: ループ回数
*/
public void play(String name, int loop) {
// TODO:
}
public void vibrate(int duration) {
// TODO:
}
public void vibrate(int[] durations) {
// TODO:
}
}

------------------------------------------------------


この状態から担当の裏返る動きをするクラス[ ReverseGoki.java ]を作成