android實現(xiàn)簡單拼圖游戲
本文實例為大家分享了android實現(xiàn)簡單拼圖游戲的具體代碼,供大家參考,具體內(nèi)容如下
1.
2.
//使用回調(diào)接口,首先初始化pintuview并綁定,實現(xiàn)回調(diào)接口的方法 ? ? 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(); ? ? } // 設(shè)置按兩次回退退出程序 ? ? @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; ? ? } ?? ? ? //構(gòu)造方法 ? ? 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 為切成的塊數(shù),用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的值的單位轉(zhuǎn)為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(); ? ? ? ? ? ? // 設(shè)置imageview[item]的寬高等屬性 ? ? ? ? ? ? initItem(); ? ? ? ? ? ? // 標(biāo)識已畫,防止再畫 ? ? ? ? ? ? once = true; ? ? ? ? ? ? countTimeBaseLevel(); ? ? ? ? } ? ? ? ? // 寬度和高度的最小值設(shè)為寬高 ? ? ? ? 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; ? ? // 相對關(guān)卡的時間數(shù) ? ? private void countTimeBaseLevel() { ? ? ? ? mTime = (int) Math.pow(2, mLevel) * 30; ? ? ? ? mHandler.sendEmptyMessage(TIME_CHANGED); ? ? }
// 動畫層的布局 private RelativeLayout mAnimaLayout; private boolean isAniming;
回調(diào)接口
public interface GamePintuListener { ? ? ? ? void nextLevel(int nextLevel); ? ? ? ? void timechanged(int currentTime); ? ? ? ? void gameover(); ? ? } ? ? public GamePintuListener mListener; ? ? // 設(shè)置接口回調(diào) ? ? 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(); ? ? }
暫停和繼續(xù)的方法
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(); ? ? };
// 設(shè)置imageview[item]的寬高等屬性 ? ? private void initItem() { ? ? ? ? // 把內(nèi)邊距和外面距剪掉除以列數(shù)就是每一塊的寬度 ? ? ? ? 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,當(dāng)拼圖成功時候做為判斷一句 ? ? ? ? ? ? item.setTag(i + "_" + mItemBitmaps.get(i).getIndex()); ? ? ? ? ? ? RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( ? ? ? ? ? ? ? ? ? ? mItemWidth, mItemWidth); ? ? ? ? ? ? // 設(shè)置間隙 ? ? ? ? ? ? // 如果不是最后一列 ? ? ? ? ? ? if ((i + 1) % mColumn != 0) { ? ? ? ? ? ? ? ? lp.rightMargin = mMargin; ? ? ? ? ? ? } ? ? ? ? ? ? // 不是第一列 ? ? ? ? ? ? if (i % mColumn != 0) { ? ? ? ? ? ? ? ? lp.addRule(RelativeLayout.RIGHT_OF, mPintuItems[i - 1].getId()); ? ? ? ? ? ? } ? ? ? ? ? ? // 縱向間隙 ? ? ? ? ? ? // 如果不是第一行,設(shè)置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方法的具體實現(xiàn)
// 交換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(); ? ? ? ? //設(shè)置動畫層,下面有具體實現(xiàn) ? ? ? ? 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); ? ? ? ? // 設(shè)置動畫 ? ? ? ? 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); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }); ? ? }
動畫層的具體實現(xiàn)
private void setUpAnimLayout() { ? if (mAnimaLayout == null) { ? ? ? ? ? ? mAnimaLayout = new RelativeLayout(getContext()); ? ? ? ? ? ? addView(mAnimaLayout); ? ? ? ? } ? ? }
//獲取多個參數(shù)的最少值作為內(nèi)邊距 private int min(int... params) { ? ? ? ? int min = params[0]; ? ? ? ? for (int param : params) { ? ? ? ? ? ? if (param < min) { ? ? ? ? ? ? ? ? min = param; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return min; ? ? }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android?SharedPreferences性能瓶頸解析
這篇文章主要為大家介紹了Android?SharedPreferences性能瓶頸解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02android使用include調(diào)用內(nèi)部組件的方法
這篇文章主要介紹了android使用include調(diào)用內(nèi)部組件的方法,涉及Android組件調(diào)用的相關(guān)技巧,需要的朋友可以參考下2015-05-05Android SharedPreferences四種操作模式使用詳解
這篇文章主要介紹了Android SharedPreferences四種操作模式使用詳解的相關(guān)資料,這里介紹了獲取Android SharedPreferences的兩種方法及比較,和操作模式的介紹,需要的朋友可以參考下2017-07-07Android利用BitMap獲得圖片像素數(shù)據(jù)的方法
這篇文章主要介紹了Android利用BitMap獲得圖片像素數(shù)據(jù)的方法,結(jié)合實例對比分析了Android獲取圖片像素數(shù)據(jù)的相關(guān)技巧,需要的朋友可以參考下2016-02-02