在这篇博客中,我们将介绍一个基于Unity的五子棋游戏的实现。以下是该游戏的主要脚本的源代码,我们将逐个解析其主要组成部分。
1. 初始化变量
游戏的主要逻辑在 Gomoku
类中定义。在此类中,我们首先定义了一些预设的游戏变量和UI资源:
// Entities and their states / Model
private static int player; // 1 for Black, 2 for White
private static int count;
private int winner;
private int[,] chessBoard = new int[15, 15];
// UI resources
public Texture2D blackStone;
public Texture2D whiteStone;
public Texture2D woodTexture;
private Texture2D transparentTexture;
在这里,player
用于记录当前玩家(黑色为 1,白色为 2),count
用于记录已经下过的棋子数量,winner
用于记录游戏的获胜者,chessBoard
是一个15x15的矩阵,用于记录棋盘上的棋子状况。blackStone
,whiteStone
和 woodTexture
是预设的UI资源,分别代表黑子,白子和棋盘的纹理。
2. 开始游戏
在 Start
方法中,我们进行了一个简单的游戏初始化:
void Start()
{
Init();
transparentTexture = new Texture2D(1, 1);
transparentTexture.SetPixel(0, 0, new Color(0, 0, 0, 0));
transparentTexture.Apply();
}
在这里,Init
方法将所有游戏变量重置到其初始状态,包括清空棋盘和设置当前玩家为黑色。然后我们创建了一个透明的纹理,用于实现透明的棋盘按钮。
3. 游戏逻辑
游戏的主要逻辑包括:渲染棋盘,处理玩家的输入,判断游戏结束条件。
在 OnGUI
方法中,我们首先渲染了一个棋盘,并添加了一个"Restart"按钮以便玩家随时重启游戏。然后我们遍历棋盘上的每一个位置,如果该位置为空,我们就在该位置添加一个透明的按钮,当玩家点击该按钮时,就在该位置下一个棋子(并将当前玩家切换到另一方);如果该位置已经有棋子,我们就在该位置绘制对应颜色的棋子。
在 GameOver
方法中,我们检查了所有可能的五子连线(包括横线、竖线、斜线),如果找到了五子连线,就宣布对应颜色的玩家获胜;如果棋盘已经被填满但还没有五子连线,那么游戏就是平局。
4. 重启游戏
在 Init
方法中,我们清空了棋盘,设置当前玩家为黑色,重置了获胜者和棋子数量:
public void Init()
{
player = 1;
winner = 0;
count = 0;
chessBoard = new int[15, 15]; // 初始化数组
for (int i = 0; i < 15; i++)
for (int j = 0; j < 15; j++)
chessBoard[i, j] = 0;
}
这样,每当玩家点击"Restart"按钮,游戏就会重置到初始状态。
这就是我们的Unity五子棋游戏的主要实现。通过这个项目,我们可以看到Unity的强大和灵活,它不仅可以用来开发复杂的3D游戏,也非常适合用来开发简单的2D棋类游戏。希望你能够从这个项目中得到启发,开发出更多有趣的游戏!
5. 下棋的逻辑
在 PutChess
方法中,我们首先在选定的位置放下棋子,然后切换当前玩家,并增加游戏的棋子数量:
public void PutChess(int i, int j)
{
chessBoard[i, j] = player;
player = 3 - player;
count += 1;
}
6. 游戏结束的判断
在 GameOver
方法中,我们进行了游戏结束的判断。判断的依据是横、竖、斜三个方向上是否出现五子连线,或者棋盘已经被填满:
public bool GameOver()
{
// Check rows, columns and diagonals...
return model.count == 225; // If all spaces are filled, the game is over
}
一旦游戏结束,我们将显示一个提示框,提示哪个玩家获胜,或者游戏是平局。
7.mvc分离实现
该游戏设计实现了mvc分离的思想,其中Gomoku类定义模型数据,包括当前棋盘情况,游戏胜者等;GomokuController类定义控制逻辑,包括根据用户点击的位置落子,以及判断游戏是否结束等;GomokuView类定义用户界面元素,如渲染棋盘、棋子,以及在游戏结束时显示相关信息等。
完整代码:
Gomoku.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gomoku : MonoBehaviour
{
public int player;
public int winner;
public int[,] chessBoard;
public int count;
public void Init()
{
player = 1;
winner = 0;
count = 0;
chessBoard = new int[15, 15]; // 初始化数组
for (int i = 0; i < 15; i++)
for (int j = 0; j < 15; j++)
chessBoard[i, j] = 0;
}
void Start()
{
Init();
}
public void PutChess(int i, int j)
{
chessBoard[i, j] = player;
player = 3 - player;
count += 1;
}
}
GomokuController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GomokuController : MonoBehaviour
{
public Gomoku model;
public bool gameover;
void Start()
{
model = GetComponent<Gomoku>();
gameover = false;
}
void OnGUI()
{
if (!GameOver())
{
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
if (model.chessBoard[i, j] == 0 && GUI.Button(new Rect(100 + j * 45, 100 + i * 45, 45, 45), ""))
{
model.PutChess(i, j);
}
}
}
}
else
{
if (GUI.Button(new Rect(400, 820, 100, 30), "Restart")) model.Init();
gameover = true;
}
}
public bool GameOver()
{
// Check rows
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 11; j++)
{
if (model.chessBoard[i, j] != 0 && model.chessBoard[i, j] == model.chessBoard[i, j + 1] && model.chessBoard[i, j] == model.chessBoard[i, j + 2] && model.chessBoard[i, j] == model.chessBoard[i, j + 3] && model.chessBoard[i, j] == model.chessBoard[i, j + 4])
{
model.winner = model.chessBoard[i, j];
return true;
}
}
}
// Check columns
for (int j = 0; j < 15; j++)
{
for (int i = 0; i < 11; i++)
{
if (model.chessBoard[i, j] != 0 && model.chessBoard[i, j] == model.chessBoard[i + 1, j] && model.chessBoard[i, j] == model.chessBoard[i + 2, j] && model.chessBoard[i, j] == model.chessBoard[i + 3, j] && model.chessBoard[i, j] == model.chessBoard[i + 4, j])
{
model.winner = model.chessBoard[i, j];
return true;
}
}
}
// Check diagonals
for (int i = 0; i < 11; i++)
{
for (int j = 0; j < 11; j++)
{
if (model.chessBoard[i, j] != 0 && model.chessBoard[i, j] == model.chessBoard[i + 1, j + 1] && model.chessBoard[i, j] == model.chessBoard[i + 2, j + 2] && model.chessBoard[i, j] == model.chessBoard[i + 3, j + 3] && model.chessBoard[i, j] == model.chessBoard[i + 4, j + 4])
{
model.winner = model.chessBoard[i, j];
return true;
}
}
}
for (int i = 4; i < 15; i++)
{
for (int j = 0; j < 11; j++)
{
if (model.chessBoard[i, j] != 0 && model.chessBoard[i, j] == model.chessBoard[i - 1, j + 1] && model.chessBoard[i, j] == model.chessBoard[i - 2, j + 2] && model.chessBoard[i, j] == model.chessBoard[i - 3, j + 3] && model.chessBoard[i, j] == model.chessBoard[i - 4, j + 4])
{
model.winner = model.chessBoard[i, j];
return true;
}
}
}
return model.count == 225; // If all spaces are filled, the game is over
}
}
GomokuView.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GomokuView : MonoBehaviour
{ private Gomoku model;
private GomokuController controller;
// UI resources
public Texture2D blackStone;
public Texture2D whiteStone;
public Texture2D woodTexture;
public Texture2D transparentTexture;
void Start()
{
controller = GetComponent<GomokuController>();
model = controller.model;
transparentTexture = new Texture2D(1, 1);
transparentTexture.SetPixel(0, 0, new Color(0, 0, 0, 0));
transparentTexture.Apply();
}
// View render entities / models
void OnGUI()
{
GUI.DrawTexture(new Rect(100, 100, 675, 675), woodTexture);
if (controller.gameover == false)
{
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
buttonStyle.normal.background = transparentTexture;
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
if (model.chessBoard[i, j] == 1)
{
GUI.DrawTexture(new Rect(100 + j * 45, 100 + i * 45, 45, 45), blackStone);
}
if (model.chessBoard[i, j] == 2)
{
GUI.DrawTexture(new Rect(100 + j * 45, 100 + i * 45, 45, 45), whiteStone);
}
}
}
}
else
{
if (model.winner != 0)
GUI.Box(new Rect(350, 350, 200, 200), "\n\nCongratulations!\nPlayer " + (model.winner == 1 ? "Black" : "White") + " has won.");
else
GUI.Box(new Rect(350, 350, 200, 200), "\n\nThis is a draw!");
}
}
}
这就是我们的Unity五子棋游戏的实现详情。通过这个简单的示例,我们可以看到Unity强大的2D游戏开发能力,以及C#语言的灵活性和易用性。希望你能从这个项目中得到启发,开发出更多有趣的游戏!