Unity3D 实践学习1 GUI井字棋的实现

     这是我学Unity3D的第一个小游戏,挺简单的,代码量也不多,参考博客是 UNITY3D学习(1)之GUI井字棋。对于Unity3D,想必大家都比较熟悉了的,我就不多作介绍了。需要了解Unity3D的,可以去这个博客——【Unity3D入门教程】Unity3D简介、安装和程序发布

     好了,闲话就不说了,先来看看成品:
这里写图片描述

     首先就是游戏背景,在这次项目中呢,背景其实是有点水分的。就是Create一个plane,然后,用一张贴图贴在plane上,再将摄像机的镜头对准平面就好了,就这么伪装出了一个背景。当然,你要是觉得这样子操作麻烦,也可以用代码实现。代码如下:

 public Texture2D img;
 GUIStyle bground = new GUIStyle();
 bground.normal.background = img;
 GUI.Label(new Rect(0, 0, Screen.width, Screen.height), "", bground);

     后面就都是代码实现就好了。先是在Asserts里面创建一个一个C#文件(最好还是讲将资源归类,即在Asserts下面创建一个Scripts文件夹,再将C#文件放在Scripts里面)。

下面对代码实现说明一下过程:
     首先,就是实现一个ResetMap()函数,用于放在Start()中将棋盘初始化,同时也用在Reset按钮中,实现棋盘的初始化。代码实现很简单,就是开一个3*3的数组,将里面的元素全部初始化为0就好。如下:

    /// <summary>
    /// 重置地图(全为0)
    /// </summary>
    void ResetMap()
    {
        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                map[i, j] = 0;
            }
        }
    }

     其次,写一个WhetherWin()函数,用来判定游戏是否已经结束了,并且给出是蓝方赢了还是红方赢了。判定的方法也很简单,就判断数组行、列或对角是否三个数相等即可。具体代码如下:

    /// 判断游戏是否结束
    /// </summary>
    /// <returns>1表示蓝方赢,2表示红方赢</returns>
    private int WhetherWin()
    {
        for(int i = 0; i < 3; i++)
        {
            if(map[i, 0] == map[i, 1] && map[i, 1] == map[i, 2] && map[i, 0] != 0)
            {
                return map[i, 0];
            }
        }
        for(int j = 0; j < 3; j++)
        {
            if(map[0, j] == map[1, j] && map[1, j] == map[2, j] && map[0, j] != 0)
            {
                return map[0, j];
            }
        }
        if(map[0, 0] == map[1, 1] && map[1, 1] == map[2, 2] && map[0, 0] != 0)
        {
            return map[0, 0];
        }
        if(map[0, 2] == map[1, 1] && map[1, 1] == map[2, 0] && map[1, 1] != 0)
        {
            return map[1, 1];
        }
        return 0;
    }

     最后,就是完成OnGUI()方法就好了。主要的做法,就是做出一个由九个Label组装成的九宫格,每个Label分别对应map数组中的每个元素。例如,当map[0, 0]中的值为0时,表示这个地方还为被占领,当值为1时,表示已经被蓝方占领了,当值为2时,表示已经被红方占领了。每一次鼠标点击Label,若对应数组元素的值为0,就把该处的值赋值为1或者2,并在每帧图像中对已经被占领了的Label加上背景,作为占领的标志。具体的实现如下:

        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                float x = midWidth - 1.5f * buttonEdge + j * buttonEdge;
                float y = midHeight - 1.5f * buttonEdge + i * buttonEdge;
                if ( map[i, j] == 1)
                {
                    GUI.Button(new Rect(x, y, buttonEdge, buttonEdge), img_0);
                }
                else if(map[i, j] == 2)
                {
                    GUI.Button(new Rect(x, y, buttonEdge, buttonEdge), img_1);
                }
                else
                {
                    if(GUI.Button(new Rect(x, y, buttonEdge, buttonEdge), ""))
                    {
                        if(player % 2 == 0)
                        {
                            map[i, j] = 1;
                        }
                        else
                        {
                            map[i, j] = 2;
                        }
                        player = (player + 1) % 2;
                    }
                }
            }

     在这次项目中,主要用到的是GUI控件中的Label和Button,关于这两个控件的具体用法,可参考这个博客——Unity3D入门篇——第三讲 GUI控件(一)
     核心的逻辑大概就是这些啦。至于具体的UI要设置成什么样子,可以在了解了这些控件的用法后,实现成自己想要的那个样子。
     当然,既然是游戏,就肯定不能就这么一个画面,肯定要加一点声音上去的。找一个游戏对象(在这里就只有摄影机和平面了),然后,AddComponent -> Audio ->Audio Source。接下来,如图:
这里写图片描述
     接着,在摄像机这个对象上,AddComponent -> Audio -> Audio Listener,游戏就会有背景音乐了。要是需要对音频有更高的要求,可以参考博客——关于Unity中3D声音的使用

     接下来就说一下贴图怎么放进去吧。虽然这个挺简单的,当时自己也找了挺久才知道怎么弄。由于我们把C#文件绑定在了摄像机上,在摄像机的C#文件组件中,我们可以看到下面这样:
这里写图片描述
     然后,就是一样的套路,点击箭头所指的那里,添加textures就行了。

      至此,我的第一个小项目就完成了,下面附上完成的代码:

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

