这次的作业要用Unity写一个井字棋游戏,显然,并不需要用到3D,因此只要建一个2D的项目就可以了。要做成一个井字棋游戏,必然用到Unity内置的GUI系统。


1.Unity中GUI的使用

UnityGUI控制是利用一个OnGUI()的函数,这个函数可以在每帧调用,就像是Update函数一样。(因此我们的代码中无需用到Update函数)

再了解下常用的控件:

(1)GUI.Label:

在OnGui中,GUI.Label(new Rect(300,40,40,40),"你好");

Rect设置Label显示的位置,4个参数分别记录X,Y,width,height,第2个参数显示文本内容()

——在井字棋游戏中,这个方法用来显示提示信息

(2)GUI.Button:

在OnGui中,if (GUI.Button(new Rect(300,40,40,40),"你好"))  {...}

通过在OnGui里面判断GUI.Button是否返回true,显示是否按下(当然也可以直接使用)

——在井字棋游戏中,这个方法用于实现游戏的主要部分


在开始写之前,要先把上面两个函数用熟。


2.主要构思

在了解GUI的使用后,就要开始思考实现这个井字棋游戏需要用到什么变量和方法。

变量:

(1)确定每一个格子的状态:一个3*3的数组

(2)确定处于哪一方的回合:一个int变量

方法:

(1)初始化函数:把上面的两个变量都初始化(在Start()函数和)

(2)判断游戏是否结束(我一开始忘了有平局的情况):这个方法我采取的是很笨的办法,其实可能还有更好的算法实现


3.完整代码


把下面的代码挂载在main camera上就能运行。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    public int[,] Status = new int[3, 3];    //0表示还没有选择,1表示√,-1表示×
    public int turn;    //1表示√的回合,-1表示×的回合
    public GUIStyle setStyle = new GUIStyle();	//自己上网查的,用于改GUI.Label()中文字的样式
    void init()
    {
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                Status[i, j] = 0;
            }
        }
        turn = 1;   //√先走
    }
    void Start()
    {
        setStyle.fontSize = 20;
        init();
    }

    void OnGUI()
    {
        if (Result() != 0)
        {
            if (Result() == 1)
            {
                GUI.Label(new Rect(300, 195, 40, 40), "√赢了", setStyle);
            }
            else if (Result() == -1)
            {
                GUI.Label(new Rect(300, 195, 40, 40), "×赢了", setStyle);
            }
            else
            {
                GUI.Label(new Rect(300, 195, 40, 40), "平局了", setStyle);
            }
            turn = 0;
            if (GUI.Button(new Rect(275, 225, 100, 50), "重新开始?"))
            {
                init();
            }
        }
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (Status[i, j] == 1)
                {
                    GUI.Button(new Rect(250 + i * 50, 30 + j * 50, 50, 50), "√");
                    continue;
                }
                if (Status[i, j] == -1)
                {
                    GUI.Button(new Rect(250 + i * 50, 30 + j * 50, 50, 50), "×");
                    continue;
                }
                if (Status[i, j] == 0 && GUI.Button(new Rect(250 + i * 50, 30 + j * 50, 50, 50), ""))
                {
                    if (turn == 1)
                    {
                        Status[i, j] = 1;
                        turn = -1;
                    }
                    else if (turn == -1)
                    {
                        Status[i, j] = -1;
                        turn = 1;
                    }
                }
            }
        }
    }
    //返回1表示√赢,-1表示×赢,0表示还没结束,2表示平局
    int Result()
    {
        if ((Status[0, 0] == Status[0, 1] && Status[0, 0] == Status[0, 2] && Status[0, 2] == Status[0, 1])
            || (Status[0, 0] == Status[1, 0] && Status[0, 0] == Status[2, 0] && Status[1, 0] == Status[2, 0]))
        {
            if (Status[0, 0] == 1)
            {
                return 1;
            }
            else if (Status[0, 0] == -1)
            {
                return -1;
            }
        }
        if ((Status[0, 2] == Status[1, 2] && Status[0, 2] == Status[2, 2] && Status[1, 2] == Status[2, 2])
            || (Status[2, 0] == Status[2, 1] && Status[2, 1] == Status[2, 2] && Status[2, 2] == Status[2, 0]))
        {
            if (Status[2, 2] == 1)
            {
                return 1;
            }
            else if (Status[2, 2] == -1)
            {
                return -1;
            }
        }
        if ((Status[1, 1] == Status[0, 1] && Status[1, 1] == Status[2, 1] && Status[2, 1] == Status[0, 1])
            || (Status[1, 1] == Status[1, 0] && Status[1, 1] == Status[1, 2] && Status[1, 2] == Status[1, 0])
            || (Status[0, 0] == Status[1, 1] && Status[1, 1] == Status[2, 2] && Status[2, 2] == Status[0, 0])
            || (Status[0, 2] == Status[1, 1] && Status[1, 1] == Status[2, 0] && Status[2, 0] == Status[0, 2]))
        {
            if (Status[1, 1] == 1)
            {
                return 1;
            }
            else if (Status[1, 1] == -1)
            {
                return -1;
            }
        }
        if (isTie())
        {
            return 2;
        }
        return 0;
    }

    bool isTie()    
    {
        int sum = 0;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (Status[i, j] != 0)
                {
                    sum++;
                }
            }
        }
        if (sum == 9)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}



4.理解

虽然是很简单的项目,但是可以帮我们熟悉Unity3D的操作,以及OnGUI的使用。

但是,OnGUI在真正开发中用得比较少——“实际项目中,这种方式不够灵活并且执行效率低,一般是采用第三方的NGUI插件来制作游戏界面”。