Android趣味课程:九宫格拼图游戏

经常有同学问到,使用Android能不能开发游戏呢?能开发那些游戏呢?由于操作系统和开发语言局限,一般开发安卓手机游戏,我们很少使用其自带语言开发。而是使用指定编译器和语言完成,能够使界面更流畅,用户体验感更好。但是对于一些常见小游戏,使用JAVA语言开发运行,还是不在话下的,那在本篇博客中,我将给大家简单介绍一下,九宫格拼图游戏的开发过程,基本逻辑和思路我将在代码的注释中体现。

九宫格拼图游戏,相信大家小时候都玩过。大概逻辑是,将1张图采用3*3的方式,分成9部分,将第3行3列的小图取出,打乱剩余的8个部分的位置,然后开始游戏,将打乱的8个位置的图片通过左右挪动的方式复位,成功后,将第9张图归位,即游戏结束。

编程时同样采取了这个逻辑,将切割后的小图片存放入容器中,然后随机拜访,给每一张小图设置点击事件,点击后可根据所缺空隙进行挪动,直到全部正确归位为止,我引入了计时功能,可以记录完成游戏时间。

那么,接下来我们进入正题,开始编写代码:

首先编写拼图界面布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/text_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="28sp"
        android:textStyle="bold"
        android:textColor="#C00"
        android:text="耗时:0秒" />
    <LinearLayout
        android:id="@+id/liner_first"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center">
        <ImageButton
            android:id="@+id/btn_00x00"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_00x00"
            android:padding="0dp"
            />
        <ImageButton
            android:id="@+id/btn_00x01"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_00x01"
            android:padding="0dp"
            />
        <ImageButton
            android:id="@+id/btn_00x02"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_00x02"
            android:padding="0dp"
            />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/liner_second"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center">
        <ImageButton
            android:id="@+id/btn_01x00"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_01x00"
            android:padding="0dp" />
        <ImageButton
            android:id="@+id/btn_01x01"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_01x01"
            android:padding="0dp" />
        <ImageButton
            android:id="@+id/btn_01x02"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_01x02"
            android:padding="0dp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/liner_third"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center">
        <ImageButton
            android:id="@+id/btn_02x00"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_02x00"
            android:padding="0dp" />
        <ImageButton
            android:id="@+id/btn_02x01"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_02x01"
            android:padding="0dp" />
        <ImageButton
            android:id="@+id/btn_02x02"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:onClick="onClick"
            android:src="@mipmap/img_xiaoxiong_02x02"
            android:padding="0dp"
            android:visibility="invisible" />
    </LinearLayout>
    <Button
        android:id="@+id/btn_restart"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:onClick="restart"
        android:layout_gravity="center"
        android:text="重新开始" />
    <ImageView
        android:id="@+id/iv_yuantu"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/yangtu" />
</LinearLayout>

效果图如下:

接下来,我们编写拼图activity的逻辑代码:

