为了账号安全,请及时绑定邮箱和手机立即绑定

随机打乱顺序失败

打乱顺序的时候,我不能交换,用了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;

}


}


}



正在回答

3 回答

1、onCreate中的所有代码及其子代码执行完成之前,里面设置的所有View是获取不到坐标的。

即:没到运行状态,view.getX()获取不到,结果都是0。(如果debug会发现,在oncreate中,即使走过了代码添加addView(),但此时界面并没有绘制View)

所以要判断,首次运行的时候,可以交换ImageView图片方块的内容,但是不能走动画,因为动画是通过getX()这种方法实现的。

我这边设置的是isAnim变量,首次不加载动画(达到了首次不会执行getX()这个效果)

private boolean isAnim = false;
onCreate(){
   //……
   //随机打乱顺序,这时onCreate还没有执行完,getX()肯定是0,但是默认isAnim是false,可以直接交换。
   isAnim = false;//在整个onCreate最后写,已经过了首次,以后可以执行动画了
}
public void changeDataByImageView(final ImageView mImageView) {
		if(!isAnim){//不要执行动画,算是首次运行,直接开始交换
			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);
			return;
		}
		//……
}

2、发现一个bug,移动时的效果动画都是从左向右的,需要去掉多余的代码。

http://img1.sycdn.imooc.com//57a40b0f00016c6408400231.jpg

====================修改后如下=================

package com.charspan.pintu;

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 boolean isAnim = false;
	/**
	 * 利用二维数组创建若干个游戏小方块
	 */
	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();
		isAnim = true;
	}

	/**
	 * 根据手势方向获取与空方块相邻的位置,如果存在方块就进行数据交换
	 * 
	 * @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() {
		// 打乱次数
		for (int i = 0; i < 100; i++) {
			int dir = (int) (Math.random() * 4) + 1;
			changeByDir(dir);
		}
		// 开始交换,无动画
	}

	/**
	 * 动画结束后,交换两个方块的数据
	 * 
	 * @param mImageView
	 *            点击的方块
	 */
	public void changeDataByImageView(final ImageView mImageView) {
		if (!isAnim) {// 不要执行动画,算是首次运行,直接开始交换
			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);
			return;
		}
		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;
		}

	}

}


0 回复 有任何疑惑可以回复我~
#1

charspan 提问者

非常感谢!
2016-08-26 回复 有任何疑惑可以回复我~

<br>

0 回复 有任何疑惑可以回复我~

怎么发那么好看的代码。。。



0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

随机打乱顺序失败

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信