Unity游戏制作(二)
实验内容
- 编程实践:魔鬼与牧师
实验环境
- Windows
- Unity 2020.3.18
技术日记
一、MVC框架
模拟人类组织管理社会的方法,根据不同人拥有资源、知识与技能的不同,赋予不同人(或对象)特定的职责。再按一定结构(如设计模式),将它们组织起来。
MVC的游戏框架如下
其中,游戏框架中的角色分别为
- 导演,1名(仅要一个)
- 类型:SSDriector
- 职责:
- 获取当前游戏的场景
- 控制场景运行、切换、入栈与出栈
- 暂停、恢复、退出
- 管理游戏全局状态
- 设定游戏的配置
- 设定游戏全局视图
- 场记若干,每场需要一个。
- 抽象类型(角色):ISceneController
- 具体类型:FirstController
- 职责:
- 管理本次场景所有的游戏对象
- 协调游戏对象(预制件级别)之间的通讯
- 响应外部输入事件
- 管理本场次的规则(裁判)
- 各种杂务
- 群众,1个
- 抽象类型(角色):IUserAction
- 具体类型:UserGUI
二、实验部分
1.项目配置过程
新建3d-unity的文件,然后直接把gitee上Assets
文件夹替换新项目的Assets
文件夹,把Scenes
里面的SampleScenc
然拖动出来后,直接点击运行即可开始游戏。
2. 实现思路及核心算法
为实现魔鬼与牧师,采用了MVC的架构,并设置了六个函数,其模块如下图所示:
具体如下:
1) 需要设置一个导演SSDirector.cs
类:
public class SSDirector : System.Object{
private static SSDirector _instance;
public ISceneController CurrentScenceController { get; set; }
public static SSDirector GetInstance(){
if (_instance == null){
_instance = new SSDirector();
}
return _instance;
}
}
通过ISceneController
接口访问不同场的场记。
2) 设置一个场记,其中场记的接口函数如下:
namespace Interface{
public interface ISceneController{
void LoadResources();
}
public interface IUserAction{
void MoveBoat(); //移动小船
void Restart(); //重新开始游戏
void MoveRole(RoleModel role); //移动人物
int Check(); //判断游戏是否结束
}
}
在LoadResources()
函数中,加载并初始化了长方形、正方形、球及其色彩代表游戏中的对象,如下所示:
public void LoadResources(){
Debug.Log("DD");
GameObject water = Instantiate(Resources.Load("Prefabs/Water", typeof(GameObject)), new Vector3(0,-1,0), Quaternion.identity) as GameObject;
water.name = "water";
start_land = new LandModel("start");
end_land = new LandModel("end");
boat = new BoatModel();
role = new RoleModel[6];
for (int i = 0; i < 3; i++){
RoleModel r = new RoleModel("priest");
r.SetName("priest" + i);
r.SetPosition(start_land.GetEmptyPosition());
r.GoLand(start_land);
start_land.AddRole(r);
role[i] = r;
}
for (int i = 3; i < 6; i++){
RoleModel r = new RoleModel("devil");
r.SetName("devil" + i);
r.SetPosition(start_land.GetEmptyPosition());
r.GoLand(start_land);
start_land.AddRole(r);
role[i] = r;
}
3) 设置游戏逻辑与用户交互的门面 UserGUI.cs
类:
public class UserGUI : MonoBehaviour {
private IUserAction action;
public int sign = 0;
void Start()
{
action = SSDirector.GetInstance().CurrentScenceController as IUserAction;
}
void OnGUI(){
if (sign == 1){
GUI.Label(new Rect(Screen.width / 2-20, Screen.height/2-60, 100, 50), "Lost!");
if (GUI.Button(new Rect(Screen.width/2-50, Screen.height/2+30, 100, 50), "Restart")){
action.Restart();
sign = 0;
}
}
else if (sign == 2){
GUI.Label(new Rect(Screen.width/2-20, Screen.height/2-60, 100, 50), "Win!");
if (GUI.Button(new Rect(Screen.width/2-50, Screen.height/2+30, 100, 50), "Restart")){
action.Restart();
sign = 0;
}
}
}
}
还有Click.cs
类捕捉用户的点击事件:
public class Click : MonoBehaviour{
IUserAction action;
RoleModel role = null;
BoatModel boat = null;
public void SetRole(RoleModel role){
this.role = role;
}
public void SetBoat(BoatModel boat){
this.boat = boat;
}
void Start(){
action = SSDirector.GetInstance().CurrentScenceController as IUserAction;
}
void OnMouseDown(){
if (boat == null && role == null){
return;
}
if (boat != null){
action.MoveBoat();
}
else if(role != null){
action.MoveRole(role);
}
}
}
4)模型的控制类ModelController.cs
负责每个对象具体的控制,包含了四个类
BoatModel
LandModel
RoleModel
Move
实验总结
由于我自己写的游戏最后还是有许多bug没有解决,最终是跟着这个师兄的思路完成的:https://blog.csdn.net/TempterCyn/article/details/101110379