Android实现拼图小游戏
程序员文章站
2023-10-22 18:07:28
本文实例为大家分享了android实现拼图小游戏的具体代码,供大家参考,具体内容如下
目标效果:
1.activity_main.xml页面:...
本文实例为大家分享了android实现拼图小游戏的具体代码,供大家参考,具体内容如下
目标效果:
1.activity_main.xml页面:
<?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" tools:context="com.example.vivinia.puzzle.mainactivity"> <gridlayout android:id="@+id/gl_main_game" android:layout_width="match_parent" android:layout_height="match_parent" android:rowcount="3" android:columncount="5"> </gridlayout> </relativelayout>
2.mainactivity.java页面:
package com.example.vivinia.puzzle; import android.graphics.bitmap; import android.graphics.drawable.bitmapdrawable; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.view.gesturedetector; import android.view.motionevent; import android.view.view; import android.view.animation.animation; import android.view.animation.translateanimation; import android.widget.gridlayout; import android.widget.imageview; import android.widget.toast; public class mainactivity extends appcompatactivity { /** * 当前动画是否正在执行 */ private boolean isanimrun=false; /** *判断游戏是否开始*/ private boolean isgamestart=false; /** *利用二维数组创建若干个游戏小方块 */ private imageview[][] iv_game_arr = new imageview[3][5]; /** *游戏主界面 */ private gridlayout gl_main_game; /** *当前空方块的实例保存 */ private imageview iv_null_imageview; /** *当前手势 */ private gesturedetector mdetector; //非图片位置可以进行手势滑动 @override public boolean ontouchevent(motionevent event) { return mdetector.ontouchevent(event); //手势监听 } //在图片上可以进行手势滑动 @override public boolean dispatchtouchevent(motionevent ev) { mdetector.ontouchevent(ev); return super.dispatchtouchevent(ev); } @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); mdetector=new gesturedetector(this, new gesturedetector.ongesturelistener() { @override public boolean ondown(motionevent motionevent) { return false; } @override public void onshowpress(motionevent motionevent) { } @override public boolean onsingletapup(motionevent motionevent) { return false; } @override public boolean onscroll(motionevent motionevent, motionevent motionevent1, float v, float v1) { return false; } @override public void onlongpress(motionevent motionevent) { } /** *一瞬间执行的方法 */ @override public boolean onfling(motionevent e1, motionevent e2, float v, float v1) { int type=getdirbyges(e1.getx(),e1.gety(),e2.getx(),e2.gety()); changebydir(type); return false; } }); setcontentview(r.layout.activity_main); //初始化游戏的若干个小方块 bitmap bigbm=((bitmapdrawable)getresources().getdrawable(r.drawable.puzzle_bg)).getbitmap(); int everywidth=bigbm.getwidth()/5; //每个游戏小方块的宽和高 for (int i = 0; i < iv_game_arr.length; i++) { for (int j = 0; j < iv_game_arr[0].length; j++) { bitmap bm=bitmap.createbitmap(bigbm,j*everywidth,i*everywidth,everywidth,everywidth);//根据行列来切成若干个游戏小图片 iv_game_arr[i][j]=new imageview(this); iv_game_arr[i][j].setimagebitmap(bm); //设置每一个游戏小方块图案 iv_game_arr[i][j].setpadding(2,2,2,2);//设置方块之间的间距 iv_game_arr[i][j].settag(new gamedata(i,j,bm)); //绑定自定义的数据 iv_game_arr[i][j].setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { boolean flag=ishasbynullimageview((imageview)view); if(flag){ changedatabyimageview((imageview)view); } } }); } } //初始化游戏主界面,并添加若干个小方块 gl_main_game = (gridlayout) findviewbyid(r.id.gl_main_game); for(int i=0;i<iv_game_arr.length;i++){ for(int j=0;j<iv_game_arr[0].length;j++){ gl_main_game.addview(iv_game_arr[i][j]); } } /** *设置最后一个方块为空的 */ setnullimageview(iv_game_arr[2][4]); /** *初始化随机打乱顺序 */ randommove(); isgamestart=true; //开始状态 } public void changebydir(int type){ changebydir(type,true); } /** * 根据手势的方向,获取空方块相应的相邻位置如果存在方块,那么进行数据交换 * @param type 1:上,2:下,3:左,4:右 * @param isanim true:有动画,false:无动画 */ public void changebydir(int type,boolean isanim){ /** *获取当前空方块的位置 */ gamedata mnullgamedata= (gamedata) iv_null_imageview.gettag(); /** * 根据方向,设置相应的相邻的位置的坐标 */ int new_x=mnullgamedata.x; int new_y=mnullgamedata.y; if(type==1){ //要移动的方块在当前空方块的下边 new_x++; }else if(type==2){ //要移动的方块在当前空方块的下边 new_x--; }else if(type==3){ //要移动的方块在当前空方块的下边 new_y++; } else if(type==4){ //要移动的方块在当前空方块的下边 new_y--; } /** *判断这个新坐标,是否存在 */ if(new_x>=0&&new_x<iv_game_arr.length&&new_y>=0&&new_y<iv_game_arr[0].length){ if(isanim) { /** *存在的话,开始移动 */ changedatabyimageview(iv_game_arr[new_x][new_y]); }else{ changedatabyimageview(iv_game_arr[new_x][new_y],isanim); } }else{ //什么也不做 } } /** *判断游戏结束的方法 */ public void isgameover(){ boolean isgameover=true; //要便利每个游戏小方块 for(int i=0;i<iv_game_arr.length;i++){ for(int j=0;j<iv_game_arr[0].length;j++){ //为空的方块数据不判断跳过 if(iv_game_arr[i][j]==iv_null_imageview){ continue; } gamedata mgamedata= (gamedata) iv_game_arr[i][j].gettag(); if(!mgamedata.istrue()){ isgameover=false; break; } } } //根据一个开关变量决定游戏是否结束,结束时给提示 if(isgameover){ toast.maketext(this,"游戏结束",toast.length_long).show(); } } /** * 手势判断,是向左还是向右 * @param start_x 手势的起始点x * @param start_y 手势的起始点y * @param end_x 手势的终止点x * @param end_y 手势的起始点y * @return 1:上,2:下,3:左,4:右 */ public int getdirbyges(float start_x,float start_y,float end_x,float end_y){ boolean isleftorright=(math.abs(start_x-end_x)>math.abs(start_y-end_y))?true:false; //是否左右 if(isleftorright){ //左右 boolean isleft=start_x-end_x>0?true:false; if(isleft){ return 3; }else{ return 4; } }else{ //上下 boolean isup=start_y-end_y>0?true:false; if(isup){ return 1; }else{ return 2; } } } /** * 随机打乱顺序 */ public void randommove(){ //打乱的次数 for(int i=0;i<10;i++){ //根据手势开始交换,无动画 int type=(int)(math.random()*4)+1; changebydir(type,false); } } public void changedatabyimageview(final imageview mimageview) { changedatabyimageview(mimageview,true); } /** * 利用动画结束之后,交换两个方块的数据 * @param mimageview 点击的方块 * @param isanim true:有动画,false:无动画 */ public void changedatabyimageview(final imageview mimageview,boolean isanim){ if(isanimrun){ //如果动画已经开始,则不做交换操作 return; } if(!isanim){ //如果没有动画 gamedata mgamedata= (gamedata) mimageview.gettag(); iv_null_imageview.setimagebitmap(mgamedata.bm); gamedata mnullgamedata= (gamedata) iv_null_imageview.gettag(); mnullgamedata.bm=mgamedata.bm; mnullgamedata.p_x=mgamedata.p_x; mnullgamedata.p_y=mgamedata.p_y; setnullimageview(mimageview); //设置当前点击的是空方块 if(isgamestart) { isgameover(); //成功时谈一个toast } return; } /** *创建一个动画,设置好方向,移动的距离 */ translateanimation translateanimation = null; if(mimageview.getx()>iv_null_imageview.getx()){ //当前点击的方块在空方块下边 //往上移动 translateanimation=new translateanimation(0.1f,-mimageview.getwidth(),0.1f,0.1f); }else if(mimageview.getx()<iv_null_imageview.getx()){ //当前点击的方块在空方块下边 //往下移动 translateanimation=new translateanimation(0.1f,mimageview.getwidth(),0.1f,0.1f); } else if(mimageview.getx()>iv_null_imageview.gety()){ //当前点击的方块在空方块下边 //往左移动 translateanimation=new translateanimation(0.1f,0.1f,0.1f,-mimageview.getwidth()); } else if(mimageview.getx()<iv_null_imageview.gety()){ //当前点击的方块在空方块下边 //往右移动 translateanimation=new translateanimation(0.1f,0.1f,0.1f,mimageview.getwidth()); } /** * 设置动画的时长 */ translateanimation.setduration(70); /** * 设置动画结束之后是否停留 */ translateanimation.setfillafter(true); /** * 设置动画结束之后真正的交换数据 */ translateanimation.setanimationlistener(new animation.animationlistener() { @override public void onanimationstart(animation animation) { isanimrun=true; //动画开始 } @override public void onanimationend(animation animation) { isanimrun=false; //动画结束 /** *结束之后,清除动画 */ mimageview.clearanimation(); gamedata mgamedata= (gamedata) mimageview.gettag(); iv_null_imageview.setimagebitmap(mgamedata.bm); gamedata mnullgamedata= (gamedata) iv_null_imageview.gettag(); mnullgamedata.bm=mgamedata.bm; mnullgamedata.p_x=mgamedata.p_x; mnullgamedata.p_y=mgamedata.p_y; setnullimageview(mimageview); //设置当前点击的是空方块 if(isgamestart) { isgameover(); //成功时谈一个toast } } @override public void onanimationrepeat(animation animation) { } }); /** * 执行动画 */ mimageview.startanimation(translateanimation); } /** * 设置某个方块为空方块 * @param mimageview 当前要设置为空的方块的实例 */ public void setnullimageview(imageview mimageview){ mimageview.setimagebitmap(null); //设置为空 iv_null_imageview=mimageview; } /** * 判断当前点击的方块,是否与空方块的位置关系是相邻关系 * @param mimageview 所点击的方块 * @return true:相邻;false:不相邻 */ public boolean ishasbynullimageview(imageview mimageview){ /** *分别获取当前空方块的位置与点击方块的位置,通过x,y两边都差1的方式判断 */ gamedata mnullgamedata= (gamedata) iv_null_imageview.gettag(); //空方块身上的数据 gamedata mgamedata= (gamedata)mimageview.gettag(); //点击方块身上的数据 if(mnullgamedata.y==mgamedata.y&&mgamedata.x+1==mnullgamedata.x){ //当前点击的方块在空方块的上边 return true; }else if(mnullgamedata.y==mgamedata.y&&mgamedata.x-1==mnullgamedata.x){ //当前点击的方块在空方块的下边 return true; }else if(mnullgamedata.y==mgamedata.y+1&&mgamedata.x==mnullgamedata.x){ //当前点击的方块在空方块的左边 return true; }else if(mnullgamedata.y==mgamedata.y-1&&mgamedata.x+1==mnullgamedata.x){ //当前点击的方块在空方块的右边 return true; } return false; } /** * 每个游戏小方块上要绑定的数据 */ class gamedata{ /** *每个小方块的实际位置x */ public int x=0; /** *每个小方块的实际位置x */ public int y=0; /** *每个小方块的图片 */ public bitmap bm; /** *每个小方块的图片的位置 */ public int p_x=0; /** *每个小方块的图片的位置 */ public int p_y=0; public gamedata(int x, int y, bitmap bm) { this.x = x; this.y = y; this.bm = bm; this.p_x = x; this.p_y = y; } /** * 每个小方块的位置是否正确 * @return true:正确,false:不正确 */ public boolean istrue() { if(x==p_x&&y==p_y) { return true; } return false; } } }
3.设置去掉标题栏样式
styles.xml页面:
<resources> <!-- base application theme. --> <style name="apptheme" parent="theme.appcompat.light"> <!-- customize your theme here. --> <item name="colorprimary">@color/colorprimary</item> <item name="colorprimarydark">@color/colorprimarydark</item> <item name="coloraccent">@color/coloraccent</item> </style> <style name="myapptheme" parent="apptheme"> <item name="windownotitle">true</item> <item name="windowactionbar">false</item> <item name="android:windowfullscreen">true</item> <item name="android:windowcontentoverlay">@null</item> </style> </resources>
4.清单文件中使用该样式
androidmanifest.xml页面:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.vivinia.puzzle"> <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundicon="@mipmap/ic_launcher_round" android:supportsrtl="true" android:theme="@style/myapptheme"> <activity android:name=".mainactivity" android:screenorientation="landscape"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> </manifest>
源码下载:点击打开链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。