本文实例为大家分享了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;
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

android实现简单拼图游戏的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  6. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

  7. Xamarin iOS图像在Grid内部重叠

    heyo,所以在Xamarin我有一个使用并在其中包含一对,所有这些都包含在内.这在Xamarin.Android中看起来完全没问题,但是在Xamarin.iOS中,图像与标签重叠.我不确定它的区别是什么–为什么它在Xamarin.Android中看起来不错但在iOS中它的全部都不稳定?

  8. 在iOS上向后播放HTML5视频

    我试图在iPad上反向播放HTML5视频.HTML5元素包括一个名为playbackRate的属性,它允许以更快或更慢的速率或相反的方式播放视频.根据Apple’sdocumentation,iOS不支持此属性.通过每秒多次设置currentTime属性,可以反复播放,而无需使用playbackRate.这种方法适用于桌面Safari,但似乎在iOS设备上的搜索限制为每秒1次更新–在我的情况下太慢了.有没有办法在iOS设备上向后播放HTML5视频?解决方法iOS6Safari现在支持playbackRat

  9. 使用 Swift 语言编写 Android 应用入门

    Swift标准库可以编译安卓armv7的内核,这使得可以在安卓移动设备上执行Swift语句代码。做梦,虽然Swift编译器可以胜任在安卓设备上编译Swift代码并运行。这需要的不仅仅是用Swift标准库编写一个APP,更多的是你需要一些框架来搭建你的应用用户界面,以上这些Swift标准库不能提供。简单来说,构建在安卓设备上使用的Swiftstdlib需要libiconv和libicu。通过命令行执行以下命令:gitclonegit@github.com:SwiftAndroid/libiconv-libi

  10. Android – 调用GONE然后VISIBLE使视图显示在错误的位置

    我有两个视图,A和B,视图A在视图B上方.当我以编程方式将视图A设置为GONE时,它将消失,并且它正下方的视图将转到视图A的位置.但是,当我再次将相同的视图设置为VISIBLE时,它会在视图B上显示.我不希望这样.我希望视图B回到原来的位置,这是我认为会发生的事情.我怎样才能做到这一点?编辑–代码}这里是XML:解决方法您可以尝试将两个视图放在RelativeLayout中并相对于彼此设置它们的位置.

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部