Unity3D学习笔记(1) IMGUI小游戏(井字棋)

这次做的井字棋仅采用unity 3D自带的IMGUI。

使用一个10*10的二维数组matrix储存每个格子的状态

private int[,] matrix = new int [10, 10];

为了实现井字棋可由用户设置格子的数目(虽然超过3阶已经不是井字棋了),添加变量

private int scale = 3;  //默认为3

表示n*n的n。

每个格子采用GUI.Button来实现。

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Texture btnTexture;
    void OnGUI() {
        if (!btnTexture) {
            Debug.LogError("Please assign a texture on the inspector");
            return;
        }
        if (GUI.Button(new Rect(10, 10, 50, 50), btnTexture))
            Debug.Log("Clicked the button with an image");

        if (GUI.Button(new Rect(10, 70, 50, 30), "Click"))
            Debug.Log("Clicked the button with text");

    }
}

游戏中设定双方分别为勾方这里写图片描述和叉方这里写图片描述
观察示例,为了让格子显示为空(显示空字符串)和图片
这里写图片描述
需要用到

public static bool Button(Rect position, string text);
public static bool Button(Rect position, Texture image);

两个方法,图片需要的参数类型是Texture,先声明两个Texture变量备用

private Texture gouImg;
private Texture chaImg;

再设置格子位置和大小

private int height = 50, width = 50;    //格子的高度、宽度
private int firstX, firstY; //第一个格子左上角的坐标

为了标记轮流下棋到过程中当前轮到哪一方,用变量

private int turn;

这个变量会应用到matrix数组上,0时表示空,1表示勾方,2表示叉方。
设计函数int win ()返回游戏状态

int win () {   //返回 0-游戏进行 1-勾方赢 2-叉方赢 3-平局
    int first;
    //横
    for (int i=0; i<scale; ++i) {
        first=matrix[i, 0];
        if (first != 0)
            for (int j = 1; j < scale; ++j) {
                if (matrix [i, j] != first)
                    break;
                if (j == scale - 1)
                    return first;
            }
    }
    //纵
    for (int j=0; j<scale; ++j) {
        first=matrix[0, j];
        if (first != 0)
            for (int i = 1; i < scale; ++i) {
                if (matrix [i, j] != first)
                    break;
                if (i == scale - 1)
                    return first;
            }
    }
    //左上到右下对角线
    first = matrix[0, 0];
    if(first!=0)
        for (int i = 1; i < scale; ++i) {
            if (matrix [i, i] != first)
            break;
            if (i == scale - 1)
                return first;
        }
    //右上到左下对角线
    first = matrix[0, scale-1];
    if(first!=0)
        for (int i = 1; i < scale; ++i) {
            if (matrix [i, scale - 1 - i] != first)
                break;
            if (i == scale - 1)
                return first;
        }

    for (int i = 0; i < scale; ++i)
        for (int j = 0; j < scale; ++j)
            if (matrix [i, j] == 0)
                return 0;   //游戏继续
    //格子被填满,平局
    return 3;
}

设计函数bool modi()检查游戏是否已开始,将用于是否显示“重新开始”按钮

扫描二维码关注公众号,回复: 1216207 查看本文章
bool modi () {
    foreach (int i in matrix)
        if (i!=0)
            return true;
    return false;
}

根据MonoBehaviour基本行为的执行顺序,在Awake时进行样式的初始化style用于设置GUI.Label的样式

private GUIStyle style = new GUIStyle ();

void Awake () {
    gouImg = Resources.Load ("勾") as Texture;
    chaImg = Resources.Load ("叉") as Texture;
    style.normal.textColor = Color.white;
    style.alignment = TextAnchor.MiddleCenter;
    style.fontSize = 20;
}

void Reset()用于重置(初始化)游戏状态和实现棋盘居中

void Reset () {
    for(int i=0;i<scale;++i)
        for(int j=0;j<scale;++j)
            matrix[i,j]=0;
    turn = 1;
    firstX = Screen.width / 2 - scale * width / 2;
    firstY = Screen.height / 2 - scale * height / 2;
}

Awake之后的Start调用Reset()

void Start () {
    Reset ();
}

最后实现游戏的主要逻辑,由OnGUI调用,每一帧执行一次,负责交互和状态的维护。采用GUI.TextField读取用户输入

// count为输入框内容,默认为"3"
string count = "3";
void OnGUI () {
    // 设置按钮字体大小
    GUI.skin.button.fontSize = 20;
    // 渲染按钮并响应用户操作
    for (int i = 0; i < scale; ++i)
        for (int j = 0; j < scale; ++j) {
            if (matrix [i, j] == 0)
            if (GUI.Button (new Rect (firstX + width * j, firstY + height * i, width, height), "") && win() == 0) {
                    matrix [i, j] = turn;
                    turn = 3 - turn;
                }
            if (matrix [i, j] == 1)
                GUI.Button (new Rect (firstX + width * j, firstY + height * i, width, height), gouImg);
            if (matrix [i, j] == 2)
                GUI.Button (new Rect (firstX + width * j, firstY + height * i, width, height), chaImg);
        }
    // 游戏开始,显示"重新开始"按钮
    if (modi ())
        if (GUI.Button (new Rect (firstX, firstY + scale * height + 30, width * scale-2, height), "重新开始"))
            Reset ();
    // 根据状态显示提示
    if (win () == 1)
        GUI.Label (new Rect (firstX, firstY - height - 10, width * scale, height), "勾赢了", style);
    else if(win() == 2)
        GUI.Label (new Rect (firstX, firstY - height - 10, width * scale, height), "叉赢了", style);
    else if(win() == 3)
        GUI.Label (new Rect (firstX, firstY - height - 10, width * scale, height), "平局", style);
    // 限定输入最多1位,当用户输入改变并大于1小于10重置游戏,输入不是数字将重置输入框
    count = GUI.TextField(new Rect (firstX+width * scale/2-10, firstY + scale * height +5, 20, 20),count,1);
    int o;
    if (count != scale.ToString () && int.TryParse (count, out o) && o > 1) {
        scale = o;
        Reset ();
    } else if(count!="")
        count = scale.ToString ();
}

猜你喜欢

转载自blog.csdn.net/z_j_q_/article/details/79700865
今日推荐