赞
踩
献给热爱编程的朋友,安装包下载地址(提取码:4g3g): https://pan.baidu.com/s/14-BaDBN9MEBR3DJTNZqn3A
源代码下载地址: https://gitee.com/landzy/PinTuGame-share.git
这是一款用安卓studio开发的拼图游戏,通过点击空白区域相邻的图片进行移动,直至还原成示例图片即为游戏成功。
游戏界面如下:
通过线性布局的嵌套,实现九宫格的排版,代码如下:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="300dp" android:layout_height="300dp" android:layout_marginTop="20dp" android:background="@color/purple_200" android:orientation="vertical" android:padding="2dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <LinearLayout android:id="@+id/line1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" android:padding="0.1dp"> <ImageButton android:id="@+id/imageButton_00" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> <ImageButton android:id="@+id/imageButton_01" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> <ImageButton android:id="@+id/imageButton_02" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> </LinearLayout> <LinearLayout android:id="@+id/line2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" android:padding="0.1dp"> <ImageButton android:id="@+id/imageButton_03" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> <ImageButton android:id="@+id/imageButton_04" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> <ImageButton android:id="@+id/imageButton_05" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> </LinearLayout> <LinearLayout android:id="@+id/line3" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" android:padding="0.1dp"> <ImageButton android:id="@+id/imageButton_06" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> <ImageButton android:id="@+id/imageButton_07" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> <ImageButton android:id="@+id/imageButton_08" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:padding="0.1dp" android:scaleType="centerCrop" /> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="60dp" android:orientation="horizontal" app:layout_constraintBottom_toTopOf="@+id/imageView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/linearLayout1" app:layout_constraintVertical_bias="0.502"> <LinearLayout android:id="@+id/line4" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="horizontal" android:padding="0.1dp"> <Button android:id="@+id/restartButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:backgroundTint="@color/yellow" android:text="重新开始" android:textSize="25sp" tools:ignore="MissingConstraints" /> </LinearLayout> </LinearLayout> <ImageView android:id="@+id/imageView" android:layout_width="200dp" android:layout_height="200dp" android:layout_marginBottom="20dp" android:background="@color/purple_200" android:padding="2dp" android:scaleType="centerCrop" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
代码如下:
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
}
代码如下:
//定义控件变量 ImageButton ib00, ib01, ib02, ib03, ib04, ib05, ib06, ib07, ib08; Button startButton; ImageView iV; //定义一个数组来存放碎片图片 private int[] image = { R.drawable.shuzi_00, R.drawable.shuzi_01, R.drawable.shuzi_02, R.drawable.shuzi_03, R.drawable.shuzi_04, R.drawable.shuzi_05, R.drawable.shuzi_06, R.drawable.shuzi_07, R.drawable.shuzi_08}; //定义一个数组来存放ImageButton按钮地址 private int[] imageButton = {R.id.imageButton_00, R.id.imageButton_01, R.id.imageButton_02, R.id.imageButton_03, R.id.imageButton_04, R.id.imageButton_05, R.id.imageButton_06, R.id.imageButton_07, R.id.imageButton_08}; //定义每行每列图片的个数 private int imageX = 3; private int imageY = 3; //图片总个数 private int imgCount = imageX * imageY; //空白区域的位置 private int blankSite = imgCount - 1; //创建一个长度与图片数相同的数组,记录图片的索引 private int[] imageIndex = new int[imgCount];
代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
initView();
//打乱图片并装载图片
initImage();
}
代码如下:
public void initView() { ib00 = findViewById(imageButton[0]); ib01 = findViewById(imageButton[1]); ib02 = findViewById(imageButton[2]); ib03 = findViewById(imageButton[3]); ib04 = findViewById(imageButton[4]); ib05 = findViewById(imageButton[5]); ib06 = findViewById(imageButton[6]); ib07 = findViewById(imageButton[7]); ib08 = findViewById(imageButton[8]); startButton = findViewById(R.id.restartButton); iV = findViewById(R.id.imageView); //给所有控件设置监听 ib00.setOnClickListener(this); ib01.setOnClickListener(this); ib02.setOnClickListener(this); ib03.setOnClickListener(this); ib04.setOnClickListener(this); ib05.setOnClickListener(this); ib06.setOnClickListener(this); ib07.setOnClickListener(this); ib08.setOnClickListener(this); startButton.setOnClickListener(this); }
先赋值一个有序数组(因为最后一个不换,所以长度为8),然后打乱顺序,再判断数组逆序对是否为偶数,代码如下:
private void initImage() { //给图片索引数组赋值0至(imgCount - 1) for (int i = 0; i < imageIndex.length; i++) { imageIndex[i] = i; } //打乱图片索引数组中数据的顺序,因为需要留一个空白,所以数组的最后一个不变动,所以是imageIndex.length - 1 Random r = new Random(); for (int i = 0; i < imageIndex.length - 1; i++) { //获取随机索引 int index = r.nextInt(imageIndex.length - 1); int temp = imageIndex[i]; imageIndex[i] = imageIndex[index]; imageIndex[index] = temp; } //获取数组的逆序对 int count = 0; for (int i = 0; i < imageIndex.length - 1; i++) { for (int j = 0; j < imageIndex.length - 1 - i; j++) { if (imageIndex[i] > imageIndex[i + 1 + j]) { count++; } } } //判断数组逆序对是否为偶,只有为偶才能拼图成功,否则游戏无解 //如果不为偶,将相邻2个数据对调位置,这里我们选前面2个对调位置 if (count % 2 != 0) { int temp = imageIndex[0]; imageIndex[0] = imageIndex[1]; imageIndex[1] = temp; } //把打乱的图片索引数组中的数据作为image索引,装载图片 putImage(); }
根据索引数据装入图片,并将最有一个位置设置不可见,即空白位置,代码如下:
private void putImage() {
for (int i = 0; i < imageIndex.length; i++) {
ImageButton ib = findViewById(imageButton[i]);
ib.setImageResource(image[imageIndex[i]]);
ib.setVisibility(View.VISIBLE);
//最后一张图片设置为不可见,即空白位置图片
if (imageIndex[i] == imageIndex.length - 1) {
ib.setVisibility(View.INVISIBLE);
}
//装载示例图片
iV.setImageResource(R.drawable.shuzi);
}
}
重写onClick方法,判断点击不同Button时操作,这里将点击位置的数据传给move()方法,并判定图片是否还原,代码如下:
@Override public void onClick(View view) { switch (view.getId()) { //重新开始按钮 case R.id.restartButton: reStart(); break; case R.id.imageButton_00: move(0); break; case R.id.imageButton_01: move(1); break; case R.id.imageButton_02: move(2); break; case R.id.imageButton_03: move(3); break; case R.id.imageButton_04: move(4); break; case R.id.imageButton_05: move(5); break; case R.id.imageButton_06: move(6); break; case R.id.imageButton_07: move(7); break; case R.id.imageButton_08: move(8); break; default: break; } //定义变量result接收判断结果,拿图片索引imageIndex数组中数据与0-8对比,如有一个不相同时,将结果改为false boolean result = true; for (int i = 0; i < imageIndex.length; i++) { if (imageIndex[i] != i) { result = false; break; } } //当上面判断全部相同时,判定为挑战成功 if (result) { //把图片数组的中最后一个图片,设置在最后一个位置,并将其更改为可见 ib08.setImageResource(image[imgCount - 1]); ib08.setVisibility(view.VISIBLE); //弹出游戏成功对话框 //创建弹窗方法对象 AlertDialog.Builder builder = new AlertDialog.Builder(this); //用对象调用方法,设置弹窗信息 builder.setMessage("恭喜你,挑战成功!").setPositiveButton("确认", null); //创建弹窗并展示 builder.create().show(); //游戏成功后,设置按钮不可点击 ib00.setClickable(false); ib01.setClickable(false); ib02.setClickable(false); ib03.setClickable(false); ib04.setClickable(false); ib05.setClickable(false); ib06.setClickable(false); ib07.setClickable(false); ib08.setClickable(false); } }
拿到点击位置的数据进行计算,然后判断与空白区域的相对位置,如果相邻,则证明可以移动(此处移动的底层逻辑是将点击图片与空白位置交换),代码如下:
private void move(int site) { //判断选中的图片在第几行,第几列,判断方法通过求余的方法 int siteX = site / imageX; int siteY = site % imageY; //获取空白区域的坐标 int blankX = blankSite / imageX; int blankY = blankSite % imageY; //图片可以移动的两个条件: //1.在同一行,列数相减绝对值为1;2.在同一列,行数相减绝对值为1 int x = Math.abs(siteX - blankX); int y = Math.abs(siteY - blankY); //只有当(x == 0 && y == 1)或 (x == 1 && y == 0)时,证明点击区域与空白区域相邻 if ((x == 0 && y == 1) || (x == 1 && y == 0)) { //交换记录图片的索引的数组中数据的位置 int temp = imageIndex[site]; imageIndex[site] = imageIndex[blankSite]; imageIndex[blankSite] = temp; //更新新的空白位置的site blankSite = site; //用调换好的数组,重新加载图片, putImage(); } }
初始化界面、控件、空白位置,打乱图片并装入图片,将图片按钮设置为可点击,代码如下:
private void reStart() { //初始化界面 setContentView(R.layout.activity_main); //初始化按钮及监听事件 initView(); //打乱图片顺序,并装入图片 initImage(); //初始化空白位置的site blankSite = imgCount - 1; //设置按钮可点击 ib00.setClickable(true); ib01.setClickable(true); ib02.setClickable(true); ib03.setClickable(true); ib04.setClickable(true); ib05.setClickable(true); ib06.setClickable(true); ib07.setClickable(true); ib08.setClickable(true); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。