本文主要是介绍3D游戏编程与设计 HW 3.5 牧师与恶魔,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 3D游戏编程与设计 HW 3.5 牧师与恶魔
- 1.游戏介绍
- 2.题目要求
- 3.MVC结构
- 4.游戏对象表,玩家动作表,事件表
- 5.类设计
- (一)Models
- ① Boat
- ② Coast
- ③ Character
- (二)Views
- ① UserGUI
- (三)Controllers
- ① Director
- ② ISceneController
- ③ IUserAction
- ④ Moveable
- ⑤ GameController
- ⑥ FirstController
- 6.游戏结果展示
- (一) 游戏界面
- (二)游戏失败
- (三)游戏胜利
3D游戏编程与设计 HW 3.5 牧师与恶魔
完整游戏过程可见以下视频:
https://www.bilibili.com/video/BV1Vk4y117J2/
完整代码可见以下仓库:
https://gitee.com/beilineili/game3-d
1.游戏介绍
- 牧师和恶魔是一款益智游戏
- 你将帮助神父和恶魔在限定的时间内过河。河的一边有三个牧师和三个魔鬼。他们都想到河的另一边去,但是只有一条船,每次只能载两个人。必须有一个人把船从一边转向另一边。如果牧师们被河两岸的恶魔们打败(在岸上的牧师数量少于恶魔),他们就会被杀死,游戏也就结束了。
- 在游戏中,你可以点击它们来移动它们,点击go按钮来移动船到另一个方向。你可以用很多的方法来尝试。让所有的牧师活下去! 祝你好运!
2.题目要求
3.MVC结构
- MVC是模型(model)-视图(view)-控制器(controller)的缩写,它是一种软件设计模式,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
- MVC基本结构图:
- 在牧师与恶魔游戏设计中,可以分为
① SSDirector:整个结构的管理者,控制各个场景的切换协调;
② ISceneController(抽象):每个场景的管理者,是Director用来向场景控制器传递要求的接口
③ IUserAction(抽象):负责管理行为之间的交互,对于玩家的每个动作产生相应的响应结果 - 通过这样基于职责的设计,实现了赋予不同对象特定的职责,使游戏程序的结构更加清晰、可复用性更高。
4.游戏对象表,玩家动作表,事件表
游戏对象 | 对象类型 |
---|---|
Priest 牧师 | Cube |
Devil 魔鬼 | Sphere |
Boat 船 | Cube |
River 河流 | Cube |
Coast 河岸 | Cube |
动作 | 触发事件 |
---|---|
点击 Character 人物 | 人物上船,下船 |
点击 Boat 船只 | 船只过河 |
事件 | 结果 |
---|---|
其中一边恶魔数量大于牧师(包括船上和岸上的) | 玩家失败 |
所有牧师和恶魔都到了另一岸 | 玩家成功 |
5.类设计
基于职责设计,使用面向对象技术设计游戏。
项目的程序代码采用MVC结构,根据功能将代码文件分别放入Controllers, Models, Views文件夹中。
(一)Models
① Boat
- 有 location(船位置坐标)属性,有起点和终点,此外还需要维护船上的空位坐标以及角色信息
② Coast
- 同 Boat,需要维护岸上的空位坐标和角色信息
③ Character
- 有 name,location 和 isOnBoard 属性;其中 name 用于区分角色是牧师还是恶魔,IsOnBoat 用于区分是否在船上
(二)Views
① UserGUI
- Start 函数,通过获得 Director 的单例,初始化获得当前场记 CurrentSecnController
// 得到 GameControllervoid Start () {status = 0;action = Director.GetInstance().CurrentSecnController as IUserAction;}
- OnGUI 函数,渲染游戏界面;
void OnGUI () {textStyle = new GUIStyle {fontSize = 40,alignment = TextAnchor.MiddleCenter};hintStyle = new GUIStyle {fontSize = 15,fontStyle = FontStyle.Normal};btnStyle = new GUIStyle("button") {fontSize = 30};// 打印标题和规则提示信息GUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 195, 100, 50), "Priest And Devil", textStyle);GUI.Label(new Rect(Screen.width / 2 - 400, Screen.height / 2 - 125, 100, 50), "White Cube: Periest\n Red Sphere: Devil\n\n" + rule, hintStyle);// 打印游戏结果和重开游戏的按钮if (status == 1) {// LoseGUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 85, 100, 50), "You Lose!", textStyle);if (GUI.Button(new Rect(Screen.width / 2 - 70, Screen.height / 2, 140, 70), "Restart", btnStyle)) {status = 0;action.Restart();}} else if (status == 2) {// WinGUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 85, 100, 50), "You Win!", textStyle);if (GUI.Button(new Rect(Screen.width / 2 - 70, Screen.height / 2, 140, 70), "Restart", btnStyle)) {status = 0;action.Restart();}}}
- OnMouseDown 函数,监听捕捉用户的点击动作,转至 Controller 处理
void OnMouseDown() {if (gameObject.name == "boat") {action.MoveBoat();} else {action.CharacterClicked(characterCtrl);}}
(三)Controllers
① Director
- 获取当前游戏的场景
- 管理游戏全局状态
public class Director : System.Object{// Singlton instance.private static Director instance;public ISceneController CurrentSecnController { get; set; }// get instance anytime anywhere!public static Director GetInstance(){if (instance == null){instance = new Director();}return instance;}public int getFPS(){return Application.targetFrameRate;}public void setFPS(int fps){Application.targetFrameRate = fps;}}
② ISceneController
- 场记 GameController 与导演 Director 交互的接口
public interface ISceneController{void LoadResources();}
③ IUserAction
- 玩家与 GameController 互动的用户交互接口
public interface IUserAction {void MoveBoat();void CharacterClicked(CharacterController characterCtrl);void Restart();}
④ Moveable
- SetDestination 用于控制对应游戏对象的运动
public void SetDestination(Vector3 pos) {destination = pos;middle = pos;if (pos.y == transform.position.y) { // 移动船status = 2;} else if (pos.y < transform.position.y) { // 将角色从岸上移到船上middle.y = transform.position.y;} else { // 将角色从船上移到岸上middle.x = transform.position.x;}status = 1;}
⑤ GameController
- CoastController
GetEmptyIndex:岸上空位的下标
GetEmptyPosition:岸上空位的坐标
GetOnCoast:上岸
GetOffCoast:离岸
GetCharacterNum:计算岸上角色的数量 - BoatController
Move:移动船
GetEmptyIndex:船上空位的下标
IsEmpty:船是否有空位
GetEmptyPosition:船上空位的坐标
GetOnBoat:当玩家点击牧师或魔鬼,使之上船时,被调用。
GetOffBoat:当玩家点击牧师或魔鬼,使之上岸时,被调用。
GetCharacterNum:计算船上角色的数量 - CharacterController
配合 CoastController 和 BoatController
⑥ FirstController
- 在场景被加载唤醒(awake)时,它会自动注入导演,设置当前场景
void Awake() {Director director = Director.GetInstance();director.CurrentSecnController = this;userGUI = gameObject.AddComponent<UserGUI>() as UserGUI;characters = new MyNamespace.CharacterController[6];LoadResources();}
- CheckGameOver 判断游戏胜负
private int CheckGameOver() {int rightPriest = 0;int rightDevil = 0;int leftPriest = 0;int leftDevil = 0;int status = 0;rightPriest += rightCoastCtrl.GetCharacterNum()[0];rightDevil += rightCoastCtrl.GetCharacterNum()[1];leftPriest += leftCoastCtrl.GetCharacterNum()[0];leftDevil += leftCoastCtrl.GetCharacterNum()[1];// Winif (leftPriest + leftDevil == 6) {status = 2; }if (boatCtrl.boat.Location == Location.right) {rightPriest += boatCtrl.GetCharacterNum()[0];rightDevil += boatCtrl.GetCharacterNum()[1];} else {leftPriest += boatCtrl.GetCharacterNum()[0];leftDevil += boatCtrl.GetCharacterNum()[1];}// Loseif ((rightPriest < rightDevil && rightPriest > 0) ||(leftPriest < leftDevil && leftPriest > 0)) {status = 1;}return status;}
6.游戏结果展示
完整游戏过程可见以下视频:
https://www.bilibili.com/video/BV1Vk4y117J2/
(一) 游戏界面
(二)游戏失败
(三)游戏胜利
这篇关于3D游戏编程与设计 HW 3.5 牧师与恶魔的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!