小编给大家分享一下android如何实现简单拼图游戏,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
具体内容如下
1.
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;
}
看完了这篇文章,相信你对“android如何实现简单拼图游戏”有了一定的了解,如果想了解更多相关知识,欢迎关注天达云行业资讯频道,感谢各位的阅读!