GamePinTu
package com.example.administrator.pintu; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast; import java.util.Collections;
import java.util.Comparator;
import java.util.List; /**
* Created by Zyh on 2016/11/22.
*/
public class GamePinTuLayout extends RelativeLayout implements View.OnClickListener {
//拼图layout的宽度,游戏面板的宽度
private int mWidth;
//面板内边距
private int mPadding;
//piece图片的间距
private int mMargin; public GamePinTuLayout(Context context) {
this(context, null);
} public GamePinTuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// //设置背景图片
// setBackgroundResource(R.mipmap.chazhuo);
mPadding = min(getPaddingLeft(), getPaddingRight(), getPaddingTop(), getPaddingBottom());
//安卓里面的单位:dip、dp、px、sp
mMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics());
} private boolean once = true; @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//设置面板的宽度
mWidth = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
//切图乱序,调试间距,将乱序后的imagepiece集合加入面板
if (once) {
initBitmap();
initItem();
}
setMeasuredDimension(mWidth, mWidth);
}
private int mItemWidth;
/**
* 1.重新规定imageView的宽高
* 2.位置需要手动规定
*/
private ImageView[] mGamePinTuItems;
private void initItem() {
// //容器我们可以直接使用addView方法将一个view加入容器中
// ImageView item=new ImageView(getContext());
// item.setImageBitmap(mItemBitmap.get(0).bitmap);
// addView(item);
/**
* mWidth游戏面板宽度,面板宽度mPadding,内容边距mMargin
* RelativeLayout.LayoutParams--规定加入控件的宽高和位置属性(addRule);
*
*/
RelativeLayout.LayoutParams lp;
mItemWidth=(mWidth-mPadding*2-mMargin*(mPiece-1))/mPiece;
mGamePinTuItems=new ImageView[mPiece*mPiece];
ImagePiece imagePiece;
//当前布局是相对布局
for (int i=0;i<mItemBitmap.size();i++){
imagePiece=mItemBitmap.get(i);
ImageView item=new ImageView(getContext());
item.setImageBitmap(imagePiece.bitmap);
item.setOnClickListener(this);
mGamePinTuItems[i]=item;
//设置一个tag标签,在做切换的时候拿到bitmap
//i是为了方便,我们位置交换的时候拿到bitmap,imagePiece.index是为了判断游戏是否结束
item.setTag(i+"_"+imagePiece.index);
//设置imageView的id,为设置位置做准备
item.setId(i+1);
//规定宽高
lp=new RelativeLayout.LayoutParams(mItemWidth,mItemWidth);
//定位,
//首先不是第一列的判断,全部都要写在谁的右边
if (i%mPiece!=0){
lp.addRule(RelativeLayout.RIGHT_OF,mGamePinTuItems[i-1].getId());
lp.leftMargin=mMargin;
}
//不是第一行的判断,全部需要写在谁的下边
if (i>=mPiece){
lp.addRule(RelativeLayout.BELOW,mGamePinTuItems[i-mPiece].getId());
lp.topMargin=mMargin;
}
addView(item,lp);
}
}
List<ImagePiece> mItemBitmap;
//游戏的图片
private Bitmap mBitmap;
private int mPiece=3;
private void initBitmap() {
if (mBitmap==null){
//从资源文件中取出图片并且转成bitmap图片
mBitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.chazhuo);
}
//分割图片
mItemBitmap=ImageSplitterUtils.splitImage(mBitmap,mPiece);
//通过Collections可以帮助我们完成乱序,sort进行,它里面有两个参数,排序集合排序规则
Collections.sort(mItemBitmap, new Comparator<ImagePiece>() {
@Override
public int compare(ImagePiece imagePiece, ImagePiece t1) {
//随机返回1或者-1,达到乱序的效果,
return Math.random()>0.5?1:-1;
// Math.random();--生成随机数,返回值是double,范围是0.0-1.0
}
});
} /**
* 可变参数的写法:int...params
* 那么params他就是一个参数数组,这里规定他的类型就是一个int型的
*
* @return
*/
private int min(int... params) {
int min = params[0];
for (int param : params) {
if (min > param) {
min = param;
}
}
return min;
}
private ImageView mFirstIv;
private ImageView mSecondIv;
@Override
public void onClick(View view) {
//点击事件
// Toast.makeText(getContext(), "----"+view.getId(), Toast.LENGTH_SHORT).show();
if (mFirstIv==null){
mFirstIv= (ImageView) view;
//color.red getColor方法获取资源文件color 十六进制的写法 Color.parseColor("#0000000")
mFirstIv.setColorFilter(Color.parseColor("#55ff0000"));
}else if (mFirstIv==view){
mFirstIv.setColorFilter(null);
mFirstIv=null;
}else {
//发生交换
mSecondIv= (ImageView) view;
exchangeView();
} }
private Bitmap mFirstBitmap,mSecondBitmap;
/**
* 作交换,做动画
*/
private void exchangeView() {
mFirstIv.setColorFilter(null);
String firstTag=mFirstIv.getTag().toString();
String secondTag=mSecondIv.getTag().toString();
mFirstBitmap=mItemBitmap.get(getImageIdByTag(mFirstIv.getTag().toString())).bitmap;
mSecondBitmap=mItemBitmap.get(getImageIdByTag(mSecondIv.getTag().toString())).bitmap;
//交换bitmap,并且交换tag
mFirstIv.setImageBitmap(mSecondBitmap);
mSecondIv.setImageBitmap(mFirstBitmap);
mFirstIv.setTag(secondTag);
mSecondIv.setTag(firstTag);
mFirstIv=mSecondIv=null;
checkGameOver();
} private void checkGameOver() {
boolean isOver=true;
for (int i=0;i<mGamePinTuItems.length;i++){
ImageView iv=mGamePinTuItems[i];
//拿到当前位置的index,判断游戏结束
int index=getImageIndexByTag(iv.getTag().toString());
if (index!=i){
//表示游戏继续进行
isOver=false;
break;
}
if (isOver){
String msg="game over,you win!";
Toast.makeText(getContext(), "game over,you win!", Toast.LENGTH_SHORT).show();
} }
} /**
* 根据tag,获取
*/
public int getImageIdByTag(String tag){
//字符串分割split
String[] mStrs=tag.split("_");
return Integer.parseInt(mStrs[0]);
}
public int getImageIndexByTag(String tag){
//字符串分割split
String[] mStrs=tag.split("_");
return Integer.parseInt(mStrs[1]); }
}
package com.example.administrator.pintu; import android.graphics.Bitmap; import java.util.ArrayList;
import java.util.List; /**
* 分割图片,并且将图片放在
* Created by Zyh on 2016/11/22.
*/
public class ImageSplitterUtils {
/**
* 将目标图片进行分割,成piece块,然后存入集合当中返回出去
* @param bitmap
* @param piece
* @return
*/
public static List<ImagePiece> splitImage(Bitmap bitmap,int piece){
List<ImagePiece> mList=new ArrayList<>();
//拿到图片的宽度和高度
int width=bitmap.getWidth();
int height=bitmap.getHeight();
width=Math.min(width,height);
//计算出每一个piece的宽度
int pieceWith=width/piece;
ImagePiece temImagePiece;
for (int i=0;i<piece;i++){
for (int j = 0; j <piece ; j++) {
temImagePiece=new ImagePiece();
//每一次分割的起始坐标
int x=pieceWith*j;
int y=pieceWith*i;
//createBitmap--这个方法可以对图片进行切割,位置是(x,y),大小为后面两个参数
Bitmap mBitmap=Bitmap.createBitmap(bitmap,x,y,pieceWith,pieceWith);
temImagePiece.bitmap=mBitmap;
temImagePiece.index=j+i*piece;
mList.add(temImagePiece);
}
}
return mList;
}
}
package com.example.administrator.pintu; import android.graphics.Bitmap; /**
* Created by Zyh on 2016/11/22.
*/
public class ImagePiece {
//存放图片和分割的序号
public int index;
public Bitmap bitmap; public ImagePiece() {
} public ImagePiece(int index, Bitmap bitmap) { this.index = index;
this.bitmap = bitmap;
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.administrator.pintu.GamePinTuLayout
android:padding="3dp"
android:id="@+id/pintu"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent"></com.example.administrator.pintu.GamePinTuLayout>
<TextView
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:textStyle="italic"
android:textSize="20sp"
android:gravity="center"
android:background="@drawable/textbg"
android:layout_alignLeft="@id/pintu"
android:layout_above="@id/pintu"
android:id="@+id/time"
android:layout_width="60dp"
android:layout_height="60dp"
android:text="123"/>
<TextView
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:textStyle="italic"
android:background="@drawable/textbg"
android:textSize="20sp"
android:gravity="center"
android:layout_above="@id/pintu"
android:layout_alignRight="@id/pintu"
android:id="@+id/cishu"
android:layout_width="60dp"
android:layout_height="60dp"
android:text="1"/>
</RelativeLayout>
GamePinTu的更多相关文章
- Android拼图游戏
效果如下 游戏的设计 首先我们分析下如何设计这款游戏: 1.我们需要一个容器,可以放这些图片的块块,为了方便,我们准备使用RelativeLayout配合addRule实现 2.每个图片的块块,我们准 ...
- Android 实战美女拼图游戏 你能坚持到第几关
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40595385,本文出自:[张鸿洋的博客] 1.概述 继2048之后,今天给大家带 ...
随机推荐
- 从零开始编写自己的C#框架(9)——数据库设计与创建
对于千万级与百万级数据库设计是有所区别的,由于本项目是基于中小型软件开发框架来设计,记录量相对会比较少,所以数据库设计时考虑的角度是:与开发相结合:空间换性能:空间换开发效率:减少null异常.... ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(1)
好久没写 DDD 领域驱动设计相关的文章了,嘎嘎!!! 这几天在开发一个新的项目,虽然不是基于领域驱动设计的,但我想把 DDD 架构设计的一些东西运用在上面,但发现了很多问题,这些在之前的短消息项目中 ...
- 将Excel文件转换为Html
将Excel文件转换为HTML 背景 我的工作有时会涉及到财务数据的处理.我们大家都知道,Excel文件在处理数据中很流行并且被广泛使用.Excel让我们可以将存储在里面的数据进行数学计算.我在工作中 ...
- 【Java心得总结二】浅谈Java中的异常
作为一个面向对象编程的程序员对于 下面的一句一定非常熟悉: try { // 代码块 } catch(Exception e) { // 异常处理 } finally { // 清理工作 } 就是面向 ...
- Oracle配置和使用闪回
环境:RHEL 6.4 + Oracle 11.2.0.4 目录: 一.闪回查询 1.1 闪回查询举例 1.2 闪回版本查询举例 二.闪回事物 2.1 闪回事物查询的先决条件 2.2 闪回事物查询 三 ...
- CentOS 7.2 yum方式安装MySQL 5.7
CentOS 7之后的版本yum的默认源中使用MariaDB替代原先MySQL,因此安装方式较为以往有一些改变: 下载mysql的源 wget http://dev.mysql.com/get/mys ...
- C#运用GmaQrCode生成二维码
项目中需要生成二维码,方法比较多,可以采用JS插件,也可以采用第三方插件后台生成二维码,在后台方法中可以采用QRCode或者GmaQrCode,现在介绍一种C#在后台生成二维码的方法: /// < ...
- ApiController使用Session验证出现Null解决方案
问题描述 在服务端保存登录信息,出现异常信息 分析发现HttpContext.Current.Session为null 解决方案 执行时出报异常,要在Global.asax里添加:开启Session功 ...
- BizTalk Server 2016
10月28日微软正式发布BizTalk第十个版本BizTalk Server 2016,陆续发布了Azure VM镜像.MSDN版本.开发者版本等.以下为BizTalk Server 2016 新特性 ...
- .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)
概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...