import android.app.Activity;
import android.app.AlertDialog;
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 Activity{
    private ImageButton button00,button01,button02,button10,button11,button12,button20,button21,button22;
    private Button buttonrestart;
    private TextView textView;
    private int Imagex = 3;
    private int Imagey = 3;
    private int imgCount = Imagex * Imagey;
    private int length = imgCount;
    private int blankSwap = length - 1;
    private int blankImgid = R.id.btn_02x02;// 初始化时候空白区域的按钮id
    private int time;
    private boolean timeswitch = true;
    // 声明一个图片数组的下标数组,随机排列这个数组
    private int[] imageIndex = new int[length];
    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, };
    Handler handler = new Handler() {
        // 为了更新时间用handler更新,其实就是textView.settext(时间)
        public void handleMessage(Message msg){
            if (msg.what == 1) {
                textView.setText("时间:" + time);
                if (timeswitch){
                    time++;
                    handler.sendEmptyMessageDelayed(1,1000);
                }
            }
        };
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 初始化这些控件
        button00 = (ImageButton) findViewById(R.id.btn_00x00);
        button01 = (ImageButton) findViewById(R.id.btn_00x01);
        button02 = (ImageButton) findViewById(R.id.btn_00x02);
        button10 = (ImageButton) findViewById(R.id.btn_01x00);
        button11 = (ImageButton) findViewById(R.id.btn_01x01);
        button12 = (ImageButton) findViewById(R.id.btn_01x02);
        button20 = (ImageButton) findViewById(R.id.btn_02x00);
        button21 = (ImageButton) findViewById(R.id.btn_02x01);
        button22 = (ImageButton) findViewById(R.id.btn_02x02);
        textView = (TextView) findViewById(R.id.text_time);
        buttonrestart = (Button) findViewById(R.id.btn_restart);
        handler.sendEmptyMessageDelayed(1,1000);
        random();
    }
    // 监听方法
    private void random() {
        timeswitch = true;
        for (int i = 0; i < imageIndex.length; i++) {
            // 利用循环讲数组存入值为012345678
            imageIndex[i] = i;
        }
        int rand1, rand2;
        for (int j = 0; j < 20; j++) {
            // math.random 0-1的随机数,乘以8就是0-8的随机数
            rand1 = (int) (Math.random() * (length - 1));
            do {
                rand2 = (int) (Math.random() * (length - 1));
                if (rand1 != rand2) {
                    break;
                }
            } while (true);
            swap(rand1, rand2);
        }
        // 随机排列
        button00.setImageDrawable(getResources().getDrawable(image[imageIndex[0]]));
        button01.setImageDrawable(getResources().getDrawable(image[imageIndex[1]]));
        button02.setImageDrawable(getResources().getDrawable(image[imageIndex[2]]));
        button10.setImageDrawable(getResources().getDrawable(image[imageIndex[3]]));
        button11.setImageDrawable(getResources().getDrawable(image[imageIndex[4]]));
        button12.setImageDrawable(getResources().getDrawable(image[imageIndex[5]]));
        button20.setImageDrawable(getResources().getDrawable(image[imageIndex[6]]));
        button21.setImageDrawable(getResources().getDrawable(image[imageIndex[7]]));
        button22.setImageDrawable(getResources().getDrawable(image[imageIndex[8]]));
    }
    public void swap(int rand1, int rand2){
        int temp = imageIndex[rand1];
        imageIndex[rand1] = imageIndex[rand2];
        imageIndex[rand2] = temp;
    }
    public void onClick(View view) {
        // id就是点击按钮的时候传过来的button的id
        int id = view.getId();
        // 通过id进行条件语句的执行
        switch (id) {
            case R.id.btn_00x00:
                move(R.id.btn_00x00, 0);
                break;
            case R.id.btn_00x01:
                move(R.id.btn_00x01, 1);
                break;
            case R.id.btn_00x02:
                move(R.id.btn_00x02, 2);
                break;
            case R.id.btn_01x00:
                move(R.id.btn_01x00, 3);
                break;
            case R.id.btn_01x01:
                move(R.id.btn_01x01, 4);
                break;
            case R.id.btn_01x02:
                move(R.id.btn_01x02, 5);
                break;
            case R.id.btn_02x00:
                move(R.id.btn_02x00, 6);
                break;
            case R.id.btn_02x01:
                move(R.id.btn_02x01, 7);
                break;
            case R.id.btn_02x02:
                move(R.id.btn_02x02, 8);
                break;
        }
    }
    // 点击的图片与空白区域的交换的方法
    public void move(int imagbtnId, int site) {
        int sitex = site / Imagex;// site 为第几张图片
        int sitey = site % Imagey;
        // 初始化空白处的坐标
        int blankx = blankSwap / Imagex;
        int blanky = blankSwap % Imagey;
        // 取绝对值
        int x = Math.abs(sitex - blankx);
        int y = Math.abs(sitey - blanky);
        // 两种情况要不是在同一行的不同列,要不就是在同一列的不同行
        if ( (x == 0 && y == 1) || (x == 1 && y == 0)) {
            // 定义新的imagebutton 等于我们传过来的图片buttonid
            ImageButton clickButton = (ImageButton) findViewById(imagbtnId);
            clickButton.setVisibility(View.INVISIBLE);
            // 定义一个新的图片按钮,然后findviewbyid空白控件的id
            ImageButton blankButton = (ImageButton) findViewById(blankImgid);
            // 然后将图片按钮重新设置图片为我们传过来的第二个参数
            blankButton.setImageDrawable(getResources().getDrawable(image[imageIndex[site]]));
            // 但是,这个控件还是不可见的,设置为可见
            blankButton.setVisibility(View.VISIBLE);
            swap(site, blankSwap);
            // 将新的空白区域位置更新等于传过来的点击的按钮的位置
            blankSwap = site;
            // 将新的空白区域的id更新为传过来的点击的按钮的id
            blankImgid = imagbtnId;
        }
        gameOver();
    }
    // 如果重新开始,我们要还原被点击的图片按钮变成初始化的模样
    public void restore() {
        handler.removeMessages(1);
        // 定义新的imagebutton 等于我们新的空白图片按钮id,并且设置可见,
        ImageButton clickButton = (ImageButton) findViewById(blankImgid);
        clickButton.setVisibility(View.VISIBLE);
        // 定义一个新的图片按钮,然后findviewbyid空白控件的id这个id就是我们初始化的时候设置隐藏的第九章图片
        ImageButton blankButton = (ImageButton) findViewById(R.id.btn_02x02);
        // 但是,这个控件还是不可见的,设置为不可见可见
        blankButton.setVisibility(View.INVISIBLE);
        blankImgid = R.id.btn_02x02;// 初始化时候空白区域的按钮id
        blankSwap = length - 1;
    }
    // 判断拼图是否成功
    public void gameOver() {
        boolean loop = true;
        for (int i = 0; i < imageIndex.length; i++) {
            if (imageIndex[i] != i) {
                loop = false;
            }
        }
        if (loop) {
            // 成功后,时间停止
            timeswitch = false;
            // 玩家拼图成功,禁止图像按钮移动
            button00.setClickable(false);
            button01.setClickable(false);
            button02.setClickable(false);
            button10.setClickable(false);
            button11.setClickable(false);
            button12.setClickable(false);
            button20.setClickable(false);
            button21.setClickable(false);
            button22.setClickable(false);
            button22.setImageDrawable(getResources().getDrawable(image[8]));
            button22.setVisibility(View.VISIBLE);
            handler.removeMessages(1);
            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
            builder.setMessage("恭喜,拼图成功!您用的时间为" + time + "秒").setPositiveButton("确认", null);
            AlertDialog dialog = builder.create();
            dialog.show();
        }
    }
    public void restart(View view) {
        time = 0;
        restore();
        textView.setText("时间:" + time);
        timeswitch = true;
        handler.sendEmptyMessageDelayed(1,1000);
        button00.setClickable(true);
        button01.setClickable(true);
        button02.setClickable(true);
        button10.setClickable(true);
        button11.setClickable(true);
        button12.setClickable(true);
        button20.setClickable(true);
        button21.setClickable(true);
        button22.setClickable(true);
        random();
    }
}

最后运行项目,就能够进行拼图游戏了!效果图如下:

好了,这就是拼图游戏了,在我的项目中,我将神仙姐姐的图片也进行了切隔操作,大家可以试试使用神仙姐姐图片进行编程,感谢您的阅读!

点击下载相关项目代码

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值