android-拼图小游戏

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);
        }
    }
}


ImagePiece.java

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 +
                '}';
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值