- 游戏内容: 井字棋 或 贷款计算器 或 简单计算器 等等
- 技术限制: 仅允许使用 IMGUI 构建 UI
- 项目目的:提升 debug 能力,提升阅读 API 文档能力
1.井字棋简介(维基百科)
1.玩法
两个玩家,一个打圈(◯),一个打叉(✗),轮流在3乘3的格上打自己的符号,最先以横、直、斜连成一线则为胜。
如果双方都下得正确无误,将得和局。
这种游戏实际上是由第一位玩家所控制,第一位玩家是攻,第二位玩家是守。
第一位玩家在角位行第一子的话赢面最大(见下图),第二位玩家若是在边,角位下子,第一位玩家就可以以两粒连线牵制着第二位玩家,然后制造“两头蛇”,所以他必须下中央。如第一位玩家下在中央,则第二位玩家必须下在角位才不会输。如第一位玩家下在边位,第二位玩家可以下在中央或角位,或是与第一位玩家下的位置相对的边位。
2.人工智能
这种游戏的变化简单,常成为博弈论和游戏树搜寻的教学例子。这个游戏只有765个可能局面,26830个棋局。如果将对称的棋局视作不同,则有255168个棋局。
由于这种游戏的结构简单,早期这游戏就成为了人工智能的一个好题目。学生都要从既有的玩法中,归纳出游戏的致胜之道,并将策略演绎成为程式,让电脑与用户对弈。
1950年制作的游戏《Bertie the Brain》是早期电子游戏史最初的游戏之一,该游戏便是和人工智能对弈井字棋。
世界上最早的电脑游戏之一,1952年为EDSAC电脑制作的《OXO》游戏,就是以该游戏为题材,可以正确无误地与人类对手下棋。
2.Immediate Mode GUI (IMGUI)
The “Immediate Mode” GUI system (also known as IMGUI) is an entirely separate feature to Unity’s main GameObject-based UI System.
直接模式图形用户界面系统,是独立于基于游戏对象的UI系统的。
IMGUI is a code-driven GUI system, and is mainly intended as a tool for programmers. It is driven by calls to the OnGUI function on any script which implements it. For example, this code:
直接模式图形用户系统是代码驱动的系统,其主要作为程序员的工具。其通过函数OnGUI实现。
3.游戏实现
1.UI布局
为了让开发有计划性,首先我们要对游戏进行初步的设计。井字棋玩法规则已定,所以我们直接考虑游戏的界面是怎样的。首先,游戏界面应该有一定的布局。在IMGUI中有(Fixed Layout vs Automatic Layout)两者模式。Fixed顾名思义,即当你有一个设计好的,不会轻易变动的设计界面时,考虑使用。而当设计不确定,或者变动几率高时,使用Automatic。当然,你也可以在一个OnGUI函数中同时使用两者。
void OnGUI () {
// Fixed Layout
GUI.Button (new Rect (25,25,100,30), "I am a Fixed Layout Button");
// Automatic Layout
GUILayout.Button ("I am an Automatic Layout Button");
}
2.IMGUI控制
IMGUI通过调用OnGUI()函数完成控制,其执行类似Update函数。
IMGUI控制可分为3块:Type(Position, Content)
1. Type: 类型即控制类型,主要有 GUI class 和 GUILayout class,如GUI.Label()
2. Position: Position is the first argument in any GUI Control function. The argument itself is provided with a Rect() function.
3. Content: The second argument for a GUI Control is the actual content to be displayed with the Control. 可以是字符串,可以是贴图。
4. GUIStyle VS GUISkin:前者定义了一个控件的一组属性,如果是一组控件,用后者来定义它们的属性。
3.具体实现
Unity3D整体采用MVC模式,Model即GameObject,View即Camera,Control即MonoBehaviour()。挂载在GameObject上的脚本要继承MonoBehaviour类。
在场景中建一个空对象(Main),用作挂载脚本(TicTacToe)。
首先,我们考虑需要表达和存储哪些信息。
我们用一个二维整型数组,存储棋盘信息。
用整型变量turn表示,当前轮次
用整型变量result表示当前棋局状态
private int[,] board = new int[3,3]; //棋盘
private int turn = 1; //1 - Player 1, 0 - Player 2
private int result = 0; //0代表未结束,1为1赢,2为2赢,3为平局
//背景及棋子
public Texture2D img;
public Texture2D img1;
public Texture2D img2;
第二,我们考虑怎么样初始化棋局。用一个函数Reset()。Start()方法也用Reset方法实现初始化。
// Use this for initialization
void Reset() {
result = 0;
turn = 1;
for (int i=0; i<3; ++i) {
for