Android实现九宫格拼图游戏
作者:Animee 发布时间:2021-06-11 09:41:13
标签:Android,九宫格,拼图
经常有同学问到,使用Android能不能开发游戏呢?能开发那些游戏呢?由于操作系统和开发语言局限,一般开发安卓手机游戏,我们很少使用其自带语言开发。而是使用指定编译器和语言完成,能够使界面更流畅,用户体验感更好。但是对于一些常见小游戏,使用JAVA语言开发运行,还是不在话下的,那在本篇博客中,我将给大家简单介绍一下,九宫格拼图游戏的开发过程,基本逻辑和思路我将在代码的注释中体现。
九宫格拼图游戏,相信大家小时候都玩过。大概逻辑是,将1张图采用3*3的方式,分成9部分,将第3行3列的小图取出,打乱剩余的8个部分的位置,然后开始游戏,将打乱的8个位置的图片通过左右挪动的方式复位,成功后,将第9张图归位,即游戏结束。
编程时同样采取了这个逻辑,将切割后的小图片存放入容器中,然后随机拜访,给每一张小图设置点击事件,点击后可根据所缺空隙进行挪动,直到全部正确归位为止,我引入了计时功能,可以记录完成游戏时间。
那么,接下来我们进入正题,开始编写代码:
首先编写拼图界面布局:
<LinearLayout 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"
android:orientation="vertical">
<TextView
android:id="@+id/text_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="#C00"
android:text="耗时:0秒" />
<LinearLayout
android:id="@+id/liner_first"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<ImageButton
android:id="@+id/btn_00x00"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_00x00"
android:padding="0dp"
/>
<ImageButton
android:id="@+id/btn_00x01"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_00x01"
android:padding="0dp"
/>
<ImageButton
android:id="@+id/btn_00x02"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_00x02"
android:padding="0dp"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/liner_second"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<ImageButton
android:id="@+id/btn_01x00"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_01x00"
android:padding="0dp" />
<ImageButton
android:id="@+id/btn_01x01"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_01x01"
android:padding="0dp" />
<ImageButton
android:id="@+id/btn_01x02"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_01x02"
android:padding="0dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/liner_third"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<ImageButton
android:id="@+id/btn_02x00"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_02x00"
android:padding="0dp" />
<ImageButton
android:id="@+id/btn_02x01"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_02x01"
android:padding="0dp" />
<ImageButton
android:id="@+id/btn_02x02"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="onClick"
android:src="@mipmap/img_xiaoxiong_02x02"
android:padding="0dp"
android:visibility="invisible" />
</LinearLayout>
<Button
android:id="@+id/btn_restart"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="restart"
android:layout_gravity="center"
android:text="重新开始" />
<ImageView
android:id="@+id/iv_yuantu"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/yangtu" />
</LinearLayout>
效果图如下:
接下来,我们编写拼图activity的逻辑代码:
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
public class MainActivity extends Activity{
private ImageButton button00,button01,button02,button10,button11,button12,button20,button21,button22;
private Button buttonrestart;
private TextView textView;
private int Imagex = 3;
private int Imagey = 3;
private int imgCount = Imagex * Imagey;
private int length = imgCount;
private int blankSwap = length - 1;
private int blankImgid = R.id.btn_02x02;// 初始化时候空白区域的按钮id
private int time;
private boolean timeswitch = true;
// 声明一个图片数组的下标数组,随机排列这个数组
private int[] imageIndex = new int[length];
private int[] image = { R.mipmap.img_xiaoxiong_00x00, R.mipmap.img_xiaoxiong_00x01, R.mipmap.img_xiaoxiong_00x02, R.mipmap.img_xiaoxiong_01x00,
R.mipmap.img_xiaoxiong_01x01, R.mipmap.img_xiaoxiong_01x02, R.mipmap.img_xiaoxiong_02x00, R.mipmap.img_xiaoxiong_02x01,
R.mipmap.img_xiaoxiong_02x02, };
Handler handler = new Handler() {
// 为了更新时间用handler更新,其实就是textView.settext(时间)
public void handleMessage(Message msg){
if (msg.what == 1) {
textView.setText("时间:" + time);
if (timeswitch){
time++;
handler.sendEmptyMessageDelayed(1,1000);
}
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化这些控件
button00 = (ImageButton) findViewById(R.id.btn_00x00);
button01 = (ImageButton) findViewById(R.id.btn_00x01);
button02 = (ImageButton) findViewById(R.id.btn_00x02);
button10 = (ImageButton) findViewById(R.id.btn_01x00);
button11 = (ImageButton) findViewById(R.id.btn_01x01);
button12 = (ImageButton) findViewById(R.id.btn_01x02);
button20 = (ImageButton) findViewById(R.id.btn_02x00);
button21 = (ImageButton) findViewById(R.id.btn_02x01);
button22 = (ImageButton) findViewById(R.id.btn_02x02);
textView = (TextView) findViewById(R.id.text_time);
buttonrestart = (Button) findViewById(R.id.btn_restart);
handler.sendEmptyMessageDelayed(1,1000);
random();
}
// 监听方法
private void random() {
timeswitch = true;
for (int i = 0; i < imageIndex.length; i++) {
// 利用循环讲数组存入值为012345678
imageIndex[i] = i;
}
int rand1, rand2;
for (int j = 0; j < 20; j++) {
// math.random 0-1的随机数,乘以8就是0-8的随机数
rand1 = (int) (Math.random() * (length - 1));
do {
rand2 = (int) (Math.random() * (length - 1));
if (rand1 != rand2) {
break;
}
} while (true);
swap(rand1, rand2);
}
// 随机排列
button00.setImageDrawable(getResources().getDrawable(image[imageIndex[0]]));
button01.setImageDrawable(getResources().getDrawable(image[imageIndex[1]]));
button02.setImageDrawable(getResources().getDrawable(image[imageIndex[2]]));
button10.setImageDrawable(getResources().getDrawable(image[imageIndex[3]]));
button11.setImageDrawable(getResources().getDrawable(image[imageIndex[4]]));
button12.setImageDrawable(getResources().getDrawable(image[imageIndex[5]]));
button20.setImageDrawable(getResources().getDrawable(image[imageIndex[6]]));
button21.setImageDrawable(getResources().getDrawable(image[imageIndex[7]]));
button22.setImageDrawable(getResources().getDrawable(image[imageIndex[8]]));
}
public void swap(int rand1, int rand2){
int temp = imageIndex[rand1];
imageIndex[rand1] = imageIndex[rand2];
imageIndex[rand2] = temp;
}
public void onClick(View view) {
// id就是点击按钮的时候传过来的button的id
int id = view.getId();
// 通过id进行条件语句的执行
switch (id) {
case R.id.btn_00x00:
move(R.id.btn_00x00, 0);
break;
case R.id.btn_00x01:
move(R.id.btn_00x01, 1);
break;
case R.id.btn_00x02:
move(R.id.btn_00x02, 2);
break;
case R.id.btn_01x00:
move(R.id.btn_01x00, 3);
break;
case R.id.btn_01x01:
move(R.id.btn_01x01, 4);
break;
case R.id.btn_01x02:
move(R.id.btn_01x02, 5);
break;
case R.id.btn_02x00:
move(R.id.btn_02x00, 6);
break;
case R.id.btn_02x01:
move(R.id.btn_02x01, 7);
break;
case R.id.btn_02x02:
move(R.id.btn_02x02, 8);
break;
}
}
// 点击的图片与空白区域的交换的方法
public void move(int imagbtnId, int site) {
int sitex = site / Imagex;// site 为第几张图片
int sitey = site % Imagey;
// 初始化空白处的坐标
int blankx = blankSwap / Imagex;
int blanky = blankSwap % Imagey;
// 取绝对值
int x = Math.abs(sitex - blankx);
int y = Math.abs(sitey - blanky);
// 两种情况要不是在同一行的不同列,要不就是在同一列的不同行
if ( (x == 0 && y == 1) || (x == 1 && y == 0)) {
// 定义新的imagebutton 等于我们传过来的图片buttonid
ImageButton clickButton = (ImageButton) findViewById(imagbtnId);
clickButton.setVisibility(View.INVISIBLE);
// 定义一个新的图片按钮,然后findviewbyid空白控件的id
ImageButton blankButton = (ImageButton) findViewById(blankImgid);
// 然后将图片按钮重新设置图片为我们传过来的第二个参数
blankButton.setImageDrawable(getResources().getDrawable(image[imageIndex[site]]));
// 但是,这个控件还是不可见的,设置为可见
blankButton.setVisibility(View.VISIBLE);
swap(site, blankSwap);
// 将新的空白区域位置更新等于传过来的点击的按钮的位置
blankSwap = site;
// 将新的空白区域的id更新为传过来的点击的按钮的id
blankImgid = imagbtnId;
}
gameOver();
}
// 如果重新开始,我们要还原被点击的图片按钮变成初始化的模样
public void restore() {
handler.removeMessages(1);
// 定义新的imagebutton 等于我们新的空白图片按钮id,并且设置可见,
ImageButton clickButton = (ImageButton) findViewById(blankImgid);
clickButton.setVisibility(View.VISIBLE);
// 定义一个新的图片按钮,然后findviewbyid空白控件的id这个id就是我们初始化的时候设置隐藏的第九章图片
ImageButton blankButton = (ImageButton) findViewById(R.id.btn_02x02);
// 但是,这个控件还是不可见的,设置为不可见可见
blankButton.setVisibility(View.INVISIBLE);
blankImgid = R.id.btn_02x02;// 初始化时候空白区域的按钮id
blankSwap = length - 1;
}
// 判断拼图是否成功
public void gameOver() {
boolean loop = true;
for (int i = 0; i < imageIndex.length; i++) {
if (imageIndex[i] != i) {
loop = false;
}
}
if (loop) {
// 成功后,时间停止
timeswitch = false;
// 玩家拼图成功,禁止图像按钮移动
button00.setClickable(false);
button01.setClickable(false);
button02.setClickable(false);
button10.setClickable(false);
button11.setClickable(false);
button12.setClickable(false);
button20.setClickable(false);
button21.setClickable(false);
button22.setClickable(false);
button22.setImageDrawable(getResources().getDrawable(image[8]));
button22.setVisibility(View.VISIBLE);
handler.removeMessages(1);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("恭喜,拼图成功!您用的时间为" + time + "秒").setPositiveButton("确认", null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
public void restart(View view) {
time = 0;
restore();
textView.setText("时间:" + time);
timeswitch = true;
handler.sendEmptyMessageDelayed(1,1000);
button00.setClickable(true);
button01.setClickable(true);
button02.setClickable(true);
button10.setClickable(true);
button11.setClickable(true);
button12.setClickable(true);
button20.setClickable(true);
button21.setClickable(true);
button22.setClickable(true);
random();
}
}
最后运行项目,就能够进行拼图游戏了!效果图如下:
来源:https://blog.csdn.net/u012156341/article/details/94760700
0
投稿
猜你喜欢
- 使用匿名内部类课使代码更加简洁、紧凑,模块化程度更高。内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到。然而这
- 前言本文主要给大家介绍了关于java poi导入Excel通用工具类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍
- 声明一个客户端对象:protected RedisClient Redis = new RedisClient("127.0.0
- 本文实例讲述了C#对二进制数据进行base64编码的方法。分享给大家供大家参考。具体实现方法如下:using System;using Sy
- 背景SpringBoot的应用监控方案比较多,SpringBoot+Prometheus+Grafana是目前比较常用的方案之一。它们三者之
- Spring Boot 简介spring框架功能很强大,但是就算是一个很简单的项目,我们也要配置很多东西。因此就有了Spring Boot框
- 本文实例讲述了C#4.0新特性的协变与逆变,有助于大家进一步掌握C#4.0程序设计。具体分析如下:一、C#3.0以前的协变与逆变如果你是第一
- 工具方法:本文的目的是把json串转成map键值对存储,而且只存储叶节点的数据maven 引用jar包版本:<dependency&g
- 在上篇文章给大家介绍了WebService教程详解(一)使用工具的原因:1、 使用工具可以更好的了解WebService请求的过程 2、 使
- 本文实例讲述了java旋转二维数组的操作,分享给大家供大家参考。具体实现方法如下:package test;/* * &
- 需要引入命名空间:using System;using System.Text;解码: public static string
- 方法一、利用控件或窗体的Paint事件中的PainEventArgs在窗体或控件的Paint事件中接收对图形对象的引用,作为PaintEve
- 在Unity3d中开发虚拟摇杆方式有比较多,可以使用EasyTouch、FairyGUI等插件来开发。本文给大家介绍使用Unity3d的原生
- 前言在实际开发当中,Spring中bean的属性直接赋值用的不是太多,整理这方面的资料,做一个小结,以备后续更深入的学习。通过配置文件的方式
- 前言在介绍Dubbo之前先了解一下基本概念:Dubbo是一个RPC框架,RPC,即Remote Procedure Call(远程过程调用)
- Jmeter 执行Java 请求时,运行结束后报错,Tidying up remote @ Mon Feb 24 19:42:34 CST
- 首先我们都知道java中的比较都是同一类对象与对象之间的比较,就好像现实生活中比较人和人的年龄一样,你不会去把人的年龄和人的身高来比较,这显
- 本文讲述了Java递归运行的机制:递归的微观解。分享给大家供大家参考,具体如下:前言:在java递归基础与递归的宏观语意和java链表的天然
- 目录一、连接查询:1、多对一:2、一对多:3、多对多:二、嵌套查询:1、多对一:2、一对多:首先在mysql中确立表:#表一:地址国家表CR
- 本文实例讲述了C#双缓冲实现方法。分享给大家供大家参考,具体如下:// 该调用是 Windows.Forms &nb