android拼图游戏
没劲1 人气:01.
2.
//使用回调接口,首先初始化pintuview并绑定,实现回调接口的方法 mPintuLayout = (PintuLayout) findViewById(R.id.mpintu); mPintuLayout.setOnGamePintuListener(new GamePintuListener() { @Override public void timechanged(int currentTime) { tvTime.setText(currentTime + ""); } @Override public void nextLevel(final int nextLevel) { mtvNextLevel.setVisibility(0); mPintuLayout.pause(); mPintuLayout.nextLevel(); level = nextLevel + ""; } @Override public void gameover() { mtvGameOver.setVisibility(0); } }); } @Override protected void onPause() { super.onPause(); mPintuLayout.pause(); } @Override protected void onResume() { super.onResume(); mPintuLayout.resume(); } // 设置按两次回退退出程序 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { exit(); Toast.makeText(getApplicationContext(), "再按一次则退出", Toast.LENGTH_SHORT).show(); return false; } return super.onKeyDown(keyCode, event); } private void exit() { if (!isExit) { isExit = true; myHandler.sendEmptyMessageDelayed(0, 2000); } else { finish(); } } Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); isExit = false; } }; //界面的点击事件 @Override public void onClick(View v) { switch (v.getId()) { case R.id.textView1: mPintuLayout.pause(); Toast.makeText(getApplicationContext(), "Pausing", Toast.LENGTH_SHORT).show(); mPintuLayout.setVisibility(4); miv.setVisibility(0); break; case R.id.textView2: mPintuLayout.resume(); Toast.makeText(getApplicationContext(), "Restarted", Toast.LENGTH_SHORT).show(); mPintuLayout.setVisibility(0); miv.setVisibility(4); break; case R.id.mtvGameOver: mtvGameOver.setVisibility(4); mPintuLayout.restart(); break; case R.id.mtvNextLevel: mtvNextLevel.setVisibility(4); tvLevel.setText("" + level); mPintuLayout.resume(); break; } }
3.每一小块退片的bean
public class ImagePieces { //小块图片的索引值 private int index; //整个一大块的图片载体 private Bitmap bitmap; public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public Bitmap getBitmap() { return bitmap; } public void setBitmap(Bitmap bitmap) { this.bitmap = bitmap; } //构造方法 public ImagePieces(int index, Bitmap bitmap) { super(); this.index = index; this.bitmap = bitmap; } public ImagePieces() { // TODO Auto-generated constructor stub } @Override public String toString() { return "ImagePieces [index=" + index + ", bitmap=" + bitmap + "]"; } }
4.图片分割类
public class ImageSplitterUtil { //pieces 为切成的块数,用list保存 public static List<ImagePieces> splitImage(Bitmap bitmap,int pieces){ List<ImagePieces> imagePieces = new ArrayList<ImagePieces>(); int width = bitmap.getWidth(); int height = bitmap.getHeight(); //去小的一方每一个快的宽度 int pieceWidth = Math.min(width,height)/pieces; for(int i=0;i<pieces;i++){ for(int j=0;j<pieces;j++){ ImagePieces imagepieces = new ImagePieces(); /* * 1+0 2+0 3+0 * 1+1 2+1 3+1 */ imagepieces.setIndex(j+i*pieces); int x = j*pieceWidth; int y = i*pieceWidth; //x,y是每一块的起点位置,piecewidth是每一块的长度和高度,这里弄成正方形 imagepieces.setBitmap(Bitmap.createBitmap(bitmap, x, y, pieceWidth, pieceWidth)); //所有操作setIndex setBitmap 然后把所有碎片按顺序加入list集合中 imagePieces.add(imagepieces); } } return imagePieces; } }
5.布局类
首先
private void init() { // 将margin的值的单位转为dp mMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics()); mPadding = min(getPaddingLeft(), getPaddingRight(), getPaddingTop(), getPaddingBottom()); }
其次onmeasure
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获得宽度和高度的最小值 mWidth = min(getMeasuredHeight(), getMeasuredWidth()); if (!once) { // 进行切图及排序 initBitmap(); // 设置imageview[item]的宽高等属性 initItem(); // 标识已画,防止再画 once = true; countTimeBaseLevel(); } // 宽度和高度的最小值设为宽高 setMeasuredDimension(mWidth, mWidth); }
其次
// 进行切图及排序 private void initBitmap() { if (mBitmap == null) { mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.psb); } mItemBitmaps = ImageSplitterUtil.splitImage(mBitmap, mColumn); // 是用sort把小块的图片乱序 Collections.sort(mItemBitmaps, new Comparator<ImagePieces>() { @Override public int compare(ImagePieces a, ImagePieces b) { return Math.random() > 0.5 ? 1 : -1; } }); }
private int mTime; // 相对关卡的时间数 private void countTimeBaseLevel() { mTime = (int) Math.pow(2, mLevel) * 30; mHandler.sendEmptyMessage(TIME_CHANGED); }
// 动画层的布局 private RelativeLayout mAnimaLayout; private boolean isAniming;
回调接口
public interface GamePintuListener { void nextLevel(int nextLevel); void timechanged(int currentTime); void gameover(); } public GamePintuListener mListener; // 设置接口回调 public void setOnGamePintuListener(GamePintuListener mListener) { this.mListener = mListener; }
游戏的进程控制,这里利用的是hangler
private static final int TIME_CHANGED = 0x110; public static final int NEXT_LEVEL = 0x111; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case TIME_CHANGED: if (isGameSuccess || isGameOver || isPausing) return; if (mListener != null) { mListener.timechanged(mTime); if (mTime == 0) { isGameOver = true; mListener.gameover(); return; } } mTime--; mHandler.sendEmptyMessageDelayed(TIME_CHANGED, 1000); break; case NEXT_LEVEL: mLevel = mLevel + 1; if (mListener != null) { mListener.nextLevel(mLevel); } else { nextLevel(); } break; } } };
重新开始游戏方法
public void restart() { isGameOver = false; mColumn--; nextLevel(); }
暂停和继续的方法
private boolean isPausing; public void pause() { isPausing = true; mHandler.removeMessages(TIME_CHANGED); } public void resume() { if (isPausing) { isPausing = false; mHandler.sendEmptyMessage(TIME_CHANGED); } } public void nextLevel() { this.removeAllViews(); mAnimaLayout = null; mColumn++; isGameSuccess = false; countTimeBaseLevel(); initBitmap(); initItem(); };
// 设置imageview[item]的宽高等属性 private void initItem() { // 把内边距和外面距剪掉除以列数就是每一块的宽度 mItemWidth = (mWidth - mPadding * 2 - mMargin * (mColumn - 1)) / mColumn; // item图片位置的初始化 mPintuItems = new ImageView[mColumn * mColumn]; // item图片的初始化 for (int i = 0; i < mPintuItems.length; i++) { ImageView item = new ImageView(getContext()); item.setOnClickListener(this); item.setImageBitmap(mItemBitmaps.get(i).getBitmap()); mPintuItems[i] = item; item.setId(i + 1); // 在item里面存放index,当拼图成功时候做为判断一句 item.setTag(i + "_" + mItemBitmaps.get(i).getIndex()); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( mItemWidth, mItemWidth); // 设置间隙 // 如果不是最后一列 if ((i + 1) % mColumn != 0) { lp.rightMargin = mMargin; } // 不是第一列 if (i % mColumn != 0) { lp.addRule(RelativeLayout.RIGHT_OF, mPintuItems[i - 1].getId()); } // 纵向间隙 // 如果不是第一行,设置topMargin和rule if ((i + 1) > mColumn) { lp.topMargin = mMargin; lp.addRule(RelativeLayout.BELOW, mPintuItems[i - mColumn].getId()); } addView(item, lp); } }
交换图片
private ImageView mFirst; private ImageView mSecond; @Override public void onClick(View v) { if (isAniming) return; if (mFirst == v) { mFirst.setColorFilter(null); mFirst = null; return; } if (mFirst == null) { mFirst = (ImageView) v; mFirst.setColorFilter(Color.parseColor("#45f0f0f0")); } else { mSecond = (ImageView) v; exchangView(); } }
交换图片的方法exchangeView方法的具体实现
// 交换image private void exchangView() { mFirst.setColorFilter(null); String firstTag = (String) mFirst.getTag(); String secondTag = (String) mSecond.getTag(); String[] firstParams = firstTag.split("_"); String[] secondParams = secondTag.split("_"); final Bitmap firstBitmap = mItemBitmaps.get( Integer.parseInt(firstParams[0])).getBitmap(); final Bitmap secondBitmap = mItemBitmaps.get( Integer.parseInt(secondParams[0])).getBitmap(); //设置动画层,下面有具体实现 setUpAnimLayout(); ImageView first = new ImageView(getContext()); first.setImageBitmap(firstBitmap); LayoutParams lp = new LayoutParams(mItemWidth, mItemWidth); lp.leftMargin = mFirst.getLeft() - mPadding; lp.topMargin = mFirst.getTop() - mPadding; first.setLayoutParams(lp); mAnimaLayout.addView(first); ImageView second = new ImageView(getContext()); second.setImageBitmap(secondBitmap); LayoutParams lp2 = new LayoutParams(mItemWidth, mItemWidth); lp2.leftMargin = mSecond.getLeft() - mPadding; lp2.topMargin = mSecond.getTop() - mPadding; second.setLayoutParams(lp2); mAnimaLayout.addView(second); // 设置动画 TranslateAnimation anim = new TranslateAnimation(0, mSecond.getLeft() - mFirst.getLeft(), 0, mSecond.getTop() - mFirst.getTop()); anim.setDuration(300); anim.setFillAfter(true); first.setAnimation(anim); TranslateAnimation anim2 = new TranslateAnimation(0, mFirst.getLeft() - mSecond.getLeft(), 0, mFirst.getTop() - mSecond.getTop()); anim2.setDuration(300); anim2.setFillAfter(true); second.setAnimation(anim2); anim.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation arg0) { mFirst.setVisibility(View.INVISIBLE); mSecond.setVisibility(View.INVISIBLE); isAniming = true; } @Override public void onAnimationRepeat(Animation arg0) { } @Override public void onAnimationEnd(Animation arg0) { mSecond.setImageBitmap(firstBitmap); mFirst.setImageBitmap(secondBitmap); String firstTag = (String) mFirst.getTag(); String secondTag = (String) mSecond.getTag(); mFirst.setTag(secondTag); mSecond.setTag(firstTag); mFirst.setVisibility(View.VISIBLE); mSecond.setVisibility(View.VISIBLE); mFirst = mSecond = null; mAnimaLayout.removeAllViews(); // 每次移动完成判断是否成功 checkSuccess(); isAniming = false; } private void checkSuccess() { boolean isSuccess = true; for (int i = 0; i < mPintuItems.length; i++) { ImageView imageview = mPintuItems[i]; String[] tag = imageview.getTag().toString().split("_"); if (Integer.parseInt(tag[1]) != i) { isSuccess = false; } } if (isSuccess) { isSuccess = true; mHandler.removeMessages(TIME_CHANGED); Toast.makeText(getContext(), "level up!", Toast.LENGTH_SHORT).show(); mHandler.sendEmptyMessage(NEXT_LEVEL); } } }); }
动画层的具体实现
private void setUpAnimLayout() { if (mAnimaLayout == null) { mAnimaLayout = new RelativeLayout(getContext()); addView(mAnimaLayout); } }
//获取多个参数的最少值作为内边距 private int min(int... params) { int min = params[0]; for (int param : params) { if (param < min) { min = param; } } return min; }
加载全部内容