学习自慕课网,吐血一滩。。。
首先写布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <GridLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/gl_main_game" android:columnCount="5" android:rowCount="3" ></GridLayout> </RelativeLayout>
java文件
package com.example.move; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; 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.RelativeLayout; import android.widget.Toast; public class MainActivity extends Activity { private boolean isGameStart = false;//判断游戏是否开始 private ImageView[][] iv_game_arr = new ImageView[3][5];//利用二维数组创建方块 private GridLayout gl_main_game;//主页面 private ImageView ivImageView; private ImageView iv_null_ImageView;//当前空方块的实例的保存 private GestureDetector mDetector;//当前手势 private boolean isAnimRun= false;//当前动画是否在执行 //设置手势 @Override public boolean onTouchEvent(MotionEvent event) { return mDetector.onTouchEvent(event); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //设置监听器 mDetector = new GestureDetector(this,new OnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent arg0) { return false; } @Override public void onShowPress(MotionEvent arg0) { } @Override public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) { return false; } @Override public void onLongPress(MotionEvent arg0) { } @Override public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,float arg3) { int type = getDirByGes(arg0.getX(), arg0.getY(), arg1.getX(), arg1.getY()); // Toast.makeText(MainActivity.this, ""+type, Toast.LENGTH_SHORT).show();//测试显示一下 changeByDir(type);//传递方法 return false; } @Override public boolean onDown(MotionEvent arg0) { return false; } }); //初始化游戏小方块 Bitmap bigBm = ((BitmapDrawable)getResources().getDrawable(R.drawable.cg_3)).getBitmap();//获取一张大图 int tuWandH = bigBm.getWidth()/5;//每个小方块的宽和高 int ivWandH = getWindowManager().getDefaultDisplay().getWidth()/5;//小方块宽应为整个屏幕/5 for (int i = 0; i < iv_game_arr.length; i++) { for (int j = 0; j < iv_game_arr[0].length; 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].setLayoutParams(new RelativeLayout.LayoutParams(ivWandH,ivWandH)); iv_game_arr[i][j].setPadding(2, 2, 2, 2);//设置方块间距 iv_game_arr[i][j].setTag(new GameData(i, j, bm));//绑定自定义数据 iv_game_arr[i][j].setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { boolean flag = isHasByNullImageView((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 < iv_game_arr.length; i++) { for (int j = 0; j < iv_game_arr[0].length; j++) { gl_main_game.addView(iv_game_arr[i][j]); } } setNullImageView(iv_game_arr[2][4]);//设置最后一个方块是空的 randomMove();//初始化随机打乱顺序 isGameStart = true;//开始游戏状态 } //重载,由于开始100次随即无动画 public void changeByDir(int type){ changeByDir(type,true); } //根据手势方向获取空方块相邻位置,存在方块,进行数据交换,1up,2down,3left,4right public void changeByDir(int type,boolean isAnim){ GameData mNullGameData=(GameData) iv_null_ImageView.getTag();//获取当前空方块位置 int new_x=mNullGameData.x;//根据方向设置相应位置坐标 int new_y=mNullGameData.y; if (type==1) {//要移动的方块在空的下面 new_x++; }else if (type==2) { new_x--; }else if (type==3) { new_y++; }else if (type==4) { new_y--; } //判断新坐标是否存在 if(new_x>=0&&new_x<iv_game_arr.length&&new_y>=0&&new_y<iv_game_arr[0].length){ if (isAnim) { changeDataByImageView(iv_game_arr[new_x][new_y]);//存在,移动 }else {//无动画 changeDataByImageView(iv_game_arr[new_x][new_y],isAnim); } }else { //不用做什么 } } //判断游戏结束方法 public void isGameOver(){ boolean isGameOver = true; //遍历每个游戏方块 for (int i = 0; i < iv_game_arr.length; i++) { for (int j = 0; j < iv_game_arr[0].length; j++) { //为空的方块数据跳过 if (iv_game_arr[i][j]==iv_null_ImageView) { continue; } GameData mGameData=(GameData) iv_game_arr[i][j].getTag(); if(!mGameData.isTrue()){ isGameOver = false; break; } } } //根据一个开关变量决定是否结束 if (isGameOver) { Toast.makeText(this, "congrdulation", Toast.LENGTH_SHORT).show(); } } //手势判断 public int getDirByGes(float start_x,float start_y,float end_x,float end_y){ boolean isLeftOrRight=(Math.abs(start_x-end_x)>Math.abs(start_y-end_y))?true:false;//是否是左右 if(isLeftOrRight){//左右 boolean isLeft = start_x-end_x>0?true:false; if(isLeft){ return 3; }else{ return 4; } }else{//上下 boolean isUp = start_y-end_y>0?true:false; if(isUp){ return 1; }else{ return 2; } } //1up,2down,3left,4right } //随即打乱顺序 public void randomMove(){ //打乱次数 for (int i = 0; i < 100; i++) { //开始交换,无动画 int type = (int) (Math.random()*4)+1; changeByDir(type,false); } } public void changeDataByImageView(final ImageView miImageView){//重载有动画 changeDataByImageView(miImageView,true); } //利用动画结束之后,交换两个方块数据 public void changeDataByImageView(final ImageView miImageView,boolean isAnim){//这里手滑多打一个i..... if (isAnimRun) { return; } if(!isAnim){ GameData mGameData = (GameData) miImageView.getTag(); iv_null_ImageView.setImageBitmap(mGameData.bm); GameData mNullGameData = (GameData) iv_null_ImageView.getTag(); mNullGameData.bm = mGameData.bm; mNullGameData.p_x = mGameData.p_x; mNullGameData.p_y = mGameData.p_y; setNullImageView(miImageView);//设置当前点击的为空方块 if(isGameStart){ isGameOver();//成功时,弹出一个toast } return; } TranslateAnimation translateAnimation=null;//创建一个动画,设置方向,移动距离 if(miImageView.getX()>iv_null_ImageView.getX()){//当前点击在空之上 translateAnimation = new TranslateAnimation(0.1f, -miImageView.getWidth(),0.1f,0.1f);//向上移动 }else if(miImageView.getX()<iv_null_ImageView.getX()){ translateAnimation = new TranslateAnimation(0.1f, miImageView.getWidth(),0.1f,0.1f);//向下移动 }else if(miImageView.getY()>iv_null_ImageView.getY()){ translateAnimation = new TranslateAnimation(0.1f, 0.1f,-miImageView.getWidth(),0.1f);//向左移动 }else if(miImageView.getY()<iv_null_ImageView.getY()){ translateAnimation = new TranslateAnimation(0.1f, 0.1f,miImageView.getWidth(),0.1f);//向右移动 } translateAnimation.setDuration(50);//设置动画时常,ms translateAnimation.setFillAfter(true);//设置动画结束之后是否停留 //设置动画结束之后真正交换数据 translateAnimation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { isAnimRun = true; } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { isAnimRun = false; miImageView.clearAnimation(); GameData mGameData = (GameData) miImageView.getTag(); iv_null_ImageView.setImageBitmap(mGameData.bm); GameData mNullGameData = (GameData) iv_null_ImageView.getTag(); mNullGameData.bm = mGameData.bm; mNullGameData.p_x = mGameData.p_x; mNullGameData.p_y = mGameData.p_y; setNullImageView(miImageView);//设置当前点击的为空方块 if(isGameStart){ isGameOver(); } } }); miImageView.startAnimation(translateAnimation);//执行动画 } //设置空方块,mImageView是当前设置为空方块的实例 public void setNullImageView(ImageView mImageView){ mImageView.setImageBitmap(null); iv_null_ImageView = mImageView; } //判断当前点击的是否是空方块位置为相邻关系,mImageView所点击的方块 public boolean isHasByNullImageView(ImageView mImageView){ //分别获取当前空方块的位置与点击方块的位置 GameData mNullGameData=(GameData) iv_null_ImageView.getTag(); GameData mGameData=(GameData)mImageView.getTag(); if(mNullGameData.y==mGameData.y&&mNullGameData.x+1==mGameData.x){//当前点击方块在空方块上面 return true; }else if(mNullGameData.y==mGameData.y&&mNullGameData.x-1==mGameData.x){//当前点击方块在空方块下面 return true; }else if(mNullGameData.y==mGameData.y+1&&mNullGameData.x==mGameData.x){//当前点击方块在空方块左面 return true; }else if(mNullGameData.y==mGameData.y-1&&mNullGameData.x==mGameData.x){//当前点击方块在空方块右面 return true; } return false; } //小方块的监测数据 class GameData{ public int x=0;//方块位置x public int y=0;//方块位置y public Bitmap bm;//方块图片 public int p_x;//图片位置x public int p_y;//图片位置y public GameData(int x, int y, Bitmap bm) { super(); this.x = x; this.y = y; this.bm = bm; this.p_x = x; this.p_y = y; } //方块的位置是否正确 public boolean isTrue() { if (x==p_x&&y==p_y) { return true; } return false; } } }
好长的说。。。注释很全的说。。。