牧师与恶魔需要从岸的一端到达另一端,河上只有一条船,一条船只能坐两个角色,并且至少需要一个角色在船上船才可以行驶。并且,如果在某一侧(包括岸上和船上),恶魔的数量大于牧师的数量,牧师就会被恶魔吃掉(如果仅有恶魔则无事发生),游戏失败。玩家要安排牧师与恶魔的过河顺序,让牧师与恶魔全部到达另一边岸上,才能游戏通关。
MVC是界面人机交互程序设计的一种架构模式。它把程序分为三个部分:
例子:
应用程序浏览网页,是一个把信息拉取下来并显示到页面上的过程,页面就是view,拉取信息的类就是model,当用户进行了点击后,负责通知model去拉去信息,并且通知view进行显示的就是controller。
而基于职责的设计与游戏的MVC总体框架包括:
两种结合,导演和场记相当于controller,游戏中的object就是model,GUI就是view。
完成牧师与恶魔游戏,程序需要满足要求:
· play the game
· 列出游戏中提及的事物(Objects)
· 用表格列出玩家动作表(规则表)
· 将游戏中对象做成预制
· 在 GenGameObjects 中创建长方形、正方形、 及其色彩代表游戏中的对象。
· 使用C#集合类型有效组织对象
· 整个游戏仅主摄像机和一个Empty对象,其他对象必须代码动态生成。整个游戏不许出现Find游戏对象,SendMessage这类突破程序结构的通讯耦合语句。
· 使用课件架构图编程,不接受非MVC结构程序
· 船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件
Windows 10
Unity 2020.3.17f1c1
游戏中主要包括的Object有以下:
object | 数量 |
---|---|
牧师 | 3 |
恶魔 | 3 |
船 | 1 |
水 | 1 |
岸边 | 2 |
动作 | 条件 | 效果 |
---|---|---|
玩家点击岸上角色 | 船上有空位 | 角色上船 |
玩家点击船上角色 | 角色上岸 | |
玩家点击船 | 船上有至少一个角色 | 开船 |
玩家点击restart | 重新开始游戏 |
点击此处可以前往
下载Assets文件夹,项目代码在Assets>Scripts中
点击此处可以前往gitee
首先是Director的部分,Director的建立基本是默认的:
public class Director : System.Object {
private static Director _instance;
public SceneController currentSceneController {
get; set; }
public static Director getInstance() {
if (_instance == null) {
_instance = new Director ();
}
return _instance;
}
}
这个Director是单例模式并且是懒汉模式的,因此如果在程序的其他地方进行调用getInstance,得到的_instance会是同一个,就可以实现类之间的通信。
然后是场记的部分,对于不同的对象设置不同的Controller:
Director中有:
public SceneController currentSceneController {
get; set; }
而SceneController是一个接口:
public interface SceneController {
void loadResources ();
}
SceneController是导演Director控制场景控制器的渠道,Director可以调用SceneController接口中的方法。而实现SceneController的currentSceneController类,在FirstSceneController中就会被定义为FirstSceneController本身,loadResources需要在FirstSceneController中实现。
(程序在BaseCode.cs中的31行开始)
Moveable是为了给角色对象、船只移动而准备的类,因此需要先写。
update主要利用MoveTowards来使得对象移动到目的位置。
当角色对象控制器和船只控制器需要移动某一个对象时,可以调用setDestination函数来进行移动。
Moveable中还设置了reset用于重新开始,初始化游戏对象的移动状态。
(程序在BaseCode.cs中的73行开始)
MyCharacterController类主要用于控制游戏中的牧师与恶魔,其构造函数会根据传入的字符串来创建牧师/恶魔对象,并且给他们每一个对象挂载ClickGUI函数用于判断用户点击,由于角色对象会运动,所以也需要挂载Moveable类。
类中还有其他可调用的函数:
(程序在BaseCode.cs中的148行开始)
CoastController用于控制河岸对象,而河岸因为要用于判断获胜条件,也需要像角色对象分为牧师与恶魔一样,分成此岸和对岸(from和to)。
因为河岸需要给角色对象站立,游戏中的角色对象总共有六个,因此在构造函数需要构造六个空对象,并且根据传入的字符串,标记此次创建的是此岸还是对岸。
其他函数:
(程序在BaseCode.cs中的230行开始)
BoatController用于控制船只,因为船只会移动到两个岸边,因此它的状态也分成在此岸或对岸(from和to)。
因为船上拥有两个位置,因此需要构造两个空对象;并且由玩家点击船只行驶,需要挂载ClickGUI类判断用户点击;由于船只会运动,所以也需要挂载Moveable类。
其他函数:
UserAction是门面模式,与用户交互相关的,与玩家动作有关:
public interface UserAction {
void moveBoat();
void characterIsClicked(MyCharacterController characterCtrl);
void restart();
}
这里就包括了移动船只,角色被点击,游戏重新开始这三个动作,UserAction接收到UI传来的信号,告知FirstSceneController调用对应动作的函数作出反应。而UserAction里面的函数就要在FirstSceneController中定义。而ClickGUI与UserGUI则通过UserAction这个门面接口来与FirstSceneController打交道。
ClickGUI是用以判断用户点击了游戏对象(牧师、恶魔、船)的类
public class ClickGUI : MonoBehaviour {
UserAction action;
MyCharacterController characterController;
public void setController(MyCharacterController characterCtrl) {
characterController = characterCtrl;
}
void Start() {
action = Director.getInstance ().currentSceneController as UserAction;
}
void OnMouseDown() {
if (gameObject.name == "boat") {
action.moveBoat ();
} else {
action.characterIsClicked (characterController);
}
}
}
ClickGUI判断被鼠标点击的对象是谁来进行下一步操作,调用UserAction(action)的接口来完成功能。
UserGUI是用于当游戏结束(失败或者成功)时显示说明文字和重玩游戏按钮的。
游戏状态分别为:0-游戏进行中,1-游戏失败,2-游戏通关。
FirstController就要负责实现loadResources、moveBoat、characterIsClicked、restart函数。
1.学习Unity(5)小游戏实例——牧师与魔鬼
2.Unity中的单例模式
3.Unity3d-learning 牧师与恶魔