Android项目---拼图小游戏(下)

原创
小哥 3年前 (2022-12-19) 阅读数 4 #大杂烩

继前一篇文章之后,前一篇完成了游戏中的计时以及进入程序的片段的自动无序排列。本文将完成剩下的部分(片段的移动和拼图的成功逻辑)

实现过程是近似的:默认情况下,不显示最后一张照片,但它确实存在。单击空白区域附近的图片(只有空白区域中的图片有效),然后在单击后实现图片的移动和空白区域的交换。在几次移动后,如果最终的总图片被组合起来,并且给出的最终图片是相同的,则会弹出一个提示框,提示拼图成功!

事实上,总结是一系列知识。使用阵列的坐标值交换来显示图片交换。在几次图片移动(几次数组交换)之后,看看它是否与引入的最终指定图片(指定的数字顺序)相同!

具体实现方法:(代码注释已经很详细了,按照分步逻辑进行注释,很容易理解)

如果你不理解评论区,可以留言或私下信任我。如果文章有代码、逻辑和不准确的写作错误,请纠正我。我会及时纠正。非常感谢。

要实现单击片段的效果,请执行以下操作:

//一个函数,表示移动指定位置的按钮,将图片与空白区域交换。 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 blackButton=findViewById(blankImgid); //将空白区域设置为图片 blackButton.setImageResource(image[imageIndex[site]]); //移动之间不可见,移动后,将控件设置为可见 blackButton.setVisibility(View.VISIBLE); //记录将角标记更改为存储图片位置的数组的过程。 swap(site,blankSwap); //新的空白位置将更新为与单击的传入按钮的位置相等 blankSwap=site; blankImgid=imagebuttonId; }

实现多次移动后判断碎片是否成功的逻辑效果:

//判断拼图是否成功 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); builder.create().show(); }

Java总代码:

package com.example.jigsaw;

import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint; import android.media.Image; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.AlteredCharSequence; 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_id_02x02;

//定义时间的变量 int time = 0; //用于存储碎片以进行统一管理的阵列 private int[]image={R.drawable.pt_id_00x00,R.drawable.pt_id_00x01,R.drawable.pt_id_00x02, R.drawable.pt_tv_01x00,R.drawable.pt_tv_01x01,R.drawable.pt_tv_01x02,R.drawable.p1,R.drawable.p2,R.drawable.p3}; //为图片数组声明下标数组并随机排列数组 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(); //打乱碎片 disruptRandpm(); handler.sendEmptyMessageDelayed(1,1000); } //随机镦粗不规则 private void disruptRandpm() { 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\_id\_00x00);
    ib01=findViewById(R.id.pt\_id\_00x01);
    ib02=findViewById(R.id.pt\_id\_00x02);
    ib10=findViewById(R.id.pt\_id\_01x00);
    ib11=findViewById(R.id.pt\_id\_01x01);
    ib12=findViewById(R.id.pt\_id\_01x02);
    ib20=findViewById(R.id.pt\_id\_02x00);
    ib21=findViewById(R.id.pt\_id\_02x01);
    ib22=findViewById(R.id.pt\_id\_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\_id\_00x00:
            move(R.id.pt\_id\_00x00,0);
            break;
        case R.id.pt\_id\_00x01:
            move(R.id.pt\_id\_00x01,1);
            break;
        case R.id.pt\_id\_00x02:
            move(R.id.pt\_id\_00x02,2);
            break;
        case R.id.pt\_id\_01x00:
            move(R.id.pt\_id\_01x00,3);
            break;
        case R.id.pt\_id\_01x01:
            move(R.id.pt\_id\_01x01,4);
            break;
        case R.id.pt\_id\_01x02:
            move(R.id.pt\_id\_01x02,5);
            break;
        case R.id.pt\_id\_02x00:
            move(R.id.pt\_id\_02x00,6);
            break;
        case R.id.pt\_id\_02x01:
            move(R.id.pt\_id\_02x01,7);
            break;
        case R.id.pt\_id\_02x02:
            move(R.id.pt\_id\_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 blackButton=findViewById(blankImgid); //将空白区域设置为图片 blackButton.setImageResource(image[imageIndex[site]]); //移动之间不可见,移动后,将控件设置为可见 blackButton.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); builder.create().show(); } // }

}

//拼图游戏又开始了 public void restart(View view) { //拼图游戏又开始了,允许玩家移动碎片 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); //拼图打乱 disruptRandpm();

    handler.removeMessages(1);
    //该回来了。0和re-⏲
    time=0;
    timeTv.setText("时间:"+time+" 秒");
    handler.sendEmptyMessageDelayed(1,1000);

}

} 屏幕截图效果:

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除