Unity3D筆記(二)使用GUI做井字棋小遊戲

第一次使用unity, 做點事情就比較笨。簡單的事情也做了許久,主要是對unity這個引擎邏輯不熟悉,對C#這個語言的邏輯也不是很熟,走了許多彎路。


開始想的是真的有九個格子那樣的對象,然後有一箇中控對象去負責統計結果,然後發現對象之間的通訊好像還有點麻煩,現在沒有太多時間去深入學習,所以使用了簡單一些的使用方式,全部都是GUI來做,只用一個腳本。
首先就是創建9個格子:

GUI.Button(new Rect(x, y, width, length), ""))

值得注意的是,這個函數,如果這個位置的按鈕不存在那麼就創建這個按鈕,如果這個按鈕已經存在了,那麼就會返回這個按鈕是否被點擊。
所以創建按鈕和檢測按鈕是否被點擊都寫在一起,寫在onGUI中。

// draw the chess table on each frame
for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j) {
        switch (state [i, j]) {
            case 0:
                    if (GUI.Button (new Rect (i * 50 + xMove, j * 50 + yMove, 50, 50), ""))
                        click (i, j);
                    break;
                case 1:
                    if (GUI.Button (new Rect (i * 50 + xMove, j * 50 + yMove, 50, 50), "O"))
                        click (i, j);
                    break;
                case 2:
                    if (GUI.Button (new Rect (i * 50 + xMove, j * 50 + yMove, 50, 50), "X"))
                        click (i, j);
                    break;
                default:
                    break;
                }
            }

這裏的state是一個3x3二維數組,用於儲存當前遊戲的狀態,同時根據當前遊戲狀態畫出不同的方格。
若被點擊則調用click進行處理。
reset按鈕就是通過恢復state數組使得下一楨的UI回覆到最初的樣子。
勝利信息通過GUI.label顯示出來。

public static void Label(Rect position, string text);
public static void Label(Rect position, Texture image);
public static void Label(Rect position, GUIContent content);
public static void Label(Rect position, string text, GUIStyle style);
public static void Label(Rect position, Texture image, GUIStyle style);
public static void Label(Rect position, GUIContent content, GUIStyle style);

遊戲中的代碼如下:

if (whetherEqual) {
            GUI.Label (new Rect (xMove, 170 + yMove, 200, 100), "No winner here, press Restart!");
        }
        else if (whetherEnd) {
            char winner = (turn == 2) ? 'O' : 'X';
            GUI.Label (new Rect (xMove, 170 + yMove, 200, 100), winner + " win! press restart to start over");
        }

至於判斷邏輯就不多說了,畢竟不是這裏的重點。


附完整代碼:
chess.cs 掛在主攝影機上即可運行

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

public class Chess : MonoBehaviour
{
    /* 0 for no chess
     * 1 for player1
     * 2 for player2
     */
    private int[,] state = new int[3, 3];
    /* switch turn
     * 1 for player1
     * 2 for player2
     */
    private int turn = 1;
    private bool whetherEnd = false;
    private bool whetherEqual = false;
    private int xMove = 350;
    private int yMove = 150;
    // Use this for initialization
    void Start ()
    {
        init ();
        Camera view = GetComponent<Camera> ();
        view.backgroundColor = Color.white;
    }

    void OnGUI ()
    {
        GUI.backgroundColor = Color.white;
        // reset button
        if (GUI.Button (new Rect (25 + xMove, 250 + yMove, 100, 50), "Restart")) {
            init ();
            return;
        }
        // draw the chess table on each frame
        for (int i = 0; i < 3; ++i)
            for (int j = 0; j < 3; ++j) {
                switch (state [i, j]) {
                case 0:
                    if (GUI.Button (new Rect (i * 50 + xMove, j * 50 + yMove, 50, 50), ""))
                        click (i, j);
                    break;
                case 1:
                    if (GUI.Button (new Rect (i * 50 + xMove, j * 50 + yMove, 50, 50), "O"))
                        click (i, j);
                    break;
                case 2:
                    if (GUI.Button (new Rect (i * 50 + xMove, j * 50 + yMove, 50, 50), "X"))
                        click (i, j);
                    break;
                default:
                    break;
                }
            }
        GUI.color = Color.black;
        if (whetherEqual) {
            GUI.Label (new Rect (xMove, 170 + yMove, 200, 100), "No winner here, press Restart!");
        }
        else if (whetherEnd) {
            char winner = (turn == 2) ? 'O' : 'X';
            GUI.Label (new Rect (xMove, 170 + yMove, 200, 100), winner + " win! press restart to start over");
        }

    }

    void click (int x, int y)
    {
        if (state [x, y] == 0 && !whetherEnd) {
            state [x, y] = turn;
            checkWhetherWin (x, y);
            turn = (turn == 2) ? 1 : 2;
        }
    }

    void checkWhetherWin (int x, int y)
    {
        // horizontal
        if (state [x, 0] == state [x, 1] && state [x, 1] == state [x, 2]) {
            whetherEnd = true;
            Debug.Log ("win at horizontal");
        }
        // vertical
        if (state [0, y] == state [1, y] && state [1, y] == state [2, y]) {
            whetherEnd = true;
            Debug.Log ("win at vertical");
        }
        // diagonal
        bool flag = true;
        for (int i = 0; i < 3; ++i) {
            if (state [i, i] != state [x, y])
                flag = false;
        }
        if (flag == true) {
            whetherEnd = true;
            Debug.Log ("win at diagonal 1");
        }
        flag = true;
        for (int i = 2; i > -1; --i) {
            if (state [2 - i, i] != state [x, y])
                flag = false;
        }
        if (flag == true) {
            whetherEnd = true;
            Debug.Log ("win at diagonal 2");
        }
        flag = true;
        for (int i = 0; i < 3; ++i)
            for (int j = 0; j < 3; ++j) {
                if (state [i, j] == 0)
                    flag = false;
            }
        if (flag) {
            whetherEnd = true;
            whetherEqual = true;
        }
    }
    // init all things when restart button pressed
    void init ()
    {
        Debug.Log ("chess start");
        for (int i = 0; i < 3; ++i)
            for (int j = 0; j < 3; ++j)
                state [i, j] = 0;
        whetherEnd = false;
        whetherEqual = false;
        turn = 1;
    }
}
發佈了24 篇原創文章 · 獲贊 9 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章