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)执行一次。
接着在OnGUI里面用一个两重循环添加出九宫格Button。为了让button点击时能发生变化(修改button的text),开始我以为能通过获得button的对象,然后通过对象的OnClick事件来处理,但查阅了资料发现几乎不可能做到,后来发现OnGUI类似一个绘图的方法,每一帧都会清理掉上一帧的所有对象,即刷屏。因此必须另外想办法。而这个办法便是使用state二维数组记录九宫格的状态。除此之外,必须添加一个check方法来决定游戏是否结束,一旦游戏结束,那么就需要一个Label来显示游戏结果,并且不再允许玩家点击Buttons。Reset按钮可以重置游戏,即调用reset方法。
查看游戏是否结束,无非就是看有没有连成一线的圈圈或者叉叉。粗暴一点的办法就是列出所有可能的情况,简单一点的就可以使用循环,先横向一排排看过去,再纵向一列列看过去,有一样的非零状态就直接返回该状态即可。最后再看看斜向的两种情况,一样且非零的话直接返回中间交点的状态值就可以了。
好了,井字棋游戏就做好了,本来我还想加个AI,思路挺简单的,在玩家每次点击一个按钮后,首先检查自己有没有赢的可能,再判断玩家有没有赢的可能,有的话直接封住,没有的话优先给自己创造机会。不过想想井字棋9个格就那几种走法,会玩的最后肯定打平,除非要做一个几乎没有边界的棋盘,不过那AI就没那么简单了。最后上一个完整的代码,代码直接作为组件挂载在主摄像机上就能跑了。
在学习Unity自带的GUI过程中,我发现大家普遍提倡使用Unity的第三方库NGUI来代替GUI,看来NGUI更适合实际的游戏开发。
首先创建一个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更适合实际的游戏开发。
相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- c#调用COM组件
- C#实现把指定数据写入串口
- C#动态创建button的方法
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#实现给图片加水印的方法
- C#使用加边法计算行列式的值
- C#实现多线程的同步方法实例分析
- C#中尾递归的使用、优化及编译器优化
- C#中的delegate委托类型基本学习教程
- C#实现子窗体与父窗体通信方法实例总结
- C#通用邮件发送类分享
- 举例讲解C#中自动实现的属性
- C#中this的用法集锦
- C#数据结构之顺序表(SeqList)实例详解
- C#.NET获取拨号连接的宽带连接方法
- C#异步绑定数据实现方法
- C#实现AddRange为数组添加多个元素的方法