Android自定义View实现拼图小游戏
本文实例为大家分享了Android拼图小游戏的具体代码,供大家参考,具体内容如下
1、效果图:
运行时:
结束时:
2、PuzzleLayoutView:
publicclassPuzzleLayoutViewextendsRelativeLayoutimplementsView.OnClickListener{
//表示将其切成2*2拼图(默认4块)
privateintmColumn=2;
//容器的内边距
privateintmPadding;
//每个块块的边距(横,纵3:表示间距为3dp)
privateintmMargin=3;
//存储ImageView
privateImageView[]mGamePintuItems;
//Item的宽度(一致)
privateintmItemWidth;
//游戏的图片
privateBitmapmBitmap;
//切图后的存储
privateListmItemBitmaps;
//操作次数
privatebooleanonce;
//容器宽度(游戏面板高宽一致)
privateintmWidth;
//设置游戏是否成功
privatebooleanisGameSuccess;
//设置游戏是否失败
privatebooleanisGameOver;
publicGamePintuListnermListner;
publicPuzzleLayoutView(Contextcontext){
this(context,null);
}
publicPuzzleLayoutView(Contextcontext,AttributeSetattrs){
this(context,attrs,0);
}
publicPuzzleLayoutView(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
init();
}
privatevoidinit(){
mMargin=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,3,
getResources().getDisplayMetrics());//将dp转化为px,或xp转化为px
mPadding=min(getPaddingLeft(),getPaddingRight(),getPaddingTop(),getPaddingBottom());
}
//接口方法
publicinterfaceGamePintuListner{
voidnextLevel(intnextLevel);//下一关
voidtimechanged(intcurrentTime);//关卡时间
voidgameover();//游戏结束
}
publicvoidsetOnGamePintuListner(GamePintuListnermListner){
this.mListner=mListner;
}
privateintlevel=1;
privatestaticfinalintTIME_CHANGED=0X123;
privatestaticfinalintNEXT_LEVEL=0X124;
privateHandlerhandler=newHandler(){
publicvoidhandleMessage(android.os.Messagemsg){
switch(msg.what){
caseTIME_CHANGED:
if(isGameSuccess||isGameOver)
return;
if(mListner!=null){
mListner.timechanged(mTime);
//时间结束后,游戏结束
if(mTime==0){
isGameOver=true;
mListner.gameover();
}
}
mTime--;
//延迟1秒发送
handler.sendEmptyMessageDelayed(TIME_CHANGED,1000);
break;
caseNEXT_LEVEL:
level=level+1;//切换到下一关
if(mListner!=null){
mListner.nextLevel(level);
}else{
nextLevel();
}
default:
break;
}
}
};
privatebooleanisTimeEnabled=false;
privateintmTime;
/**
*设置是否启动时间(默认不启动)
*
*@paramisTimeEnabled
*/
publicvoidsetTimeEnabled(booleanisTimeEnabled){
this.isTimeEnabled=isTimeEnabled;
}
/**
*获取当前布局的大小(正方形)
*/
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
//取宽和高中的最小值
mWidth=Math.min(getMeasuredHeight(),getMeasuredWidth());
if(!once){
//调用进行切图,以及排序(方法)
initBitmap();
//调用设置ImageView(Item)的宽高等属性(方法)
initItem();
//判断是否开启时间(方法调用)
checkTimeEnable();
once=true;
}
setMeasuredDimension(mWidth,mWidth);//强制调用使面板为正方形
}
/**
*判断是否开启时间
*/
privatevoidcheckTimeEnable(){
if(isTimeEnabled){
//根据当前等级设置时间
countTimeBaseLevel();
//通知线程更新关卡时间
handler.sendEmptyMessage(TIME_CHANGED);
}
}
privatevoidcountTimeBaseLevel(){
mTime=(int)Math.pow(2,level)*60;//第一关120秒第二关:240第三关:480
}
/**
*进行切图,以及排序方法
*/
privatevoidinitBitmap(){
//将图片引入
if(mBitmap==null){
mBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.pic_view);//注意此处的导包
}
mItemBitmaps=ImageSplitterUtil.sqlitImage(mBitmap,mColumn);//返回长度为4(2*2)
//使用sort进行乱排序
Collections.sort(mItemBitmaps,newComparator(){
publicintcompare(ImagePieceBeana,ImagePieceBeanb){//注意此处的a,b
//是否大于0.5具有不确定性
returnMath.random()>0.5?1:-1;
}
});
}
/**
*设置ImageView(Item)的宽高等属性方法
*/
privatevoidinitItem(){
//容器的宽度-Item内边距=所有小块块加起来的/Item个数(宽度)2:左边和右边边距
mItemWidth=(mWidth-mPadding*2-mMargin*(mColumn-1))/mColumn;
mGamePintuItems=newImageView[mColumn*mColumn];//界面块块个数相*
//生成我们的Item,设置Rule(Item间的关系,高矮等)
for(inti=0;imColumn){
lp.topMargin=mMargin;
lp.addRule(RelativeLayout.BELOW,mGamePintuItems[i-mColumn].getId());
}
addView(item,lp);//添加到RelativeLayout中
}
}
/**
*当过关失败,时间停止时调用此方法(重新开始此关卡)
*/
publicvoidrestart(){
isGameOver=false;//重置当前关卡
mColumn--;
nextLevel();
}
publicvoidnextLevel(){
this.removeAllViews();//移除当前所有View
mAnimLayout=null;
mColumn++;//由2*2变为3*3游戏面版
isGameSuccess=false;//游戏未成功(新的开始)
checkTimeEnable();//下一关时间重新计算
initBitmap();
initItem();
}
/**
*获取多个参数的最小值
*/
privateintmin(int...params){//...传多个参数
intmin=params[0];//获取最小的
for(intparam:params){//发现最小的则赋值
if(param
工具类:ImageSplitterUtil
publicclassImageSplitterUtil{
/**
*传入bitmap,切成piece*piece块
*/
publicstaticListsqlitImage(Bitmapbitmap,intpiece){
ListImagePieceBeans=newArrayList<>();
intwidth=bitmap.getWidth();//拿到图片宽高
intheight=bitmap.getHeight();
intpieceWidth=Math.min(width,height)/piece;//得到每一块的宽度
for(inti=0;i
实体类:ImagePieceBean
publicclassImagePieceBean{
privateintindex;//表示当前第几块
privateBitmapbitmap;//当前图片
publicImagePieceBean(){
}
//快捷键构造方法Source倒3
publicImagePieceBean(intindex,Bitmapbitmap){
this.index=index;
this.bitmap=bitmap;
}
publicintgetIndex(){
returnindex;
}
publicvoidsetIndex(intindex){
this.index=index;
}
publicBitmapgetBitmap(){
returnbitmap;
}
publicvoidsetBitmap(Bitmapbitmap){
this.bitmap=bitmap;
}
publicStringtoString(){
return"ImagePiece[index="+index+",bitmap="+bitmap+"]";
}
}
3、使用方法:GameActivity
/**
*总结:
*1.自定义控件选择,九宫格,RelativeLayout,id+Rule
*2.切图
*3.动画图层
*4.pauseresumerestart
*5.游戏时间HandlersendMessageDelayed()延迟一秒发送线程
*/
publicclassGameActivityextendsAppCompatActivity{
privatePuzzleLayoutViewpuzzleLayoutView;
privateTextViewmLevel,mTime;
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_game);
mLevel=this.findViewById(R.id.id_level);
mTime=this.findViewById(R.id.id_time);
puzzleLayoutView=this.findViewById(R.id.puzzle_layout_view);
puzzleLayoutView.setTimeEnabled(true);
//监听事件
puzzleLayoutView.setOnGamePintuListner(newPuzzleLayoutView.GamePintuListner(){
publicvoidtimechanged(intcurrentTime){
//此处为int注意加""
mTime.setText(currentTime+"秒");
}
publicvoidnextLevel(finalintnextLevel){
//弹出提示框
newAlertDialog.Builder(GameActivity.this).setTitle("游戏信息")
.setMessage("游戏升级").setPositiveButton("进入下一关",
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intwhich){
//游戏结束后,调用下一关
puzzleLayoutView.nextLevel();
mLevel.setText("第"++nextLevel+"关");
}
}).show();
}
publicvoidgameover(){
//弹出提示框
newAlertDialog.Builder(GameActivity.this).setTitle("游戏信息")
.setMessage("游戏结束!").setPositiveButton("是否继续该关卡?",
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intwhich){
puzzleLayoutView.restart();//重新启动
}
}).setNegativeButton("是否放弃该游戏!",newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intwhich){
finish();
}
}).show();
}
});
}
}
对应布局:activity_game
 
 
 
 
 
 
注意:pic_view图片资源自行更换
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。