Unity3D精简版双人井字棋

Posted 2019-10-10Visited

项目地址:https://github.com/liangwj45/Unity-3D/tree/master/HW2

视频链接:https://www.bilibili.com/video/av67336462/

项目目标

  • 熟悉 Unity3D 软件的界面和操作等基本使用;
  • 使用 Unity3D IMGUI 编写一款简单的井字棋游戏;
  • 游戏界面构想:一个 3*3 的棋盘,一个重新开始的按钮以及显示游戏状态的文本框。

游戏界面

游戏思路

创建棋盘

  • 定义一个 3*3 的二维数组用来存储棋盘中棋子的信息
1
private int[,] map = new int[3, 3]; // 记录棋子信息
  • 在 OnGUI()方法中通过两层 for 循环创建出棋盘的 9 个按钮
1
2
3
4
5
6
7
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "")) {
...
}
}
}

创建重置按钮

  • 重置后会调用 Start()方法
1
if (GUI.Button(new Rect(900, 650, 100, 60), "Reset")) Start();

记录下子情况

  • 定义一个 turn 变量用来记录到哪个玩家下子,另外用一个 count 变量来计数
1
public int turn = 1, count = 0;
  • 用户点击棋盘时记录棋子
1
2
3
4
if (GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "")) {
...
map[i, j] = turn; turn = -turn;
}
  • 用户点击棋盘后更新棋盘
1
2
3
4
if (GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "")) {
if (map[i, j] == 1) GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "O", style: style);
else if (map[i, j] == -1) GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "X", style: style);
}
  • 定义字体风格
1
2
3
4
5
GUIStyle style = new GUIStyle();
style.fontSize = 30;
style.alignment = TextAnchor.MiddleCenter;
style.fontStyle = FontStyle.BoldAndItalic;
style.normal.textColor = Color.red;

判断胜负情况

  • 使用一个 3*3 的二维数组计数下子情况:

    • check[0][]:行计数
    • check[1][]:列计数
    • check[2][0]:左上到右下的对角线计数
    • check[2][0]:右上到左下的对角线计数
1
private int[,] check = new int[3, 3]; // 记录胜负情况
  • 每次下子后对应的计数器加上 turn 的值(turn 的值为+1/-1 交替出现),当某个计数器的绝对值等于 3 时,则表明某个玩家胜利,如果 count 计数器值等于 9 时表示平局,用一个 win 变量记录对局情况。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (map[i, j] == 1) GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "O", style: style);
else if (map[i, j] == -1) GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "X", style: style);
if (GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "")) {
if (win > 0) return;
if (System.Math.Abs((check[0, i] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (System.Math.Abs((check[1, j] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (i == j && System.Math.Abs((check[2, 0] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (i + j == 2 && System.Math.Abs((check[2, 1] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (win == 0 && ++count == 9) win = 3;
map[i, j] = turn; turn = -turn;
}
}
}

打印对局情况

1
2
3
if (win == 1) GUI.Label(new Rect(900, 180, 100, 100), "Player1 WIN", style);
else if (win == 2) GUI.Label(new Rect(900, 180, 100, 100), "Player2 WIN", style);
else if (win == 3) GUI.Label(new Rect(900, 180, 100, 100), "TIE", style);

初始化游戏

1
2
3
4
5
6
7
void Start() {
turn = 1; count = 0; win = 0;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j) {
check[i, j] = 0; map[i, j] = 0;
}
}

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using UnityEngine;

public class Main :MonoBehaviour {
private int[,] check = new int[3, 3]; // 记录胜负情况
private int[,] map = new int[3, 3]; // 记录棋子信息
public int turn = 1, count = 0, win = 0;

void Start() {
turn = 1; count = 0; win = 0;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j) {
check[i, j] = 0; map[i, j] = 0;
}
}

private void OnGUI() {
if (GUI.Button(new Rect(900, 650, 100, 60), "Reset")) Start();

GUIStyle style = new GUIStyle();
style.fontSize = 30;
style.alignment = TextAnchor.MiddleCenter;
style.fontStyle = FontStyle.BoldAndItalic;
style.normal.textColor = Color.red;

if (win == 1) GUI.Label(new Rect(900, 180, 100, 100), "Player1 WIN", style);
else if (win == 2) GUI.Label(new Rect(900, 180, 100, 100), "Player2 WIN", style);
else if (win == 3) GUI.Label(new Rect(900, 180, 100, 100), "TIE", style);

for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (map[i, j] == 1) GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "O", style: style);
else if (map[i, j] == -1) GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "X", style: style);
if (GUI.Button(new Rect(i * 100 + 800, j * 100 + 300, 100, 100), "")) {
if (win > 0) return;
if (System.Math.Abs((check[0, i] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (System.Math.Abs((check[1, j] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (i == j && System.Math.Abs((check[2, 0] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (i + j == 2 && System.Math.Abs((check[2, 1] += turn)) == 3) win = turn > 0 ? 1 : 2;
if (win == 0 && ++count == 9) win = 3;
map[i, j] = turn; turn = -turn;
}
}
}
}
}

项目运行

只需在项目中建立一个场景并创建一个空对象,将以上 c# 脚本绑定到该对象中即可,编译运行。