隨機打亂順序失敗
打亂順序的時候,我不能交換,用了Toast,發現我交換的兩個小方塊的坐標是一樣的,但是他們數組的i,j是不一樣的,這是怎么回事呢,現在還沒解決。。。。?
package com.charspan.pintu;
import java.util.Random;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
private int rowsNum = 3;
private int colsNum = 5;
/**
* 利用二維數組創建若干個游戲小方塊
*/
private ImageView[][] iv_game_arr;
/**
* 當前空方塊的實例
*/
private ImageView iv_null;
/**
* 游戲主界面
*/
private GridLayout gl_main_game;
/**
* 當前手勢
*/
private GestureDetector mDetector;
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return mDetector.onTouchEvent(event);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDetector = new GestureDetector(this, new OnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// TODO Auto-generated method stub
int dir = getDirByGes(e1.getX(), e1.getY(), e2.getX(), e2.getY());
// Toast.makeText(MainActivity.this, "" + dir, Toast.LENGTH_SHORT).show();
changeByDir(dir);
return false;
}
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
});
setContentView(R.layout.activity_main);
iv_game_arr = new ImageView[rowsNum][colsNum];
// Bitmap bigBm =(
// (BitmapDrawable)getResources().getDrawable(R.drawable.pic_1)).getBitmap();
// 獲取一張大圖
Bitmap bigBm = BitmapFactory.decodeResource(getResources(), R.drawable.pic_1);
// 計算每個小方塊的寬和高
int tuWandH = bigBm.getWidth() / colsNum;
// 初始化游戲小方塊
for (int i = 0; i < rowsNum; i++) {
for (int j = 0; j < colsNum; j++) {
Bitmap bm = Bitmap.createBitmap(bigBm, j * tuWandH, i * tuWandH, tuWandH, tuWandH);
iv_game_arr[i][j] = new ImageView(this);
iv_game_arr[i][j].setImageBitmap(bm);
// 設置方塊之間的間距
iv_game_arr[i][j].setPadding(2, 2, 2, 2);
// 綁定自定義的數據
iv_game_arr[i][j].setTag(new ImageViewData(i, j, bm));
iv_game_arr[i][j].setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
boolean flag = isNearByNull((ImageView) v);
// Toast.makeText(MainActivity.this, "" + flag,
// Toast.LENGTH_SHORT).show();
if (flag) {
changeDataByImageView((ImageView) v);
}
}
});
}
}
// 初始化游戲主界面,加載若干個小方塊
gl_main_game = (GridLayout) findViewById(R.id.gl_main_game);
for (int i = 0; i < rowsNum; i++) {
for (int j = 0; j < colsNum; j++) {
gl_main_game.addView(iv_game_arr[i][j]);
}
}
// 設置最后一個方塊為空
setNullImageView(iv_game_arr[rowsNum - 1][colsNum - 1]);
randomMove();
}
/**
* 根據手勢方向獲取與空方塊相鄰的位置,如果存在方塊就進行數據交換
*?
* @param dir
*/
public void changeByDir(int dir) {
// 獲取空方塊位置
ImageViewData data = (ImageViewData) iv_null.getTag();
// 根據手勢方向,設置相鄰位置坐標
int new_x = data.x;
int new_y = data.y;
if (dir == 1) {//
new_x++;
} else if (dir == 2) {
new_x--;
} else if (dir == 3) {
new_y++;
} else if (dir == 4) {
new_y--;
}
// Toast.makeText(MainActivity.this, data.x+" :: "+data.y,Toast.LENGTH_SHORT).show();
// 判斷新坐標是否存在
if (new_x >= 0 && new_x < rowsNum && new_y >= 0 && new_y < colsNum) {
// Toast.makeText(MainActivity.this, new_x+" : "+new_y,Toast.LENGTH_SHORT).show();
// 存在的話開始移動
changeDataByImageView(iv_game_arr[new_x][new_y]);
}
}
/**
* 手勢的判斷
*?
* @param sx
* @param sy
* @param ex
* @param ey
* @return 上下左右 1 2 3 4
*/
public int getDirByGes(float sx, float sy, float ex, float ey) {
// 左右:橫向距離大于豎直距離
boolean isLeftOrRight = Math.abs(sx - ex) > Math.abs(sy - ey);
if (isLeftOrRight) {// 左右
// 左 :終點x小于起點x
boolean isLeft = sx > ex;
if (isLeft) {
return 3;
} else {
return 4;
}
} else {// 上下
// 上:終點y大于起點y
boolean isUp = sy > ey;
if (isUp) {
return 1;
} else {
return 2;
}
}
}
//隨機打亂順序
public void randomMove(){
changeByDir(2);
// //打亂次數
// for (int i = 0; i < 3; i++) {
// int dir=(int)(Math.random()*4)+1;
// changeByDir(dir);
// }
// //開始交換,無動畫
}
/**
* 動畫結束后,交換兩個方塊的數據
*?
* @param mImageView
* ? ? ? ? ? ?點擊的方塊
*/
public void changeDataByImageView(final ImageView mImageView) {
ImageViewData nullD=(ImageViewData) iv_null.getTag();
ImageViewData mD=(ImageViewData) mImageView.getTag();
// Toast.makeText(MainActivity.this, nullD.x+" :.. "+mD.x, Toast.LENGTH_SHORT).show();
// Toast.makeText(MainActivity.this, nullD.y+" :.. "+mD.y, Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, mImageView.getX()+" :.. "+iv_null.getX(), Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, mImageView.getY()+" : "+iv_null.getY(), Toast.LENGTH_SHORT).show();
// 創建一個動畫,設置放心,移動距離
TranslateAnimation translateAnimation = null;
if (mImageView.getX() > iv_null.getX()) {// 在空方塊下面
// 往上移動
translateAnimation = new TranslateAnimation(0.1f, -mImageView.getWidth(), 0.1f, 0.1f);
} else if (mImageView.getX() < iv_null.getX()) {//
// 下
translateAnimation = new TranslateAnimation(0.1f, mImageView.getWidth(), 0.1f, 0.1f);
} else if (mImageView.getY() > iv_null.getY()) {//
// 左
translateAnimation = new TranslateAnimation(0.1f, 0.1f, 0.1f, -mImageView.getWidth());
} else if (mImageView.getY() < iv_null.getY()) {//
// 右
translateAnimation = new TranslateAnimation(0.1f, 0.1f, 0.1f, mImageView.getWidth());
}
translateAnimation = new TranslateAnimation(0.1f, mImageView.getWidth(), 0.1f, 0.1f);
// 設置動畫時長
translateAnimation.setDuration(70);
// 設置動畫結束后是否停留
translateAnimation.setFillAfter(true);
// 動畫結束后交換數據對象
translateAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mImageView.clearAnimation();
ImageViewData data1 = (ImageViewData) mImageView.getTag();
ImageViewData data2 = (ImageViewData) iv_null.getTag();
iv_null.setImageBitmap(data1.imageView);
data2.imageView = data1.imageView;
data2.p_x = data1.p_x;
data2.p_y = data2.p_y;
// 設置當前點擊的是空方塊
setNullImageView(mImageView);
}
});
mImageView.startAnimation(translateAnimation);
}
/**
* 設置某個方塊為空方塊
*?
* @param imageView
* ? ? ? ? ? ?當前需要設置為空的方塊實例
*/
public void setNullImageView(ImageView imageView) {
imageView.setImageBitmap(null);
iv_null = imageView;
}
/**
* 判斷點擊方塊是否和空方塊相鄰
*?
* @param imageView
* ? ? ? ? ? ?點擊的方塊
* @return true:相鄰,false:不相鄰
*/
public boolean isNearByNull(ImageView imageView) {
// 點擊方塊和當前空方塊的x或y只差一個單位就是相鄰
ImageViewData mNullImageViewData = (ImageViewData) iv_null.getTag();
ImageViewData mImageViewData = (ImageViewData) imageView.getTag();
if (mNullImageViewData.y == mImageViewData.y && mImageViewData.x + 1 == mNullImageViewData.x) {// 點擊方塊在空方塊上面
return true;
} else if (mNullImageViewData.y == mImageViewData.y && mImageViewData.x - 1 == mNullImageViewData.x) {// 點擊方塊在空方塊下面
return true;
} else if (mNullImageViewData.y == mImageViewData.y + 1 && mImageViewData.x == mNullImageViewData.x) {// 點擊方塊在空方塊左邊
return true;
} else if (mNullImageViewData.y == mImageViewData.y - 1 && mImageViewData.x == mNullImageViewData.x) {// 點擊方塊在空方塊右邊
return true;
}
return false;
}
/**
* 小方塊上綁定的數據
*/
class ImageViewData {
/** 小方塊的原始位置 **/
public int x = 0;
public int y = 0;
/** 小方塊的圖片 **/
public Bitmap imageView;
/** 小方塊的當前位置 **/
public int p_x;
public int p_y;
public ImageViewData(int x, int y, Bitmap imageView) {
super();
this.x = x;
this.y = y;
this.imageView = imageView;
this.p_x = x;
this.p_y = y;
}
}
}
2016-08-05
1、onCreate中的所有代碼及其子代碼執行完成之前,里面設置的所有View是獲取不到坐標的。
即:沒到運行狀態,view.getX()獲取不到,結果都是0。(如果debug會發現,在oncreate中,即使走過了代碼添加addView(),但此時界面并沒有繪制View)
所以要判斷,首次運行的時候,可以交換ImageView圖片方塊的內容,但是不能走動畫,因為動畫是通過getX()這種方法實現的。
我這邊設置的是isAnim變量,首次不加載動畫(達到了首次不會執行getX()這個效果)
2、發現一個bug,移動時的效果動畫都是從左向右的,需要去掉多余的代碼。
====================修改后如下=================
2016-10-21
<br>
2016-08-26
怎么發那么好看的代碼。。。