Android project --- jigsaw puzzle game (below)

Continuing from the previous article, the previous article completed the timing in the game and the automatic random arrangement of the program fragments. This article will complete the remaining parts (the movement of the fragments and the success logic of the puzzle)

The implementation process is roughly: the last photo is not displayed by default, but it actually exists. Click the adjacent picture in the blank area (only the picture in the blank area is clicked and valid) and then realize the movement of the picture after clicking and the exchange of the blank area. After the second move, if the combination of the final total picture is the same as the given final picture, a prompt box showing the success of the puzzle will pop up!

In fact, the summary is an array of knowledge. Use the coordinate value exchange of the array to show the exchange of pictures, and use the picture movement several times (the exchange of the number of arrays) to see if it is the same as the imported final designated picture (specified numerical order)!

The specific implementation method: (the code comments are already very detailed, and are commented step by step according to the logic, which is easy to understand)

If you don’t understand something in the comment area, you can leave a message or private message me. If the article has code, logic, or inaccurate writing errors, please correct me. I will correct and learn in time, thank you!

To achieve the effect of clicking on the fragments:

//Represents the function of moving the button at the specified position, exchanging the picture with the blank area
    private void move(int imagebuttonId, int site) {
//Judging which row and column the selected picture is in, the judgment method is through the method of finding the remainder
        int sitex=site/imageX;
        int sitey=site%imageY;
        // Get the coordinates of the blank area
        int blankx=blankSwap/imageX;
        int blanky=blankSwap%imageY;
        //Two conditions for the image to move
        //1. In the same row, the absolute value of the subtraction of the number of columns is 1; 2. In the same column, the absolute value of the subtraction of the number of rows is 1
        int x=Math.abs(sitex-blankx);
        int y=Math.abs(sitey-blanky);
        if((x == 0&&y==1)||(y==0&&x==1)){
            // Find this movable button by id
            ImageButton clickButton=findViewById(imagebuttonId);
            clickButton.setVisibility(View.INVISIBLE);
            // button to view the blank area
            ImageButton blackButton=findViewById(blankImgid);
            //Set the blank area to the image
            blackButton.setImageResource(image[imageIndex[site]]);
            //Invisible between movements, after movement, set the control to be visible
            blackButton.setVisibility(View.VISIBLE);
            //Record the process of changing the corner mark into the array that stores the image location
            swap(site,blankSwap);
            //The position of the new blank area is updated to be equal to the position of the incoming click button
            blankSwap=site;
            blankImgid=imagebuttonId;
        }

Realize the logical effect of judging whether the debris moves successfully after several times:

/ / Determine whether the puzzle is successful
    private void judgeGameOver() {
     boolean loop=true;//Define flag bit
        for(int i=0;i<imageIndex.length;i++) {
            if (imageIndex[i] != i) {
                loop = false;
                break;
            }
        }
            if(loop){
                //Puzzle is successful, stop timing
                handler.removeMessages(1);
                // After the puzzle is successful, the player is prohibited from continuing to move the button
                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);
                //Pop up the user success dialog box
                AlertDialog.Builder builder=new AlertDialog.Builder(this);
                builder.setMessage("Congratulations, the puzzle is successful! Your time is "+time+"seconds").setPositiveButton("Confirm",null);
                builder.create().show();
            }

Java total code:

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;
//Define the number of pictures in each row and column
private int imageX=3;
    private  int imageY=3;
    //Total number of pictures
    private int imgCount=imageX*imageY;
    //position of blank space
    private  int blankSwap=imgCount-1;
    //Initialize the button id of the blank area
    private int blankImgid=R.id.pt_id_02x02;

//Define time variables
int time = 0;
//Store the array of fragments for unified management
    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};
    // Declare an array of subscripts for an image array, and randomly arrange the array
    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: "+time+" seconds");
         handler.sendEmptyMessageDelayed(1,1000);
     }
    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        //scramble fragments
        disruptRandpm();
        handler.sendEmptyMessageDelayed(1,1000);
    }
// randomly shuffle the irregular
    private void disruptRandpm() {
        for(int i=0;i<imageIndex.length;i++){
            imageIndex[i]=i;
        }
        //Specify 20 times, randomly select the values ​​corresponding to the two subscripts to exchange
        int rand1,rand2;
        for(int j=0;j<20;j++){
            // Randomly generate a corner mark, the value of 0-8
            rand1=(int)(Math.random()*(imageIndex.length-1));
            //The second randomly generated corner mark cannot be the same as the first time
            do{
                rand2=(int)(Math.random()*(imageIndex.length-1));
                if(rand1!=rand2){
                    break;
                }
            }while (true);
            //Exchange the corresponding values ​​on the two corner marks
            swap(rand1,rand2);
        }
        //Randomly arranged on the specified control
        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]]);
    }
//exchange
    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;
        }
    }
//Represents the function of moving the button at the specified position, exchanging the picture with the blank area
    private void move(int imagebuttonId, int site) {
//Judging which row and column the selected picture is in, the judgment method is through the method of finding the remainder
        int sitex=site/imageX;
        int sitey=site%imageY;
        // Get the coordinates of the blank area
        int blankx=blankSwap/imageX;
        int blanky=blankSwap%imageY;
        //Two conditions for the image to move
        //1. In the same row, the absolute value of the subtraction of the number of columns is 1; 2. In the same column, the absolute value of the subtraction of the number of rows is 1
        int x=Math.abs(sitex-blankx);
        int y=Math.abs(sitey-blanky);
        if((x == 0&&y==1)||(y==0&&x==1)){
            // Find this movable button by id
            ImageButton clickButton=findViewById(imagebuttonId);
            clickButton.setVisibility(View.INVISIBLE);
            // button to view the blank area
            ImageButton blackButton=findViewById(blankImgid);
            //Set the blank area to the image
            blackButton.setImageResource(image[imageIndex[site]]);
            //Invisible between movements, after movement, set the control to be visible
            blackButton.setVisibility(View.VISIBLE);
            //Record the process of changing the corner mark into the array that stores the image location
            swap(site,blankSwap);
            //The position of the new blank area is updated to be equal to the position of the incoming click button
            blankSwap=site;
            blankImgid=imagebuttonId;
        }
//Judge whether the jigsaw puzzle is completed after this move is completed
        judgeGameOver();
    }
/ / Determine whether the puzzle is successful
    private void judgeGameOver() {
     boolean loop=true;//Define flag bit
        for(int i=0;i<imageIndex.length;i++) {
            if (imageIndex[i] != i) {
                loop = false;
                break;
            }
        }
            if(loop){
                //Puzzle is successful, stop timing
                handler.removeMessages(1);
                // After the puzzle is successful, the player is prohibited from continuing to move the button
                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);
                //Pop up the user success dialog box
                AlertDialog.Builder builder=new AlertDialog.Builder(this);
                builder.setMessage("Congratulations, the puzzle is successful! Your time is "+time+"seconds").setPositiveButton("Confirm",null);
                builder.create().show();
            }
       // }

    }
// jigsaw puzzle restart
    public void restart(View view) {
        // The jigsaw puzzle restarts, allowing the player to move pieces
        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);
        // jigsaw puzzle
disruptRandpm();

        handler.removeMessages(1);
        //The time returns to 0, and re-⏲
        time=0;
        timeTv.setText("Time: "+time+" seconds");
        handler.sendEmptyMessageDelayed(1,1000);

    }
}
Screenshot effect:

 

Guess you like

Origin blog.csdn.net/Abtxr/article/details/126228834