Android Studio 实现简单的拼图游戏(超级简单)!

目录

前言

一、项目概述

1、构成以及功能设计

二、开发环境

 三、准备内容

四、详细设计

1、新建工程

2、搭建启动页 

3、搭建游戏界面

五、运行演示

Get 项目模板源码


前言

        本项目是一个基于Android Studio的拼图游戏应用程序。通过重新排列碎片的方式,将乱序的图片拼接成完整的图片。该应用程序具有计时功能,记录玩家完成拼图所需的时间,并提供重新开始按钮,方便玩家重新挑战。

一、项目概述

1、构成以及功能设计

①.启动页

②游戏页面

    - 实现拼图游戏

    -计时器

二、开发环境

        我的开发环境如下,大家的AS版本不需要和我相同,只要是近两年从官网下载的版本,都是比4.0.0(2020版)高的,是可以满足运行和开发要求的。

 三、准备内容

        需要准备一张照片,并且将照片分割成9份

四、详细设计

1、新建工程

  • 首先打开Android Studio,并新建一个工程,File——>New——>New Project——>Empty Project,工程名称叫做SawPuzzle,可以根据自己喜好设置名称。

  • 包名自己随意设定,这里博主用的是com.example,一般是com.example;工程文件的保存路径要修改一下,不要放在C盘,我这里选择的是放在H盘,养成项目统一放在英文路径下的好习惯。

  • 最后选择API 24:Android 7.0,因为这样它就拥有了96.3%的跨平台性(兼容性非常好),因为它版本很低,基本上模拟器API版本都是高于20的,所以这个软件可以运行其他各种设备上。点击Finish完成创建。

2、搭建启动页 

        设计一个app的时候,一定要先设计layout文件,再设计java文件,因为布局有了,才能在上面进行代码的编写。我们来看一下activity_start.xml布局文件。

<?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"
    android:background="@drawable/start"
    tools:context=".Start.StartActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

        然后回到我们的Activity文件,启动页逻辑代码如下:

package com.example.sawpuzzle.Start;

import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;

import androidx.appcompat.app.AppCompatActivity;

import com.example.sawpuzzle.MainActivity;
import com.example.sawpuzzle.R;

public class StartActivity extends AppCompatActivity {
    TimeCount timeCount;
    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            tomainActive();
        }
    };
    // 进入主页面
    private void tomainActive() {
        startActivity(new Intent(this, MainActivity.class));
        // 跳转完成后注销
        finish();
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
     
    }

    // 计时器
    class TimeCount extends CountDownTimer {
        public TimeCount(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }
        @Override
        public void onTick(long l) {
        }
        @Override
        public void onFinish() {
         
          
        }
    }
}

3、搭建游戏界面

        图片碎片的随机排列:通过定义一个图片数组的下标数组,随机打乱数组元素的顺序,从而实现图片碎片的随机排列。
        图片碎片的移动:通过按钮的点击事件,判断选中的图片碎片是否可以移动,并且将移动后的图片位置更新到存储图片位置数组中,同时更新空白区域的位置。
        判断拼图是否成功:在每次移动完成后,判断是否完成了拼图游戏。通过遍历存储图片位置数组,判断每个位置上的图片是否与预期位置一致,从而确定游戏是否成功。
        计时功能和重新开始:通过Handler实现计时功能,每隔一秒更新计时器的显示。同时,提供重新开始按钮,点击按钮后将游戏状态和计时器还原,并重新打乱图片碎片的顺序。

activity_main.xml页面布局代码如下所示:

<?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"
    tools:context=".MainActivity"
    android:padding="20dp">

    <TextView
        android:id="@+id/pt_tv_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="时间 : 0"
        android:textColor="#FF0000"
        android:textSize="20sp" />
    <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="100dp"
            android:layout_height="140dp"
            android:onClick="onClick"
            android:padding="0dp"
            android:scaleType="centerCrop"
            android:src="@drawable/xx_01" />

        <ImageButton
            android:id="@+id/pt_ib_00x02"
            android:layout_width="100dp"
            android:layout_height="140dp"
            android:onClick="onClick"
            android:padding="0dp"
            android:scaleType="centerCrop"
            android:src="@drawable/xx_03" />
    </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_01x02"
            android:layout_width="100dp"
            android:layout_height="140dp"
            android:onClick="onClick"
            android:padding="0dp"
            android:scaleType="centerCrop"
            android:src="@drawable/xx_06" />
    </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="100dp"
            android:layout_height="140dp"
            android:onClick="onClick"
            android:padding="0dp"
            android:scaleType="centerCrop"
            android:src="@drawable/xx_07" />

        <ImageButton
            android:id="@+id/pt_ib_02x02"
            android:layout_width="100dp"
            android:layout_height="140dp"
            android:onClick="onClick"
            android:padding="0dp"
            android:scaleType="centerCrop"
            android:src="@drawable/xx_09"
            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:layout_marginTop="10dp"
        android:onClick="restart"
        android:text="重新开始" />

    <ImageView
        android:id="@+id/pt_iv"
        android:layout_width="99dp"
        android:layout_height="131dp"
        android:layout_gravity="center"
        android:layout_marginTop="10dp"
        android:src="@drawable/xx" />
</LinearLayout>

对应的逻辑代码:
 

package com.example.sawpuzzle;

public class MainActivity extends AppCompatActivity {
    ImageButton ib00,ib01,ib02,ib10,ib11,ib12,ib20,ib21,ib22;
    Button restartBtn;
    TextView timeTv;

 
    Handler handler = new Handler(){
        @Override
        public void handleMessage(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);
    }

  
//        随机排列到指定的控件上
        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 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 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);
    }
}

五、运行演示

Android studio期末设计大作业~拼图游戏App

Get 项目模板源码

👇👇👇快捷获取方式👇👇👇

  • 35
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程乐学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值