【项目说明】

  该项目使用 Unity 实现玩家对战的井字棋,所有 UI 均使用 IMGUI 构建。项目所有资源均已上传至 github ✈️传送门

【游戏简介】

  井字棋(Tic-Tac-Toe)是一种在3*3格子上进行的连珠游戏,由分别代表 O 和 X 的两个玩家轮流在格子里留下标记,任意三个标记形成一条直线,则为获胜。

【实现过程】

  0、创建脚本 TicTacToe.cs,并将该脚本拖到 Unity 场景中的 Main Camera,后续调试均通过运行游戏来完成。

  Unity编程实践——井字棋 - 图1

  1、确定程序框架。

  1. /*渲染棋子的纹理*/
  2. public Texture2D O;//红圈
  3. public Texture2D X;//红叉
  4. public Texture2D Background;//背景
  5. public Texture2D Grid;//网格底图
  6. private bool menu;//表示是否显示游戏主页
  7. public int turn;//表示当前玩家,0 表示玩家 1,其棋子为红圈;1 代表玩家 2,其棋子为红叉
  8. public bool gameover;//表示游戏是否到达结束状态,当一方获胜或双方平局时游戏结束
  9. public bool draw;//表示游戏结果是否为平局
  10. public int[,] grid = new int[3, 3];//表示 3*3 的棋盘的网格的状态。对于网格[i, j](0<=i<3, 0<=j<3)而言,-1 表示还没有玩家占据此处,0 表示玩家 1 占据此处,1 表示玩家 2 占据此处
  11. void Start(){
  12. /*游戏初始化*/
  13. }
  14. void NewGame(){
  15. /*(重新)开始游戏*/
  16. }
  17. void OnGUI(){
  18. /*处理游戏界面及变换*/
  19. }

  2、实现程序框架中的每个函数。

  • 实现游戏的初始化:
  1. void Start() {
  2. menu = true;
  3. NewGame();
  4. }

  游戏初始化时应显示游戏主页,同时初始化游戏状态。

  • 实现游戏的(重新)开始:
  1. void NewGame() {
  2. turn = 0;
  3. gameover = false;
  4. draw = false;
  5. for (int i = 0; i < 3; ++i) {
  6. for (int j = 0; j < 3; ++j) {
  7. grid[i, j] = -1;
  8. }
  9. }
  10. }

  游戏开始时,默认玩家 1 为先手,游戏结束状态与游戏结果平局标志均重置为 false,3*3 的棋盘的所有网格均重置为无人占据状态。

  • 实现游戏界面的处理:
  1. void BackToMenu(){
  2. GUI.Label(new Rect(0, 0, 1024, 685), Background);
  3. GUIStyle fontStyle = new GUIStyle();
  4. fontStyle.normal.textColor = Color.black;
  5. fontStyle.normal.background = null;
  6. fontStyle.fontSize = 80;
  7. GUIStyle fontStyle2 = new GUIStyle();
  8. fontStyle2.normal.textColor = Color.black;
  9. fontStyle2.normal.background = null;
  10. fontStyle2.fontSize = 40;
  11. GUI.Label(new Rect(Screen.width/10 + 80, Screen.height/10 + 45, 200, 50), "Tic Tac Toe", fontStyle);
  12. if (GUI.Button(new Rect(480, 250, 100, 50), "Play", fontStyle2)){
  13. menu = false;
  14. }
  15. }
  16. void OnGUI() {
  17. if (menu){
  18. BackToMenu();
  19. }

  游戏界面分主页和游戏页,通过 menu 变量的值判断显示哪一页。当显示主页时,使用 IMGUI 构建包括背景、“Tic Tac Toe”游戏名称和“Start”按钮的 UI。

  1. else {
  2. GUIStyle fontStyle = new GUIStyle();
  3. fontStyle.normal.textColor = Color.black;
  4. fontStyle.normal.background = null;
  5. fontStyle.fontSize = 25;
  6. GUI.Label(new Rect(0, 0, 1024, 685), Background);
  7. if (GUI.Button(new Rect(450, 160, 100, 50), "Replay", fontStyle))
  8. NewGame();
  9. if (GUI.Button(new Rect(455, 240, 100, 50), "Menu", fontStyle)){
  10. menu = true;
  11. BackToMenu();
  12. NewGame();
  13. }
  14. if ((gameover = Judge()))
  15. ShowResult();
  16. else
  17. ShowTurn();
  18. ShowChessboardAndListen();
  19. }
  20. }

  当显示游戏页时,使用 IMGUI 构建包括背景、“Replay”按钮、“Menu”按钮以及棋盘、游戏状态的 UI。游戏过程中需要处理游戏逻辑,根据当前的游戏情况采取相应的动作:当玩家按下“Replay”按钮时,表示想要重新开始游戏,应调用 NewGame() 重置当前的游戏状态;当游戏结束时,需要在游戏界面显示游戏结果,同时注意在游戏处于结束状态时任一玩家都不能再落子;如果游戏还在进行中,则需要在游戏界面显示当前轮到哪一位玩家落子。最后更新棋盘。

  限于篇幅此处省去对上述逻辑函数的实现描述,细节可参看完整代码及注释

【游戏效果】

  Unity编程实践——井字棋 - 图2

  Unity编程实践——井字棋 - 图3

  Unity编程实践——井字棋 - 图4

  Unity编程实践——井字棋 - 图5

  游戏成果动态展示见TicTacToe