返回

Android 初学者案例手册:构建一个富有挑战性的华容道拼图游戏

Android

序幕:
欢迎各位亲爱的读者,今天我们继续踏上Android开发之旅,这一次,我们将在前几节课的基础上,将理论付诸实践,构建一个华容道拼图游戏。华容道是一款古老而经典的益智游戏,据说起源于中国古代,游戏规则简单,但要解决却并不容易,它将考验你的逻辑思维能力和策略制定能力,话不多说,让我们开始吧!

第一章:搭建舞台

在开始编码之前,我们需要先搭建一个基本的Android项目,作为我们游戏的舞台。首先,在您的计算机上安装Android Studio,这是一款专为Android开发设计的集成开发环境(IDE)。然后,按照以下步骤创建一个新项目:

  1. 打开Android Studio,点击“新建项目”。
  2. 在“项目模板”中,选择“基本活动”,并输入项目名称和包名。
  3. 选择最低SDK版本,我们建议使用Android 5.0(API 21)或更高版本。
  4. 点击“完成”,您的项目就创建好了。

第二章:定义游戏布局

现在,让我们定义游戏的主界面布局。在res/layout文件夹中创建一个名为“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">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/title"
        android:textSize="24sp"
        android:textStyle="bold" />

    <GridLayout
        android:id="@+id/grid_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnCount="3"
        android:rowCount="3" />

    <Button
        android:id="@+id/reset_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/reset" />

</LinearLayout>

这段代码定义了一个垂直布局(LinearLayout),其中包含一个标题文本视图(TextView)、一个格状布局(GridLayout)和一个重置按钮(Button)。格状布局将用于放置华容道拼图的瓷砖。

第三章:瓷砖的艺术

现在,让我们创建瓷砖。在res/drawable文件夹中创建一个名为“tile.xml”的文件,并输入以下代码:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#ffffff" />

    <corners
        android:radius="10dp" />

</shape>

这段代码定义了一个矩形瓷砖的形状,它具有圆角和白色背景。

第四章:为瓷砖注入生命

现在,我们需要在MainActivity.java文件中编写代码来填充格状布局并使瓷砖可拖动。在MainActivity.java文件中添加以下代码:

public class MainActivity extends AppCompatActivity {

    private GridLayout gridLayout;
    private int[][] tilePositions;
    private Tile[][] tiles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化变量
        gridLayout = findViewById(R.id.grid_layout);
        tilePositions = new int[3][3];
        tiles = new Tile[3][3];

        // 创建瓷砖并填充格状布局
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                Tile tile = new Tile(this);
                tile.setImageDrawable(getDrawable(R.drawable.tile));
                tile.setPosition(i, j);
                tilePositions[i][j] = tile.getPosition();
                tiles[i][j] = tile;
                gridLayout.addView(tile);
            }
        }

        // 设置重置按钮的点击事件
        Button resetButton = findViewById(R.id.reset_button);
        resetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resetGame();
            }
        });
    }

    private void resetGame() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                tiles[i][j].setPosition(i, j);
                tilePositions[i][j] = tiles[i][j].getPosition();
                tiles[i][j].invalidate();
            }
        }
    }

    private class Tile extends ImageView {

        private int position;

        public Tile(Context context) {
            super(context);
        }

        public void setPosition(int i, int j) {
            this.position = i * 3 + j;
        }

        public int getPosition() {
            return this.position;
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startDrag(this);
                    break;
                case MotionEvent.ACTION_MOVE:
                    moveDrag(event);
                    break;
                case MotionEvent.ACTION_UP:
                    stopDrag(this);
                    break;
            }
            return true;
        }
    }
}

这段代码首先初始化了瓷砖的位置和图片,然后将瓷砖添加到格状布局中。它还设置了重置按钮的点击事件,以便在游戏过程中重置拼图。

第五章:瓷砖的舞动

现在,让我们让瓷砖可拖动。在MainActivity.java文件中添加以下代码:

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            startDrag(event);
            break;
        case MotionEvent.ACTION_MOVE:
            moveDrag(event);
            break;
        case MotionEvent.ACTION_UP:
            stopDrag(event);
            break;
    }
    return true;
}

private void startDrag(View view) {
    ClipData data = ClipData.newPlainText("", "");
    DragShadowBuilder shadowBuilder = new DragShadowBuilder(view);
    view.startDrag(data, shadowBuilder, view, 0);
}

private void moveDrag(MotionEvent event) {
    View view = (View) event.getRawX();
    int x = (int) event.getX();
    int y = (int) event.getY();
    view.setPosition(x, y);
}

private void stopDrag(View view) {
    view.clearAnimation();
}

这段代码定义了瓷砖的拖动事件处理程序。当用户按下瓷砖时,它会开始拖动,当用户移动瓷砖时,它会跟随手指移动,当用户松开瓷砖时,它会停止拖动。

第六章:胜利的曙光

现在,我们已经完成了华容道拼图游戏的大部分功能,但我们还需要添加一些逻辑来检测游戏是否已经获胜。在MainActivity.java文件中添加以下代码:

private boolean checkWin() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (tiles[i][j].getPosition() != tilePositions[i][j]) {
                return false;
            }
        }
    }
    return true;
}

这段代码检查瓷砖的位置是否与初始位置相同。如果所有瓷砖都位于其初始位置,则游戏获胜。

第七章:胜利的欢呼

现在,我们已经完成了华容道拼图游戏的所有功能,但我们还需要