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之后,今天给大家带 ...
随机推荐
- .Net 转战 Android 4.4 日常笔记(10)--PullToRefresh下拉刷新使用
下拉刷新很多地方都用到了,新浪微博,微信,百度新闻 这里我们使用一个开源的库叫:PullToRefresh 开源地址:https://github.com/chenyoca/pull-to-refre ...
- 分享几个.NET WinForm开源组件,纪念逐渐远去的WinForm。。。
前面3个月的时间内,这些.NET开源项目你知道吗?系列文章已经发表了3篇,共计45个平时接触比较少,曾经默默无闻的.NET开源项目,展示给大家,当然不是每个人都能用得上,但也的确是有些人用了,反响还不 ...
- 从零开始编写自己的C#框架(6)——SubSonic3.0插件介绍(附源码)
前面几章主要是概念性的东西为主,向初学者们介绍项目开始前的一些知识与内容,从本章开始将会进入实操阶段,希望跟着本系统学习的朋友认真按说明做好每一步操作(对于代码最好是直接照着文档内容在你的IDE中打一 ...
- 由position属性引申的关于css的进阶讨论(包含块、BFC、margin collapse)
写这篇文章的起因是源于这篇文章:谈谈面试与面试题 中关于position的讨论,文中一开始就说的这句话: 面试的时候问个css的position属性能刷掉一半的人这是啥情况…… 其实这问题我本来打算的 ...
- Objective-C中的Block回调模式
在前面的博客中提到了Block的概念和使用方法,个人感觉Block最爽的用法莫过于在回调时用block.感觉比委托回调和目标方法回调用着要顺手,好不好用还得读者亲自用一下才知道.如果 读者之前用过SS ...
- 如何从源码中学习javascript
艾伦说啊,学习javascript,必须要学会看源码,通过高手的源码,你可以从中吸取很多书本上难以看到的技巧. 看源码就好像喝鸡汤,所有的营养都在这汤里了.这汤就是源码,高手写的源码,就是最好的鸡汤. ...
- JavaScript中Promises/A+规范的实现
Promises是一种异步编程模型,通过一组API来规范化异步操作,这样也能够让异步操作的流程控制更加容易. 下面的代码是假设执行一个异步队列,每一项都会使用上一项返回的数据: function ne ...
- 编译lsusb
参考博客: http://blog.csdn.net/mcy_cool/article/details/10178841 涉及到的源码: http://files.cnblogs.com/files/ ...
- Ajax 与 XmlHttpRequest
AJAX描述了确保Web应用在Web服务器请求新数据的情况下也能(几乎)实时反应的一种方法.具体地说,AJAX只是一些建立已久的技术的相互作用,从HTML.XHTML和HTTP,到JavaScript ...
- Azure Application Gateway (4) 设置URL路由 - PowerShell
<Windows Azure Platform 系列文章目录> 本文将介绍如果使用Azure PowerShell,创建Azure Application Gateway URL Rout ...