unity|Unity3D游戏编程-牧师与恶魔
Unity3D游戏编程-牧师与恶魔
文章目录
- Unity3D游戏编程-牧师与恶魔
-
- 前置说明
-
- 牧师与恶魔
- MVC架构
- 作业要求
- 项目配置
- Object
- 玩家动作(规则表)
- 项目演示
-
- 视频演示
- 项目下载
- 文字说明
- 项目截图
- 实现过程和方法(算法)
-
- Director
- Controller
-
- SceneController
- Moveable
- CharacterController
- CoastController
- BoatController
- UserAction
-
- UserAction
- ClickGUI
- UserGUI
- FirstController
- 参考资料
前置说明 牧师与恶魔
牧师与恶魔需要从岸的一端到达另一端,河上只有一条船,一条船只能坐两个角色,并且至少需要一个角色在船上船才可以行驶。并且,如果在某一侧(包括岸上和船上),恶魔的数量大于牧师的数量,牧师就会被恶魔吃掉(如果仅有恶魔则无事发生),游戏失败。玩家要安排牧师与恶魔的过河顺序,让牧师与恶魔全部到达另一边岸上,才能游戏通关。
MVC架构
MVC是界面人机交互程序设计的一种架构模式。它把程序分为三个部分:
- 模型(Model):数据对象及关系
· 游戏对象、空间关系 - 控制器(Controller):接受用户事件,控制模型的变化
· 一个场景一个主控制器
· 至少实现与玩家交互的接口(IPlayerAction)
· 实现或管理运动 - 界面(View):显示模型,将人机交互事件交给控制器处理
· 处收Input 事件
· 渲染GUI ,接收事件
应用程序浏览网页,是一个把信息拉取下来并显示到页面上的过程,页面就是view,拉取信息的类就是model,当用户进行了点击后,负责通知model去拉去信息,并且通知view进行显示的就是controller。
【unity|Unity3D游戏编程-牧师与恶魔】而基于职责的设计与游戏的MVC总体框架包括:
- 导演,1名(仅要一个)
·类型:SSDriector
·职责:把握全局;控制场景 - 场记若干,话剧有很多场,每场需要一个。
·抽象类型(角色):ISceneController
·具体类型:FirstController
·职责:第一场的场记,控制布景、演员的上下场、管理动作等执行 - 吃瓜群众,1个
· 抽象类型:IUserAction
· 具体类型:IUserAction
· 职责:门面,与controller沟通
作业要求 完成牧师与恶魔游戏,程序需要满足要求:
· play the game
· 列出游戏中提及的事物(Objects)
· 用表格列出玩家动作表(规则表)
· 将游戏中对象做成预制
· 在 GenGameObjects 中创建长方形、正方形、 及其色彩代表游戏中的对象。
· 使用C#集合类型有效组织对象
· 整个游戏仅主摄像机和一个Empty对象,其他对象必须代码动态生成。整个游戏不许出现Find游戏对象,SendMessage这类突破程序结构的通讯耦合语句。
· 使用课件架构图编程,不接受非MVC结构程序
· 船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件
项目配置 Windows 10
Unity 2020.3.17f1c1
Object 游戏中主要包括的Object有以下:
object | 数量 |
---|---|
牧师 | 3 |
恶魔 | 3 |
船 | 1 |
水 | 1 |
岸边 | 2 |
动作 | 条件 | 效果 |
---|---|---|
玩家点击岸上角色 | 船上有空位 | 角色上船 |
玩家点击船上角色 | 角色上岸 | |
玩家点击船 | 船上有至少一个角色 | 开船 |
玩家点击restart | 重新开始游戏 |
点击此处可以前往
项目下载
下载Assets文件夹,项目代码在Assets>Scripts中
点击此处可以前往gitee
文字说明
- 创建unity专案后,将保存的文件夹中的Assets替换成在上面项目下载的Assets文件夹
- 打开专案,然后点选Assets中的ass加载场景
- 运行即可开始游戏
- 白色长方体为牧师,红色圆球为恶魔
![unity|Unity3D游戏编程-牧师与恶魔](https://img.it610.com/image/info8/bc63f79179234137b869d3b52d9968f7.jpg)
文章图片
![unity|Unity3D游戏编程-牧师与恶魔](https://img.it610.com/image/info8/32c3e00dbf8546ed8957ce2dc521560f.jpg)
文章图片
![unity|Unity3D游戏编程-牧师与恶魔](https://img.it610.com/image/info8/244f7368e6284129ac4b7f78ff18efb8.jpg)
文章图片
实现过程和方法(算法) Director
首先是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会是同一个,就可以实现类之间的通信。
- 单例模式:一些东西在整个游戏中只有一个,而又想可以方便地随时访问它,这时就可以考虑单例模式。单例模式保证应用只有全局惟一的实例,并且提供一个访问它的全局访问点。单例包含一个静态方法,叫做getInstance(),调用这个静态方法,它就立刻现身,随时可以工作。
- 懒汉模式:在启动时并不创建单例对象,仅在调用getInstance()的时候才创建。程序运行中,调用Director.getInstance会判断_instance是否为空。如果为空,就创建一个返回。如果不为空,说明之前已经创建过了,直接返回。
然后是场记的部分,对于不同的对象设置不同的Controller:
SceneController Director中有:
public SceneController currentSceneController {
get;
set;
}
而SceneController是一个接口:
public interface SceneController {void loadResources ();
}
SceneController是导演Director控制场景控制器的渠道,Director可以调用SceneController接口中的方法。而实现SceneController的currentSceneController类,在FirstSceneController中就会被定义为FirstSceneController本身,loadResources需要在FirstSceneController中实现。
Moveable (程序在BaseCode.cs中的31行开始)
Moveable是为了给角色对象、船只移动而准备的类,因此需要先写。
update主要利用MoveTowards来使得对象移动到目的位置。
当角色对象控制器和船只控制器需要移动某一个对象时,可以调用setDestination函数来进行移动。
Moveable中还设置了reset用于重新开始,初始化游戏对象的移动状态。
CharacterController (程序在BaseCode.cs中的73行开始)
MyCharacterController类主要用于控制游戏中的牧师与恶魔,其构造函数会根据传入的字符串来创建牧师/恶魔对象,并且给他们每一个对象挂载ClickGUI函数用于判断用户点击,由于角色对象会运动,所以也需要挂载Moveable类。
类中还有其他可调用的函数:
- setName设置名称(如“牧师1/恶魔1”)
- setPosition设置对象位置
- moveToPosition设置对象移动到目标位置,调用moveable的setDestination
- getType返回对象的类型(如“牧师”、“恶魔”)
- getName返回对象的名称(如“牧师1/恶魔1”)
- getOnBoat对象上船,并且修改对象的状态(_isOnBoat)
- getOnCoast对象下船,并且修改对象的状态(_isOnBoat)
- isOnBoat返回对象_isOnBoat的状态
- getCoastController返回岸边控制器
- reset用于重新初始化
CoastController用于控制河岸对象,而河岸因为要用于判断获胜条件,也需要像角色对象分为牧师与恶魔一样,分成此岸和对岸(from和to)。
因为河岸需要给角色对象站立,游戏中的角色对象总共有六个,因此在构造函数需要构造六个空对象,并且根据传入的字符串,标记此次创建的是此岸还是对岸。
其他函数:
- getEmptyIndex获取岸上的空位置的下标,passengerPlaner是用来记录在一个河岸上的角色位置,如果为NULL表示该位置为空没有角色站立在此。
- getEmptyPosition获取岸上的空位置
- getOnCoast有角色下船,修改对应的岸上状态
- getOffCoast有角色上船,修改对应的岸上状态
- get_to_or_from返回这个河岸是此岸还是对岸
- getCharacterNum返回当前河岸牧师与恶魔的数量
- reset重置
BoatController用于控制船只,因为船只会移动到两个岸边,因此它的状态也分成在此岸或对岸(from和to)。
因为船上拥有两个位置,因此需要构造两个空对象;并且由玩家点击船只行驶,需要挂载ClickGUI类判断用户点击;由于船只会运动,所以也需要挂载Moveable类。
其他函数:
- Move控制船只在两岸中移动
- getEmptyIndex返回船上空余位置下标
- getEmptyPosition返回船上空余位置
- isEmpty返回船只是否空的
- GetOnBoat有角色上船,修改船的属性
- GetOffBoat角色下船,修改船的属性
- getGameobj返回船本体的游戏对象
- get_to_or_from返回船只当前所在河岸
- getCharacterNum返回船上牧师和恶魔的数量
- reset重置船只
UserAction UserAction是门面模式,与用户交互相关的,与玩家动作有关:
public interface UserAction {void moveBoat();
void characterIsClicked(MyCharacterController characterCtrl);
void restart();
}
这里就包括了移动船只,角色被点击,游戏重新开始这三个动作,UserAction接收到UI传来的信号,告知FirstSceneController调用对应动作的函数作出反应。而UserAction里面的函数就要在FirstSceneController中定义。而ClickGUI与UserGUI则通过UserAction这个门面接口来与FirstSceneController打交道。
- 门面模式:定义一个用户动作接口,实现用户行为与游戏系统规则计算的分离,称这个接口就是游戏逻辑与用户之间交互的门面(Fasàde)。
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 UserGUI是用于当游戏结束(失败或者成功)时显示说明文字和重玩游戏按钮的。
游戏状态分别为:0-游戏进行中,1-游戏失败,2-游戏通关。
FirstController
FirstController就要负责实现loadResources、moveBoat、characterIsClicked、restart函数。
- Awake函数是负责游戏的初始化加载
- loadResources是从Aseets中取出对象,生成水面、船只、两个河岸,以及调用loadCharacter生成牧师和恶魔。
- loadCharacter负责在出发的河岸上生成三个牧师和三个恶魔。
- moveBoat检测船只上的人员是否为空,如果不是的话则可以移动船只,并且判断游戏的状态(是不是gameover)
- characterIsClicked检查被点击的对象,
若处于船上:取得船在哪个岸边、人物下船、调用函数修改游戏属性(包括船、河岸);
若处于岸上:取得人物所在哪个岸边、判断船还有没有空位、判断船和人物是否处于同一侧岸、调用函数修改游戏属性(包括船、河岸);
最后也要判断游戏的状态(是不是gameover)。 - check_game_over就是数出发岸和目标岸(包括船上)各自的牧师与恶魔数量,如果目标岸的角色总数=6,则游戏通关(状态为2);如果某一个岸恶魔的数量大于牧师,则游戏失败(状态为1);其余情况游戏继续(状态为0);
- restart重置游戏,分别调用各个对象自己的reset。
2.Unity中的单例模式
3.Unity3d-learning 牧师与恶魔
推荐阅读
- 游戏IP(立足于玩家情感的粉丝经济)
- 人生游戏--是游戏,还是人生()
- 「按键精灵安卓版」关于全分辨率脚本的一些理解(非游戏app)
- (小说)月流水几亿的火爆游戏养成记
- 游戏治愈了我无聊之症
- Unity和Android通信系列文章2——扩展UnityPlayerActivity
- 生活与游戏日记(第182篇)(〔成长瞬间〕关注解决问题2019.10)
- 我妈让我不要玩游戏多做点事
- unity探究UGUI的Image中sprite和overrideSprite的区别
- 牛逼!C++开发的穿越丛林真人游戏,游戏未上线就有百万人气