您的位置:首页 > 移动开发 > Unity3D

Unity3D学习笔记(2)——用GUI制作井字棋游戏

2016-03-01 16:36 621 查看
        本来拿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;
}


        好了,井字棋游戏就做好了,本来我还想加个AI,思路挺简单的,在玩家每次点击一个按钮后,首先检查自己有没有赢的可能,再判断玩家有没有赢的可能,有的话直接封住,没有的话优先给自己创造机会。不过想想井字棋9个格就那几种走法,会玩的最后肯定打平,除非要做一个几乎没有边界的棋盘,不过那AI就没那么简单了。最后上一个完整的代码,代码直接作为组件挂载在主摄像机上就能跑了。

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; }
}


        在学习Unity自带的GUI过程中,我发现大家普遍提倡使用Unity的第三方库NGUI来代替GUI,看来NGUI更适合实际的游戏开发。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Unity3D C#