Unity3D学习笔记(1) IMGUI小游戏(井字棋)
程序员文章站
2022-03-26 15:56:07
...
这次做的井字棋仅采用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()
检查游戏是否已开始,将用于是否显示“重新开始”按钮
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 ();
}