MainActivity.java
package com.adolph.pingtu;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import com.adolph.pingtu.com.adolph.pinhtu.view.GamePingtuLayout;
public class MainActivity extends AppCompatActivity {
private GamePingtuLayout gamePingtuLayout;
private TextView mLevel;
private TextView mTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLevel= (TextView) findViewById(R.id.id_level);
mTime = (TextView) findViewById(R.id.id_time);
gamePingtuLayout = (GamePingtuLayout) findViewById(R.id.id_GamePintu);
gamePingtuLayout.setTimeEnabled(true);
gamePingtuLayout.setOnGamePintuListener(new GamePingtuLayout.GamePintuListener() {
@Override
public void nextLevel(final int nextLevel) {
new AlertDialog.Builder(MainActivity.this).setTitle("Game Info")
.setMessage("LEVEL UP!!!").setPositiveButton("NEXT LEVEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
gamePingtuLayout.nextLevel();
mLevel.setText(""+nextLevel);
}
}).show();
}
@Override
public void timechanged(int currentTime) {
mTime.setText(""+currentTime);
}
@Override
public void gameover() {
new AlertDialog.Builder(MainActivity.this).setTitle("Game Info")
.setMessage("Game over!!!")
.setPositiveButton("RESTART", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
gamePingtuLayout.restart();
}
}).setNegativeButton("QUIT", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).show();
}
});
}
protected void onPause(){
super.onPause();
gamePingtuLayout.pause();
}
protected void onResume(){
super.onResume();
gamePingtuLayout.resume();
}
}
ImageSplitterUyil.java
package com.adolph.pingtu.com.adolph.pingpu.utils;
import android.graphics.Bitmap;
import java.util.ArrayList;
import java.util.List;
/**
* 传入bitmap 切成piece快 返回List<>
* Created by Administrator on 2016/10/18.
*/
public class ImageSplitterUtil {
//mpiece:指定切多少块
public static List<ImagePiece> splitImage(Bitmap bitmap,int piece ){
List<ImagePiece> imagePieces = new ArrayList<>();
//得到图片的宽高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
//得到每一小块的宽度
int pieceWidth = Math.min(width,height)/piece;
//切图
for (int i=0; i<piece; i++)
{
for (int j=0; j<piece; j++)
{
ImagePiece imagePiece = new ImagePiece();
imagePiece.setIndex(j+i*piece);
int x = j*pieceWidth;
int y = i*pieceWidth;
imagePiece.setBitmap(Bitmap.createBitmap(bitmap,x,y,
pieceWidth,pieceWidth));
//将切好的图片保存到List中
imagePieces.add(imagePiece);
}
}
return imagePieces;
}
}
GamePingtuLayout.java
package com.adolph.pingtu.com.adolph.pinhtu.view;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Handler;
import android.util.AttributeSet;
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 com.adolph.pingtu.R;
import com.adolph.pingtu.com.adolph.pingpu.utils.ImagePiece;
import com.adolph.pingtu.com.adolph.pingpu.utils.ImageSplitterUtil;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.LogRecord;
/**
* Created by Administrator on 2016/10/19.
*/
public class GamePingtuLayout extends RelativeLayout implements View.OnClickListener {
//几乘几的
private int mColum;
//容器的内边距
private int mPading;
//每张小图之间的距离
private int mMargin =3;
//存储ImageView
private ImageView[] mGamePintuItems;
//图片的宽
private int mItemWidth;
//游戏的图片
private Bitmap mBitmap;
private List<ImagePiece> mItemBitmaps;
private boolean once;
//容器的宽度
private int mWidth;
private boolean isGameSuccess;
private boolean isGameOver;
//定义接口
public interface GamePintuListener{
void nextLevel(int nextLevel);
void timechanged(int currentTime);
void gameover();
}
public GamePintuListener mListener;
//设置接口回调
public void setOnGamePintuListener(GamePintuListener mListener){
this.mListener = mListener;
}
private int level =1;
private static final int TIME_CHANGED =0x110;
private 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 || isPause){
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:
level = level+1;
if (mListener != null){
mListener.nextLevel(level);
}else {
nextLevel();
}
break;
}
};
};
private boolean isTimeEnabled = false;
private int mTime;
//设置是否开启时间
public void setTimeEnabled(boolean isTimeEnabled){
this.isTimeEnabled = isTimeEnabled;
}
public GamePingtuLayout(Context context) {
this(context,null);
}
public GamePingtuLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public GamePingtuLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
mColum = 3;
}
private void init() {
//将dp转化为px
mMargin = (int)TypedValue.applyDimension
(TypedValue.COMPLEX_UNIT_DIP,3,getResources().getDisplayMetrics());
mPading = min(getPaddingLeft(),getPaddingRight(),getPaddingBottom(),getPaddingTop());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//取宽和高的最小值作为容器的宽度
mWidth = Math.min(getMeasuredHeight(),getMeasuredWidth());
if (!once){
//进行切图和排序
initBittmap();
//设置图片的宽高
initItem();
//判断是否开启时间
checkTimeEnable();
once = true;
}
setMeasuredDimension(mWidth,mWidth);
}
private void checkTimeEnable() {
if (isTimeEnabled){
//根据当前等级设置时间
countTimeBaseLevel();
mHandler.sendEmptyMessage(TIME_CHANGED);
}
}
private void countTimeBaseLevel() {
mTime = (int) Math.pow(2,level)*60;
}
//
private void initItem() {
//得到每个小图的宽度
mItemWidth = (mWidth - mPading*2-mMargin*(mColum-1))/mColum;
mGamePintuItems = new ImageView[mColum*mColum];
//生成Item 设置rule
for (int i=0; i < mGamePintuItems.length; i++){
ImageView item = new ImageView(getContext());
item.setOnClickListener(this);
//为Item设置图片
item.setImageBitmap(mItemBitmaps.get(i).getBitmap());
mGamePintuItems[i]=item;
item.setId(i+1);
//在Item的tag中存储index
item.setTag(i+"_"+mItemBitmaps.get(i).getIndex());
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mItemWidth,mItemWidth);
//设置item间横向间隙,通过rightMarage
//不是最后一列
if ((i+1)% mColum !=0){
// lp.rightMargin =mMargin;
lp.rightMargin = mMargin;
}
//不是第一行
if (i % mColum !=0){
lp.addRule(RelativeLayout.RIGHT_OF,
mGamePintuItems[i-1].getId());
}
//不是第一行
if ((i+1) >mColum){
lp.topMargin = mMargin;
lp.addRule(RelativeLayout.BELOW,mGamePintuItems[i-mColum].getId());
}
addView(item,lp);
}
}
//得到图片
private void initBittmap() {
if (mBitmap == null){
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
}
mItemBitmaps = ImageSplitterUtil.splitImage(mBitmap,mColum);
//将数组进行乱序排序
Collections.sort(mItemBitmaps, new Comparator<ImagePiece>() {
@Override
public int compare(ImagePiece lhs, ImagePiece rhs) {
//通过产生随机数,随机排序
return Math.random()>0.5?1:-1;
}
});
}
//重新开始
public void restart(){
isGameOver = false;
mColum--;
nextLevel();
}
private boolean isPause;
//暂停
public void pause(){
isPause = true;
mHandler.removeMessages(TIME_CHANGED);
}
//恢复
public void resume(){
if (isPause){
isPause = false;
mHandler.sendEmptyMessage(TIME_CHANGED);
}
}
public void nextLevel(){
this.removeAllViews();
mAnimLayout = null;
mColum++;
isGameSuccess = false;
checkTimeEnable();
initBittmap();
initItem();
}
/*获取多个参数的最小值
* 使用可变参数,int...params
* 无论传入几个值都可以
* */
private int min(int...params) {
int min = params[0];
for (int i=1; i<params.length; i++){
if (params[i]<min) min = params[i];
}
return min;
}
//响应点击事件的图片
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("#55FF0000"));
}else {
mSecond = (ImageView)v;
//改变两张图片的位置
exchangeView();
}
}
/*
* 动画层
* */
private RelativeLayout mAnimLayout;
private boolean isAniming;
//改变两张图片的位置
private void exchangeView() {
mFirst.setColorFilter(null);
//构造动画层
setUpAnimLayout();
final ImageView first = new ImageView(getContext());
final Bitmap firstBitmap = mItemBitmaps.get(
getImageIdByTag((String)mFirst.getTag())).getBitmap();
first.setImageBitmap(firstBitmap);
LayoutParams lp = new LayoutParams(mItemWidth,mItemWidth);
lp.leftMargin = mFirst.getLeft() - mPading;
lp.topMargin = mFirst.getTop() -mPading;
first.setLayoutParams(lp);
mAnimLayout.addView(first);
ImageView second = new ImageView(getContext());
final Bitmap secondBitmap = mItemBitmaps.get(getImageIdByTag((String)mSecond.getTag())).getBitmap();
second.setImageBitmap(secondBitmap);
LayoutParams lp2 = new LayoutParams(mItemWidth,mItemWidth);
lp2.leftMargin = mSecond.getLeft() - mPading;
lp2.topMargin = mSecond.getTop() -mPading;
second.setLayoutParams(lp2);
mAnimLayout.addView(second);
//设置动画
TranslateAnimation anim = new TranslateAnimation(0,mSecond.getLeft()
-mFirst.getLeft(),0,mSecond.getTop()-mFirst.getTop());
anim.setDuration(300);
anim.setFillAfter(true);
first.startAnimation(anim);
TranslateAnimation animSecond = new TranslateAnimation(0,-mSecond.getLeft()
+mFirst.getLeft(),0,-mSecond.getTop()+mFirst.getTop());
animSecond.setDuration(300);
animSecond.setFillAfter(true);
second.startAnimation(animSecond);
//动画监听
anim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//隐藏图片
mFirst.setVisibility(View.INVISIBLE);
mSecond.setVisibility(View.INVISIBLE);
isAniming =true;
}
@Override
public void onAnimationEnd(Animation animation) {
String firstTag = (String)mFirst.getTag();
String secondTag = (String)mSecond.getTag();
mFirst.setImageBitmap(secondBitmap);
mSecond.setImageBitmap(firstBitmap);
mFirst.setTag(secondTag);
mSecond.setTag(firstTag);
//显示图片
mFirst.setVisibility(View.VISIBLE);
mSecond.setVisibility(View.VISIBLE);
mFirst = mSecond = null;
mAnimLayout.removeAllViews();
checkSuccess();
isAniming = false;
}
//判断游戏是否成功
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
//判断游戏是否成功
private void checkSuccess() {
boolean isSuccess = true;
for (int i=0; i<mGamePintuItems.length; i++){
ImageView imageView = mGamePintuItems[i];
if (getImageIndex((String)imageView.getTag()) != i){
isSuccess = false;
}
}
//成功
if (isSuccess){
isSuccess = true;
mHandler.removeMessages(TIME_CHANGED);
Toast.makeText(getContext(),"Success,level up",Toast.LENGTH_LONG).show();
mHandler.sendEmptyMessage(NEXT_LEVEL);
}
}
//根据tag获取id
public int getImageIdByTag(String tag){
String[] split = tag.split("_");
return Integer.parseInt(split[0]);
}
public int getImageIndex(String tag){
String[] split = tag.split("_");
return Integer.parseInt(split[1]);
}
//构造动画层
private void setUpAnimLayout() {
if (mAnimLayout == null){
mAnimLayout = new RelativeLayout(getContext());
//将动画层添加到控制面板
addView(mAnimLayout);
}
}
}
package com.adolph.pingtu.com.adolph.pingpu.utils;
import android.graphics.Bitmap;
/**
* Created by Administrator on 2016/10/18.
*/
public class ImagePiece {
//作用:存储游戏中每个小块图片
private int index;//记录每个小块的id
private Bitmap bitmap;
public int getIndex() {
return index;
}
public Bitmap getBitmap() {
return this.bitmap;
}
public void setIndex(int index) {
this.index = index;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public ImagePiece()
{
this.index = index;
this.bitmap = bitmap;
}
@Override
public String toString() {
return "ImagePiece{" +
"index=" + index +
", bitmap=" + bitmap +
'}';
}
}