Unity实现简易打飞碟(Hit UFO)
前言
这是中山大学数据科学与计算机学院2019年3D游戏编程与设计的第四次作业
所有项目与代码已上传至github当中,欢迎大家访问。
github个人主页: https://starashzero.github.io
3D游戏编程与设计主页: https://starashzero.github.io/3DGameDesign
本次作业项目地址: https://github.com/StarashZero/3DGameDesign/tree/master/hw5
游戏简介
鼠标作为武器,打爆飞碟!
游戏玩法
点击飞出来的UFO(各种圆盘)即可得分。
游戏规则
- 正常模式共有五轮飞碟,飞碟数列遵循斐波那契数列,当所有飞碟发射完毕时游戏结束。
- 无限模式拥有无限轮数
(其实就是重复) - 红色飞碟为1分,绿色飞碟为2分,蓝色飞碟为3分
(RGB!)
游戏试玩
项目要求
参考潘老师的博客第五章最后一部分
关于程序的要求如下:
- 游戏有 n 个 round,每个 round 都包括10 次 trial;
- 每个 trial 的飞碟的色彩、大小、发射位置、速度、角度、同时出现的个数都可能不同。它们由该 round 的 ruler 控制;
- 每个 trial 的飞碟有随机性,总体难度随 round 上升;
- 鼠标点中得分,得分规则按色彩、大小、速度不同计算,规则可自由设定
- 使用带缓存的工厂模式管理不同飞碟的生产与回收,该工厂必须是场景单实例的!具体实现见参考资源 Singleton 模板类
- 近可能使用前面 MVC 结构实现人机交互与游戏模型分离
项目代码结构
大部分文件的用途都跟其他几次作业相似,因此这里就不进行解释了。
UML图:
各部分代码解释
-
Singleton.cs
public class Singleton<T> : MonoBehaviour where T: MonoBehaviour { protected static T instance; public static T Instance { get { if (instance == null) { instance = (T)FindObjectOfType(typeof(T)); if (instance == null) { Debug.LogError("An instance of " + typeof(T) + " is needed in the scene, but there is none"); } } return instance; } } }
场景单实例类,当所需的实例第一次被需要时,在场景内搜索该实例,下一次使用时不需要搜索直接返回。
-
DiskData.cs
public class DiskData : MonoBehaviour { public float speed; //水平速度 public int points; //得分 public Vector3 direction; //初始方向 }
飞碟数据,携带飞碟的飞行速度、得分、以及飞行方向。
-
DiskFactory.cs
public class DiskFactory : MonoBehaviour { public GameObject disk_Prefab; //飞碟预制 private List<DiskData> used; //正被使用的飞碟 private List<DiskData> free; //空闲的飞碟 public void Start() { used = new List<DiskData>(); free = new List<DiskData>(); disk_Prefab = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Disk_Prefab"), Vector3.zero, Quaternion.identity); disk_Prefab.SetActive(false); } public GameObject GetDisk(int round) { GameObject disk; //如果有空闲的飞碟,则直接使用,否则生成一个新的 if (free.Count > 0) { disk = free[0].gameObject; free.Remove(free[0]); } else { disk = GameObject.Instantiate<GameObject>(disk_Prefab, Vector3.zero, Quaternion.identity); disk.AddComponent<DiskData>(); } //按照round来设置飞碟属性 //飞碟的等级 = 0~2之间的随机数 * 轮次数 //0~4: 红色飞碟 //4~7: 绿色飞碟 //7~10: 蓝色飞碟 float level = UnityEngine.Random.Range(0, 2f) * (round + 1); if (level < 4) { disk.GetComponent<DiskData>().points = 1; disk.GetComponent<DiskData>().speed = 4.0f; disk.GetComponent<DiskData>().direction = new Vector3(UnityEngine.Random.Range(-1f, 1f) > 0 ? 2 : -2, 1, 0); disk.GetComponent<Renderer>().material.color = Color.red; } else if (level > 7) { disk.GetComponent<DiskData>().points =