Unity学习记录——与游戏世界交互
前言
本文是中山大学软件工程学院2020级3d游戏编程与设计的作业5
编程题:简单打飞碟
1. 题目要求
- 编写一个简单的鼠标打飞碟(Hit UFO)游戏
游戏内容要求:
- 游戏有n个 round,每个round 都包括10次trial;
- 每个 trial的飞碟的色彩、大小、发射位置、速度、角度、同时出现的个数都可能不同。它们由该round 的ruler 控制;
- 每个 trial 的飞碟有随机性,总体难度随 round 上升;
- 鼠标点中得分,得分规则按色彩、大小、速度不同计算,规则可自由设定。
- 游戏的要求:
- 使用带缓存的工厂模式管理不同飞碟的生产与回收,该工厂必须是场景单实例的!具体实现见参考资源 Singleton 模板类
- 尽可能使用前面 MVC 结构实现人机交互与游戏模型分离
2. 基本介绍
本次简单打飞碟小游戏使用了工厂模式管理不同飞碟的生产与回收。
**工厂模式(Factory Pattern)**是 游戏开发中最常用的设计模式之一。该模式将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。也因此,在工厂模式中,我们在创建对象时不会对用户暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
3.代码解读
本次代码仍旧使用了MVC模式,同时进行了动作分离。
由于动作分离中动作基类等代码基本一致,本次编程题中,一部分代码使用了上次作业(牧师与魔鬼动作分离版本)中的代码,复用的代码分别为:SSAction()
,SSActionManager()
,CCSequenceAction()
三个类。
同时,Interface()
与SSDirector()
两个类的设计在这三次游戏编程中也是基本一致,此处不进行介绍。
以下为代码解读:
FlyAction
飞碟的动作类。控制飞碟的飞行。实现的逻辑为根据飞碟的位置决定飞碟的运动,当飞碟位置在一定范围内时进行我们所设计的模拟位移,超出一定范围之后就停止位移,等待工厂的回收。
public class FlyAction : SSAction
{
public float gravity = -1; //向下的加速度
private Vector3 start_vector; //初速度向量
private Vector3 gravity_vector = Vector3.zero; //加速度的向量,初始时为0
private Vector3 current_angle = Vector3.zero; //当前时间的欧拉角
private float time; //已经过去的时间
private FlyAction() { }
public static FlyAction GetSSAction(int lor, float angle, float power)
{
//初始化物体将要运动的初速度向量
FlyAction action = CreateInstance<FlyAction>();
if (lor == -1)
{
action.start_vector = Quaternion.Euler(new Vector3(0, 0, -angle)) * Vector3.left * power;
}
else
{
action.start_vector = Quaternion.Euler(new Vector3(0, 0, angle)) * Vector3.right * power;
}
return action;
}
public override void Update()
{
//计算物体的向下的速度,v=at
time += Time.fixedDeltaTime;
gravity_vector.y = gravity * time;
//位移模拟
transform.position += (start_vector + gravity_vector) * Time.fixedDeltaTime;
current_angle.z = Mathf.Atan((start_vector.y + gravity_vector.y) / start_vector.x) * Mathf.Rad2Deg;
transform.eulerAngles = current_angle;
//如果物体y坐标小于-10,动作就做完了
if (this.transform.position.y < -10)
{
this.deleted = true;
this.callback.SSActionEvent(this);
}
}
public override void Start() { }
}
FlyActionManager
飞碟的动作管理类。通过调用FlyAction控制飞碟的运动。
public class FlyActionManager : SSActionManager
{
public FlyAction fly;
public FirstController scene_controller;
protected void Start()
{
scene_controller = (FirstController)SSDirector.GetInstance().CurrentSceneController;
scene_controller.action_manager = this;
}
public void DiskFly(GameObject disk, float angle, float power)
{
int loc = disk.transform.position.x < 0