public class GameScense : MonoBehaviour {
    //地图。 0表示未被占据,1 表示蓝色方占据, 2表示红色方占据
    private int[,] map = new int[3, 3];
    private int player = 0;
    public AudioClip audio; //开始的音乐
    private AudioSource audioSource;
    //玩家图片
    public Texture2D img_0;
    public Texture2D img_1;

    /// <summary>
    /// 重置地图(全为0)
    /// </summary>
    void ResetMap()
    {
        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                map[i, j] = 0;
            }
        }

        audioSource.Play();
        //startAudio.gameObject.GetComponent<AudioSource>().Play();
    }
    private void Awake()
    {//设置AudioSource组件
        audioSource = this.gameObject.GetComponent<AudioSource>();
        audioSource.loop = false;
        audioSource.volume = 1.0f;
        audioSource.clip = audio;
    }

    // Use this for initialization
    void Start () {
        ResetMap();    
    }

    /// <summary>
    /// 判断游戏是否结束
    /// </summary>
    /// <returns>1表示蓝方赢,2表示红方赢</returns>
    private int WhetherWin()
    {
        for(int i = 0; i < 3; i++)
        {
            if(map[i, 0] == map[i, 1] && map[i, 1] == map[i, 2] && map[i, 0] != 0)
            {
                return map[i, 0];
            }
        }
        for(int j = 0; j < 3; j++)
        {
            if(map[0, j] == map[1, j] && map[1, j] == map[2, j] && map[0, j] != 0)
            {
                return map[0, j];
            }
        }
        if(map[0, 0] == map[1, 1] && map[1, 1] == map[2, 2] && map[0, 0] != 0)
        {
            return map[0, 0];
        }
        if(map[0, 2] == map[1, 1] && map[1, 1] == map[2, 0] && map[1, 1] != 0)
        {
            return map[1, 1];
        }
        return 0;
    }
    //用屏幕的高度作为度量单位来处理屏幕大小不同而导致的问题
    private void OnGUI()
    {
        int midWidth = Screen.width / 2;
        int midHeight = Screen.height / 2;
        int buttonEdge = Screen.height / 5;
        GUIStyle fontStyle_0 = new GUIStyle();
        fontStyle_0.fontSize = buttonEdge / 2;
        fontStyle_0.fontStyle = FontStyle.Bold;
        fontStyle_0.normal.textColor = Color.black;

        GUIStyle fontStyle_1 = new GUIStyle();
        fontStyle_1.fontSize = buttonEdge /2;
        fontStyle_1.fontStyle = FontStyle.Bold;
        fontStyle_1.normal.textColor = Color.blue;

        GUIStyle fontStyle_2 = new GUIStyle();
        fontStyle_2.fontSize = buttonEdge / 2;
        fontStyle_2.fontStyle = FontStyle.Bold;
        fontStyle_2.normal.textColor = Color.red;

        GUI.Label(new Rect(midWidth - buttonEdge * 4, midHeight - 1.5f * buttonEdge, 1.5f * buttonEdge, 1.5f * buttonEdge), img_0);
        GUI.Label(new Rect(midWidth - buttonEdge * 4, midHeight, 1.5f * buttonEdge, buttonEdge), "Blue", fontStyle_1);
        GUI.Label(new Rect(midWidth + buttonEdge * 3, midHeight - 1.5f * buttonEdge, 1.5f * buttonEdge, 1.5f * buttonEdge), img_1);
        GUI.Label(new Rect(midWidth + buttonEdge * 3, midHeight, 1.5f * buttonEdge, buttonEdge), "Red", fontStyle_2);

        int winner = WhetherWin();
    //    Debug.Log(winner);
        if(winner == 1)
        {
            if (GUI.Button(new Rect(midWidth - buttonEdge * 1.5f, 0.5f * buttonEdge, 3 * buttonEdge, 3.5f * buttonEdge), "Blue Win", fontStyle_1))
            {
                ResetMap();
            }
        }
        else if(winner == 2)
        {
            if (GUI.Button(new Rect(midWidth - buttonEdge * 1.5f,0.5f * buttonEdge, 3 * buttonEdge, 3.5f * buttonEdge), "Red Win", fontStyle_2))
            {
                ResetMap();
            }
        }
        else
        {
            GUI.Label(new Rect(midWidth - buttonEdge * 2.5f, buttonEdge / 4, buttonEdge * 2, buttonEdge), "Welcome To Tictactoe", fontStyle_0);
        }

        if(GUI.Button(new Rect(midWidth - 0.5f*buttonEdge, midHeight + 1.75f*buttonEdge, buttonEdge, 0.5f*buttonEdge), "Reset"))
        {
            ResetMap();
        }

        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                float x = midWidth - 1.5f * buttonEdge + j * buttonEdge;
                float y = midHeight - 1.5f * buttonEdge + i * buttonEdge;
                if ( map[i, j] == 1)
                {
                    GUI.Button(new Rect(x, y, buttonEdge, buttonEdge), img_0);
                }
                else if(map[i, j] == 2)
                {
                    GUI.Button(new Rect(x, y, buttonEdge, buttonEdge), img_1);
                }
                else
                {
                    if(GUI.Button(new Rect(x, y, buttonEdge, buttonEdge), ""))
                    {
                        if(player % 2 == 0)
                        {
                            map[i, j] = 1;
                        }
                        else
                        {
                            map[i, j] = 2;
                        }
                        player = (player + 1) % 2;//改变玩家角色
                    }
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/ShenDW818/article/details/79689656
今日推荐