专属空间十二——拼图游戏
今天完成的功能是拼图游戏。
时间效果使用handler来进行实现的。一秒一传输。用随机数的方式实现图片的打乱。
需要注意的时候生成的随机数的区间是左闭右开的。
完整代码可以在文件pintu.rar中
package com.example.pintu; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; 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 AppCompatActivity { ImageButton ib00,ib01,ib02,ib10,ib11,ib12,ib20,ib21,ib22; Button restartBtn; TextView timeTv; // 每行的图片个数 private int imageX = 3; private int imageY = 3; //每列的图片的个数 // 图片的总数目 private int imgCount = imageX*imageY; // 空白区域的位置 private int blankSwap = imgCount-1; // 初始化空白区域的按钮id private int blankImgid = R.id.pt_ib_02x02; //定义计数时间的变量 int time=0; // 存放碎片的数组,便于进行统一的管理 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}; // 声明一个图片数组的下标数组,随机排列这个数组 private int[]imageIndex = new int[image.length]; Handler handler=new Handler(){ @Override public void handleMessage(@NonNull Message msg) { if (msg.what==1) { time++; timeTv.setText("时间:"+time+"秒"); handler.sendEmptyMessageDelayed(1,1000); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); // 打乱碎片的函数 disruptRandom(); handler.sendEmptyMessageDelayed(1,1000); } // 随机打乱数组当中元素,以不规则的形式进行图片显示 private void disruptRandom() { for (int i = 0; i < imageIndex.length; i++) { imageIndex[i] = i; } // 规定20次,随机选择两个角标对应的值进行交换 int rand1 ,rand2; for (int j=0;j<20;j++){ // 随机生成第一个角标 生成0-8之间的随机数 rand1 = (int)(Math.random()*(imageIndex.length-1)); // 第二次随机生成的角标,不能和第一次随机生成的角标相同,如果相同,就不方便交换了 do { rand2 = (int)(Math.random()*(imageIndex.length-1)); if (rand1!=rand2) { break; } }while (true); swap(rand1,rand2); } // 随机排列到指定的控件上 ib00.setImageResource(image[imageIndex[0]]); ib01.setImageResource(image[imageIndex[1]]); ib02.setImageResource(image[imageIndex[2]]); ib10.setImageResource(image[imageIndex[3]]); ib11.setImageResource(image[imageIndex[4]]); ib12.setImageResource(image[imageIndex[5]]); ib20.setImageResource(image[imageIndex[6]]); ib21.setImageResource(image[imageIndex[7]]); ib22.setImageResource(image[imageIndex[8]]); } // 交换数组指定角标上的数据 private void swap(int rand1, int rand2) { int temp = imageIndex[rand1]; imageIndex[rand1] = imageIndex[rand2]; imageIndex[rand2] = temp; } /*初始化控件*/ private void initView() { ib00 = findViewById(R.id.pt_ib_00x00); ib01 = findViewById(R.id.pt_ib_00x01); ib02 = findViewById(R.id.pt_ib_00x02); ib10 = findViewById(R.id.pt_ib_01x00); ib11 = findViewById(R.id.pt_ib_01x01); ib12 = findViewById(R.id.pt_ib_01x02); ib20 = findViewById(R.id.pt_ib_02x00); ib21 = findViewById(R.id.pt_ib_02x01); ib22 = findViewById(R.id.pt_ib_02x02); timeTv = findViewById(R.id.pt_tv_time); restartBtn = findViewById(R.id.pt_btn_restart); } public void onClick(View view) { int id = view.getId(); // 九个按钮执行的点击事件的逻辑应该是相同的,如果有空格在周围,可以改变图片显示的位置,否则点击事件不响应 switch (id) { case R.id.pt_ib_00x00: move(R.id.pt_ib_00x00,0); break; case R.id.pt_ib_00x01: move(R.id.pt_ib_00x01,1); break; case R.id.pt_ib_00x02: move(R.id.pt_ib_00x02,2); break; case R.id.pt_ib_01x00: move(R.id.pt_ib_01x00,3); break; case R.id.pt_ib_01x01: move(R.id.pt_ib_01x01,4); break; case R.id.pt_ib_01x02: move(R.id.pt_ib_01x02,5); break; case R.id.pt_ib_02x00: move(R.id.pt_ib_02x00,6); break; case R.id.pt_ib_02x01: move(R.id.pt_ib_02x01,7); break; case R.id.pt_ib_02x02: move(R.id.pt_ib_02x02,8); break; } } /*表示移动指定位置的按钮的函数,将图片和空白区域进行交换*/ private void move(int imagebuttonId, int site) { // 判断选中的图片在第几行 int sitex = site / imageX; int sitey = site % imageY; //第几列 // 获取空白区域的坐标 int blankx = blankSwap / imageX; int blanky = blankSwap % imageY; // 可以移动的条件有两个 // 1.在同一行,列数相减,绝对值为1,可移动 2.在同一列,行数相减,绝对值为1,可以移动 int x = Math.abs(sitex-blankx); int y = Math.abs(sitey-blanky); if ((x==0&&y==1)||(y==0&&x==1)) { // 通过id,查找到这个可以移动的按钮 ImageButton clickButton = findViewById(imagebuttonId); clickButton.setVisibility(View.INVISIBLE); // 查找到空白区域的按钮 ImageButton blankButton = findViewById(blankImgid); // 将空白区域的按钮设置图片 blankButton.setImageResource(image[imageIndex[site]]); // 移动之前是不可见的,移动之后,将控件设置为可见 blankButton.setVisibility(View.VISIBLE); // 将改变角标的过程记录到存储图片位置数组当中 swap(site, blankSwap); // 新的空白区域位置更新等于传入的点击按钮的位置 blankSwap = site; blankImgid = imagebuttonId; } // 判断本次移动完成后,是否完成了拼图游戏 judgeGameOver(); } /* 判断拼图是否成功*/ private void judgeGameOver() { boolean loop = true; //定义标志位 for (int i = 0; i < imageIndex.length; i++) { if (imageIndex[i]!=i) { loop = false; break; } } if (loop) { // 拼图成功了 // 停止计时 handler.removeMessages(1); // 拼图成功后,禁止玩家继续移动按钮 ib00.setClickable(false); ib01.setClickable(false); ib02.setClickable(false); ib10.setClickable(false); ib11.setClickable(false); ib12.setClickable(false); ib20.setClickable(false); ib21.setClickable(false); ib22.setClickable(false); ib22.setImageResource(image[8]); ib22.setVisibility(View.VISIBLE); // 弹出提示用户成功的对话框 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("恭喜,拼图成功!您用的时间为"+time+"秒") .setPositiveButton("确认",null); AlertDialog dialog = builder.create(); dialog.show(); } } /*重新开始按钮点击事件*/ public void restart(View view) { // 将状态还原 restore(); // 将拼图重新打乱 disruptRandom(); handler.removeMessages(1); //将时间重新归0,并重新开始计时 time=0; timeTv.setText("时间:"+time+"秒"); handler.sendEmptyMessageDelayed(1,1000); } private void restore() { // 拼图游戏重新开始,允许完成移动碎片按钮 ib00.setClickable(true); ib01.setClickable(true); ib02.setClickable(true); ib10.setClickable(true); ib11.setClickable(true); ib12.setClickable(true); ib20.setClickable(true); ib21.setClickable(true); ib22.setClickable(true); // 还原被点击的图片按钮变成初始化的模样 ImageButton clickBtn = findViewById(blankImgid); clickBtn.setVisibility(View.VISIBLE); // 默认隐藏第九章图片 ImageButton blankBtn = findViewById(R.id.pt_ib_02x02); blankBtn.setVisibility(View.INVISIBLE); blankImgid = R.id.pt_ib_02x02; //初始化空白区域的按钮id blankSwap = imgCount - 1; } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" android:padding="20dp" tools:context=".MainActivity"> <TextView android:id="@+id/pt_tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="时间:0" android:layout_gravity="center" android:textSize="20sp" android:textColor="#ff0000" /> <LinearLayout android:id="@+id/pt_line1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_gravity="center"> <ImageButton android:id="@+id/pt_ib_00x00" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_00x00" android:padding="0dp" android:onClick="onClick"/> <ImageButton android:id="@+id/pt_ib_00x01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_00x01" android:padding="0dp" android:onClick="onClick"/> <ImageButton android:id="@+id/pt_ib_00x02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_00x02" android:padding="0dp" android:onClick="onClick"/> </LinearLayout> <LinearLayout android:id="@+id/pt_line2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_gravity="center"> <ImageButton android:id="@+id/pt_ib_01x00" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_01x00" android:padding="0dp" android:onClick="onClick"/> <ImageButton android:id="@+id/pt_ib_01x01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_01x01" android:padding="0dp" android:onClick="onClick"/> <ImageButton android:id="@+id/pt_ib_01x02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_01x02" android:padding="0dp" android:onClick="onClick"/> </LinearLayout> <LinearLayout android:id="@+id/pt_line3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_gravity="center"> <ImageButton android:id="@+id/pt_ib_02x00" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_02x00" android:padding="0dp" android:onClick="onClick"/> <ImageButton android:id="@+id/pt_ib_02x01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_02x01" android:padding="0dp" android:onClick="onClick"/> <ImageButton android:id="@+id/pt_ib_02x02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_xiaoxiong_02x02" android:padding="0dp" android:onClick="onClick" android:visibility="invisible"/> </LinearLayout> <Button android:id="@+id/pt_btn_restart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="重新开始" android:onClick="restart"/> <ImageView android:id="@+id/pt_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@mipmap/yangtu" android:layout_marginTop="20dp"/> </LinearLayout>