本来拿gui来做游戏蛮怪的,但这却是一个熟悉gui的不错的途径。今天我就学着使用GUI.Button做了一个十分简单的井字棋游戏。上个成品图:
首先创建一个C#脚本文件,去掉Update方法,因为这里我不会用到它。然后添加OnGUI方法。声明两个私有变量,一个用来记录是谁的回合, 假定turn为1是圈圈的回合,turn为-1是叉叉的回合。另一个变量为3*3的二维数组,用来记录当前九宫格的状态,假定1代表格子里是圈圈,2代表格子里是叉叉。函数reset用来初始化个参数,在脚本被调用时(Start)执行一次。
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
private int turn = 1; //记录是谁的回合
private int[,] state = new int[3,3]; //九方格数据
//参数初始化
void Start() {
reset();
}
void OnGUI() {
}
//重置参数
void reset() {
turn = 1;
for (int i=0; i<3; ++i) {
for (int j=0; j<3; ++j) {
state[i,j] = 0;
}
}
}
}
接着在OnGUI里面用一个两重循环添加出九宫格Button。为了让button点击时能发生变化(修改button的text),开始我以为能通过获得button的对象,然后通过对象的OnClick事件来处理,但查阅了资料发现几乎不可能做到,后来发现OnGUI类似一个绘图的方法,每一帧都会清理掉上一帧的所有对象,即刷屏。因此必须另外想办法。而这个办法便是使用state二维数组记录九宫格的状态。除此之外,必须添加一个check方法来决定游戏是否结束,一旦游戏结束,那么就需要一个Label来显示游戏结果,并且不再允许玩家点击Buttons。Reset按钮可以重置游戏,即调用reset方法。
void OnGUI() {
if (GUI.Button(new Rect(20,300,100,50),"Reset"))
reset();
int result = check(); // 返回0代表游戏没有结束,1代表圈圈赢,2代表叉叉赢。
if (result==1) {
GUI.Label(new Rect(50,230,100,50),"O wins!");
}
else if (result==2) {
GUI.Label(new Rect(50,230,100,50),"X wins!");
}
for (int i=0; i<3; ++i) {
for (int j=0; j<3; ++j) {
if (state[i,j]==1)
GUI.Button(new Rect(i*50,j*50,50,50),"O");
if (state[i,j]==2)
GUI.Button(new Rect(i*50,j*50,50,50),"X");
if(GUI.Button(new Rect(i*50,j*50,50,50),"")) {
if (result==0) {
if (turn == 1)
state[i,j] = 1;
else
state[i,j] = 2;
turn = -turn;
}
}
}
}
}
查看游戏是否结束,无非就是看有没有连成一线的圈圈或者叉叉。粗暴一点的办法就是列出所有可能的情况,简单一点的就可以使用循环,先横向一排排看过去,再纵向一列列看过去,有一样的非零状态就直接返回该状态即可。最后再看看斜向的两种情况,一样且非零的话直接返回中间交点的状态值就可以了。
//判断游戏结束条件
int check() {
// 横向连线
for (int i=0; i<3; ++i) {
if (state[i,0]!=0 && state[i,0]==state[i,1] && state[i,1]==state[i,2]) {
return state[i,0];
}
}
//纵向连线
for (int j=0; j<3; ++j) {
if (state[0,j]!=0 && state[0,j]==state[1,j] && state[1,j]==state[2,j]) {
return state[0,j];
}
}
//斜向连线
if (state[1,1]!=0 &&
state[0,0]==state[1,1] && state[1,1]==state[2,2] ||
state[0,2]==state[1,1] && state[1,1]==state[2,0]) {
return state[1,1];
}
return 0;
}
using UnityEngine;
using System.Collections;
public class jingziqi : MonoBehaviour {
private int turn = 1; //记录是谁的回合
private int[,] state = new int[3,3]; //九方格数据
//参数初始化
void Start() {
reset();
}
void OnGUI() {
if (GUI.Button(new Rect(20,300,100,50),"Reset"))
reset();
int result = check();
if (result==1) {
GUI.Label(new Rect(50,230,100,50),"O wins!");
}
else if (result==2) {
GUI.Label(new Rect(50,230,100,50),"X wins!");
}
for (int i=0; i<3; ++i) {
for (int j=0; j<3; ++j) {
if (state[i,j]==1)
GUI.Button(new Rect(i*50,j*50,50,50),"O");
if (state[i,j]==2)
GUI.Button(new Rect(i*50,j*50,50,50),"X");
if(GUI.Button(new Rect(i*50,j*50,50,50),"")) {
if (result==0) {
if (turn == 1)
state[i,j] = 1;
else
state[i,j] = 2;
turn = -turn;
}
}
}
}
}
//重置参数
void reset() {
turn = 1;
for (int i=0; i<3; ++i) {
for (int j=0; j<3; ++j) {
state[i,j] = 0;
}
}
}
//判断游戏结束条件
int check() {
// 横向连线
for (int i=0; i<3; ++i) {
if (state[i,0]!=0 && state[i,0]==state[i,1] && state[i,1]==state[i,2]) {
return state[i,0];
}
}
//纵向连线
for (int j=0; j<3; ++j) {
if (state[0,j]!=0 && state[0,j]==state[1,j] && state[1,j]==state[2,j]) {
return state[0,j];
}
}
//斜向连线
if (state[1,1]!=0 &&
state[0,0]==state[1,1] && state[1,1]==state[2,2] ||
state[0,2]==state[1,1] && state[1,1]==state[2,0]) {
return state[1,1];
}
return 0;
}
}