牧师与魔鬼-动作不分离版

牧师与魔鬼-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

这里可以通过调整各种参数来调整其大小,颜色,位置等。

github链接

clement2048/priest_and_devil (github.com)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值