随机打乱顺序失败

来源:2-6 随机打乱顺序

charspan

2016-08-05 08:26

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

  • 阿旭_
    2016-08-05 11:44:12
    已采纳

    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://img.mukewang.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;
    		}
    
    	}
    
    }


    charsp...

    非常感谢!

    2016-08-26 08:34:28

    共 1 条回复 >

  • 慕粉4140763
    2016-10-21 17:08:52

    <br>

  • charspan
    2016-08-26 08:34:59

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



快速实现不一样的移动拼图

实现一个支持手势的移动拼图小游戏,手把手带你开发小游戏

15576 学习 · 67 问题

查看课程

相似问题