牧师与魔鬼-MVC版
MVC框架结构
(1)Models
这部分包含了各个对象的模块,模块定义了对象的类。同时自定义部件click用于处理点击事件。
其中所有的模型都是通过
GameObject.Instantiate(Resources.Load("Prefabs/boat", typeof(GameObject))) as GameObject;
这个函数来加载prefabs文件夹中的材质来进行渲染的,可以通过修改该文件夹下的材质来对游戏物体进行修改。
比较重要的代码如下:
1)船模型代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Boat { public GameObject boat;//船对象 public Role[] roles;//船上的角色 public bool isRight; public int priestCount, devilCount; public Boat(Vector3 position) { boat = GameObject.Instantiate(Resources.Load("Prefabs/boat", typeof(GameObject))) as GameObject; boat.name = "boat"; boat.transform.position = position; boat.transform.localScale = new Vector3(2.8f,0.4f,2); roles = new Role[2]; isRight = false; priestCount = devilCount = 0; boat.AddComponent<BoxCollider>(); boat.AddComponent<Click>(); } }
2)角色代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Role { public GameObject role;//model对应的游戏对象 public bool isPriest; public bool inBoat; public bool onRight; public int id; public Role (Vector3 position, bool isPriest, int id) { this.isPriest = isPriest; this.id = id; onRight = false; inBoat = false; role = GameObject.Instantiate(Resources.Load("Prefabs/" + (isPriest ? "priest" : "devil"), typeof(GameObject))) as GameObject; role.transform.localScale = new Vector3(1,1.2f,1); role.transform.position = position; role.name = "role" + id; role.AddComponent<Click>(); role.AddComponent<BoxCollider>(); } }
这里用isPriest来判断是否为牧师,如果该角色为牧师则为True。
船和角色均需要通过点击来进行移动,所以需要添加组件Click和BoxCollider来判断是否点击该角色。其中Click的行为比较复杂所以该组件为自定义组件。
3)其他固定物体代码
这部分代码只需要设定位置和加载对应材质即可。这里不多进行展示直接查看github代码即可。
(2) Controllers
项目中的控制部分,用于负责所有游戏对象的生成和变化还有用户事件。
最核心的部分为FirstController。
同时还有两个接口类:IsceneController和IUserAction。
前者控制整个场景资源的接口,后者为用户操作接口。
Move空间和Move控制器
后者用于实现动画效果,而不是闪现
类似需要将角色从船上移动到岸上的相对位置需要在岸控制器中完成。
SSDirestor、ISceneController、IUserAction类
这三个分别为导演类、资源控制接口和用户操作接口。
导演类代码:
public class SSDirector : System.Object { static SSDirector _instance; public ISceneController CurrentSceneController {get; set;} public static SSDirector GetInstance() { if (_instance == null) { _instance = new SSDirector(); } return _instance; } }
资源控制接口代码:
public interface ISceneController { void LoadResources(); }
用户操作接口代码:
public interface IUserAction { void MoveBoat(); void MoveRole(Role roleModel); void Check(); }
FirstController类
指挥控制器们的行为,并且负责加载资源、创建对象,以及实现用户操作的响应、更新游戏界面、保存游戏状态等等。
加载资源代码:
public void LoadResources() { //role roleControllers = new RoleCtrl[6]; for (int i = 0; i < 6; ++i) { roleControllers[i] = new RoleCtrl(); roleControllers[i].CreateRole(Position.role_shore[i], i < 3 ? true : false, i); } //shore leftShoreController = new ShoreCtrl(); leftShoreController.CreateShore(Position.left_shore); leftShoreController.GetShore().shore.name = "left_shore"; rightShoreController = new ShoreCtrl(); rightShoreController.CreateShore(Position.right_shore); rightShoreController.GetShore().shore.name = "right_shore"; //将人物添加并定位至左岸 foreach (RoleCtrl roleController in roleControllers) { roleController.GetRoleModel().role.transform.localPosition = leftShoreController.AddRole(roleController.GetRoleModel()); } //boat boatController = new BoatCtrl(); boatController.CreateBoat(Position.left_boat); //river river = new River(Position.river); //move moveController = new MoveCtrl(); isRunning = true; ## 游戏倒计时 time = 60; }
移动船只代码:
public void MoveBoat() { if (isRunning == false || moveController.GetIsMoving()) return; if (boatController.GetBoatModel().isRight) { moveController.SetMove(Position.left_boat, boatController.GetBoatModel().boat); } else { moveController.SetMove(Position.right_boat, boatController.GetBoatModel().boat); } boatController.GetBoatModel().isRight = !boatController.GetBoatModel().isRight; }
移动角色代码:
public void MoveRole(Role roleModel) { if (isRunning == false || moveController.GetIsMoving()) return; if (roleModel.inBoat) { if (boatController.GetBoatModel().isRight) { moveController.SetMove(rightShoreController.AddRole(roleModel), roleModel.role); } else { moveController.SetMove(leftShoreController.AddRole(roleModel), roleModel.role); } roleModel.onRight = boatController.GetBoatModel().isRight; boatController.RemoveRole(roleModel); } else { if (boatController.GetBoatModel().isRight == roleModel.onRight) { if (roleModel.onRight) { rightShoreController.RemoveRole(roleModel); } else { leftShoreController.RemoveRole(roleModel); } moveController.SetMove(boatController.AddRole(roleModel), roleModel.role); } } }
检查游戏是否结束代码:
public void MoveRole(Role roleModel) { if (isRunning == false || moveController.GetIsMoving()) return; if (roleModel.inBoat) { if (boatController.GetBoatModel().isRight) { moveController.SetMove(rightShoreController.AddRole(roleModel), roleModel.role); } else { moveController.SetMove(leftShoreController.AddRole(roleModel), roleModel.role); } roleModel.onRight = boatController.GetBoatModel().isRight; boatController.RemoveRole(roleModel); } else { if (boatController.GetBoatModel().isRight == roleModel.onRight) { if (roleModel.onRight) { rightShoreController.RemoveRole(roleModel); } else { leftShoreController.RemoveRole(roleModel); } moveController.SetMove(boatController.AddRole(roleModel), roleModel.role); } } }
游戏启动代码:
void Awake() { SSDirector.GetInstance().CurrentSceneController = this; LoadResources(); this.gameObject.AddComponent<UserGUI>(); }
状态更新代码(用于计时):
void Update() { if (isRunning) { time -= Time.deltaTime; this.gameObject.GetComponent<UserGUI>().time = (int)time; if (time <= 0) { this.gameObject.GetComponent<UserGUI>().time = 0; this.gameObject.GetComponent<UserGUI>().gameMessage = "Game Over!"; isRunning = false; } } }
总和代码可以查看github项目。
(3)Views
这里定义了用户看到的界面。
UserGUI.cs代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class UserGUI : MonoBehaviour { IUserAction userAction; public string gameMessage ; public int time; GUIStyle style, bigstyle; // Start is called before the first frame update void Start() { // 定义游戏时间 time = 120; userAction = SSDirector.GetInstance().CurrentSceneController as IUserAction; // 定义时间文本颜色 style = new GUIStyle(); style.normal.textColor = Color.blue; style.fontSize = 30; // 定义游戏名称文本颜色 bigstyle = new GUIStyle(); bigstyle.normal.textColor = Color.white; bigstyle.fontSize = 50; } // Update is called once per frame void OnGUI() { userAction.Check(); GUI.Label(new Rect(160, Screen.height * 0.1f, 50, 200), "牧师与魔鬼", bigstyle); GUI.Label(new Rect(250, 100, 50, 200), gameMessage, style); GUI.Label(new Rect(0,0,100,50), "剩余时间: " + time, style); } }
这里主要定义了三个用户界面的控件
剩余时间:time
剩余时间文本:style
游戏标题:bigstyle
这里可以通过调整各种参数来调整其大小,颜色,位置等。