Unity实现Priests and Deivls游戏

本文介绍了中山大学数据科学与计算机学院3D游戏编程与设计的作业——Unity实现游戏Priests and Deivls。游戏目标是安全运送3个牧师过河,避免恶魔数量超过牧师。游戏采用MVC架构,详细讲解了模型、控制器和视图的代码实现,包括角色、船只、陆地的管理以及点击事件处理。项目代码已上传至GitHub。
摘要由CSDN通过智能技术生成

Unity实现Priests and Deivls游戏

前言

这是中山大学数据科学与计算机学院2019年3D游戏编程与设计的第三次作业
所有项目与代码已上传至github当中,欢迎大家访问。
github个人主页: https://starashzero.github.io
3D游戏编程与设计主页: https://starashzero.github.io/3DGameDesign
本次作业项目地址: https://github.com/StarashZero/3DGameDesign/tree/master/hw3

游戏简介

3个牧师与3个恶魔要过河,需要将牧师安全的运过去。河中有一条船,每次最多只能运两个人过河,如果任意一边的恶魔数量大于牧师数量,牧师就会被杀死。
在这里插入图片描述
(界面略丑,没有艺术细胞真是抱歉了,嘛,不是重点)

游戏玩法

点击牧师(白色圆柱)、恶魔(红色圆柱)可以让它们上船、上岸。
点击船(水面上的方块)可以让船移动。

游戏规则

  1. 任意一边的牧师数量不能小于恶魔数量(船上的牧师和恶魔也会被计算),除非牧师数目为0。
  2. 船上必须有人才能使船移动。
  3. 没有反悔选项(防止作弊),一旦游戏结束只能重来.
  4. 游戏限时60s.
  5. 当三个牧师都到了右边河岸,游戏胜利.

游戏试玩

在这里插入图片描述

项目要求

参考潘老师的博客第三章最后一部分
关于程序的要求如下:

  1. 请将游戏中对象做成预制
  2. 在GenGameObjects中创建长方形、正方形、球及其色彩代表游戏中的对象。
  3. 使用C#集合类型有效组织对象
  4. 整个游戏仅主摄像机和一个 Empty 对象,其他对象必须代码动态生成!!! 。 整个游戏不许出现 Find 游戏对象, SendMessage这类突破程序结构的 通讯耦合 语句违背本条准则,不给分
  5. 请使用课件架构图编程,不接受非 MVC 结构程序
  6. 注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件!

在编写程序时均按照上述要求编写,不过对于要求3,我选择的是直接用数组来组织对象,因为我觉得这是最合适、效率较高的。

项目代码结构

游戏对象事先做成预制
在这里插入图片描述
项目的程序代码采用MVC结构,根据功能将代码文件分别放入Controllers, Models, Views文件夹中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为了方便理解,我准备了一个UML图来解释各文件之间的关系(部分借鉴了潘老师的图,偷偷懒)。
在这里插入图片描述
(MVC确实好用,好用就好用在它能加速掉发)
大体结构是按照课程网站来做的,所有游戏对象的数据被储存在各自model对象当中。新增部分的解释如下:

  1. 在游戏中可能会变更数据的model都分配了一个各自的controller来管理大部分数据变更。
  2. 人物和船具有可被点击的属性,因此其controller需要实现ClickAction的接口,以此来处理点击事件。
  3. 游戏中物体的移动由MoveController统一管理,其携带一个Move脚本。
  4. 游戏所有物体的特殊位置信息储存在PositionModel当中,PositionModel中的数据均为静态类型,因此可以全局访问。

除了UML图里的文件,还有一个MoveCamera.cs脚本,这个脚本只是用来移动主摄像机的位置而已,因此不在程序结构之中。

各部分代码解释

Models:

首先是Models部分,Models当中主要用于存储游戏对象的各种数据,只携带初始化函数,变更数据通过Controller。

  1. RoleModel.cs

    public class RoleModel{
          
        public GameObject role;             //角色的游戏对象
        public bool isPriest;               //区分角色是牧师还是恶魔
        public int tag;                     //给对象标号,方便查找
        public bool isRight;                //区分角色是在左侧还是右侧
        public bool isInBoat;               //区分角色是在船上还是在岸上
    
        //初始化函数
        public RoleModel(Vector3 position, bool isPriest, int tag)
        {
         
            this.isPriest = isPriest;
            this.tag = tag;
            isRight = false;
            isInBoat = false;
            role = GameObject.Instantiate(Resources.Load("Prefabs/"+(isPriest?"priest":"devil"), typeof(GameObject))) as GameObject;
            role.transform.localScale = new Vector3(1,1,1);
            role.transform.position = position;
            role.name = "role" + tag;
            role.AddComponent<Click>();
            role.AddComponent<BoxCollider>();
        }
    }
    

    存储游戏当中角色(牧师、恶魔)的相关信息。
    定义了一个初始化函数,参数设置对象的位置、角色类型和标号,函数中会调用预制生成对象,并进行一些参数设置(位置、碰撞、点击等)。

  2. BoatModel.cs

    public class BoatModel {
         
        public GameObject boat;                     //船对象
        public RoleModel[] roles;                   //船上的角色的指针
        public bool isRight;                        //判断船在左侧还是右侧
        public int priestNum, devilNum;             //船上牧师与恶魔的数量
    
        public BoatModel(Vector3 position)
        {
         
            priestNum = devilNum = 0;
            roles = new RoleModel[2];
            boat = GameObject.Instantiate(Resources.Load("Prefabs/boat", typeof(GameObject))) as GameObject;
            boat.name = "boat";
            boat.transform.position = position;
            boat.transform.localScale = new Vector3(4, (float)1.5, 3);
            boat.AddComponent<BoxCollider>();
            boat.AddComponent<Click>();
            isRight = false;
        }
    }
    

    储存船的相关信息。
    定义了一个初始化函数,参数设置船的初始位置,此外会为船附加碰撞和点击属性。

  3. LandModel.cs

    public class LandModel
    {
         
        public GameObject land;                     //岸的游戏对象
        public int priestNum, devilNum;             //岸上牧师与恶魔的数量
        public LandModel(string name, Vector3 position)
        {
         
            priestNum = devilNum = 0;
            land = GameObject.Instantiate(Resources.Load("Prefabs/land", typeof(GameObject))) as GameObject;
            land.name = name;
            land.transform.position = position;
            land.transform.localScale = new Vector3(13,5,3);
        }
    }
    

    储存岸的相关信息。
    初始化函数的参数设置岸的名字(左岸或者右岸)和位置。

  4. RiverModel.cs

    public class RiverModel
    {
         
        private GameObject river;               //河流的游戏对象
    
        public RiverModel(Vector3 position)
        {
         
            river = Object.Instantiate(Resources.Load("Prefabs/river", typeof(GameObject))) as GameObject;
            river.name = "river";
            river.transform.position = position;
            river.transform.localScale = new Vector3(15, 2, 3);
        }
    }
    

    储存河流的相关信息。
    初始化函数的参数设置河流的位置。

  5. PositionModel.cs

    public class PositionModel
    {
         
        public static Vector3 right_land = new Vector3(15, -4, 0);                  //右侧岸的位置
        public static Vector3 left_land = new Vector3(-13, -4, 0);                  //左侧岸的位置
        public static Vector3 river = new Vector3(1, -(float)5.5, 0);               //河流的位置
        public static Vector3 right_boat = new Vector3(7, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值