适配器模式(Adapter Pattern)是做为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。html
关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。git
基于做业05修改代码,首先能够明确的是MVC架构中的游戏对象模型
、控制器Controller.cs
、界面UserGUI.cs
的代码是不须要作修改的。github
如今添加飞碟物理运动框架:web
PhysisFlyAction.cs
PhysisFlyActionManager
FlyAction.cs
和FlyActionManager.cs
的总体框架基本相差无异,不一样在于内部运动的实现逻辑://FlyAction 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.destroy = true; this.callback.SSActionEvent(this); } } public override void Start() { //飞行动做创建时候不作任何事情 } public override void FixedUpdate() { //不作任何事情,但必须重载,不然SSAction中抛出异常 }
//PhysisFlyAction public override void FixedUpdate() { //判断是否超出范围 if (this.transform.position.y < -10) { this.destroy = true; this.callback.SSActionEvent(this); } } public override void Update() { //不作任何事情,但必须重载,不然SSAction中抛出异常 } public override void Start() { //使用重力以及给一个初速度 gameobject.GetComponent<Rigidbody>().velocity = power / 35 * start_vector; gameobject.GetComponent<Rigidbody>().useGravity = true; }
这里值得一提的是,当MonoBehaviour
启动时,Update()
和FixedUpdate()
都会在每一帧被调用,可是因为物理运动中须要处理Rigidbody
,因此须要使用FixedUpdate()
编程
Update和FixedUpdate的区别:
update跟当前平台的帧数有关,而FixedUpdate是真实时间,因此处理物理逻辑的时候要把代码放在FixedUpdate而不是Update.
Update是在每次渲染新的一帧的时候才会调用,也就是说,这个函数的更新频率和设备的性能有关以及被渲染的物体(能够认为是三角形的数量)。在性能好的机器上可能fps 30,差的可能小些。这会致使同一个游戏在不一样的机器上效果不一致,有的快有的慢。由于Update的执行间隔不同了。
而FixedUpdate,是在固定的时间间隔执行,不受游戏帧率的影响。有点想Tick。因此处理Rigidbody的时候最好用FixedUpdate。
PS:FixedUpdate的时间间隔能够在项目设置中更改,Edit->ProjectSetting->time 找到Fixedtimestep。就能够修改了。设计模式
接下来,为了使程序兼容两种运动模式,须要添加适配器代码ActionManagerAdapter.cs
:架构
using System.Collections; using System.Collections.Generic; using UnityEngine; public interface IActionManager { void playDisk(GameObject disk, float angle, float power, bool isPhy); } public class ActionManagerAdapter : MonoBehaviour,IActionManager { public FlyActionManager action_manager; public PhysisFlyActionManager phy_action_manager; public void playDisk(GameObject disk, float angle, float power, bool isPhy) { if (isPhy) { phy_action_manager.UFOFly(disk, angle, power); } else { action_manager.UFOFly(disk, angle, power); } } //Use this for initialization void Start() { action_manager = gameObject.AddComponent<FlyActionManager>() as FlyActionManager; phy_action_manager = gameObject.AddComponent<PhysisFlyActionManager>() as PhysisFlyActionManager; } }
此外,因为增长了FixedUpdate()
方法的调用,故而还须要对父类SSAction
和SSActionManager
作修改——SSAction
中添加虚函数FixedUpdate()
,SSActionManager
中添加可供子类调用的函数FixedUpdate()
(方法内部实现代码与Update()
彻底相同)框架
至此,做业04的代码便成功修改为了适配器模式。ide
代码传送门svg
同做业04的演示视频:前往B站观看游戏demo演示视频