贴一下效果图
接下来随便用一张图片就好
以下是全代码
自定义View
GameView类
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Toast; import java.util.Collections; import java.util.Comparator; import java.util.List; public class GameView extends RelativeLayout implements View.OnClickListener { //默认3*3 private int mColumn = 3; //容器的内边距 private int mPadding; //小图的距离 dp private int mMagin = 3; //存储图片的,宽高 都是固定的,所以使用数组 private ImageView[] mGameOintuItems; //宽度 private int mItemWidth; //图片 private Bitmap mBitmap; //切图后存储 private List<ImagePiece> mItemBitmaps; //标记 private boolean once; //记录时间 private int mTime; //容器的一个宽度 private int mWidth; //判断游戏是否成功 private boolean isGameSuccess; //是否显示时间 private boolean isTimeEnabled = false; /** * 动画层,覆盖在viewGroup中 */ private RelativeLayout mAnimLayout; private boolean isGameOver; /** * 动画限制 */ private boolean isAniming; private static final int TIME_CHANGED = 10; private static final int NEXT_LEVEL = 11; /** * 设置接口回调 * * @param mListener */ public void setOnGamemListener(GamePintuListener mListener) { this.mListener = mListener; } public GamePintuListener mListener; /** * 关数 */ private int level = 1; /** * 设置开启时间 * * @param timeEnabled */ public void setTimeEnabled(boolean timeEnabled) { isTimeEnabled = timeEnabled; } //接口 public interface GamePintuListener { //关卡 void nextLevel(int nextLevel); //时间 void timechanged(int time); //游戏结束 void gameOver(); } //子线程操作 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case TIME_CHANGED: if (isGameSuccess || isGameOver || isPause) { return; } if (mListener != null) { mListener.timechanged(mTime); if (mTime == 0) { isGameOver = true; mListener.gameOver(); return; } } mTime--; handler.sendEmptyMessageDelayed(TIME_CHANGED, 1000); break; case NEXT_LEVEL: level = level + 1; if (mListener != null) { mListener.nextLevel(level); } else { nextLevel(); } break; } super.handleMessage(msg); } }; public GameView(Context context) { this(context, null); } public GameView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public GameView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } /** * 初始化 */ private void init() { //单位转换——dp-px mMagin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics());