Unity实现鼠标打飞碟(Hit UFO)adapter模式
程序员文章站
2022-07-12 23:26:51
...
Unity实现鼠标打飞碟(Hit UFO)adapter模式
与上一版本的变化
- 按 adapter模式设计图修改飞碟游戏
- 使它同时支持物理运动与运动学(变换)运动
适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
UML类图
由于采用了适配器模式,场景控制器可以通过一个适配器接口来选择不同的运动方式,可以很方便的从物理运动切换到运动学运动。增加了一个物理运动管理类。
代码分析
- IActionManager
场景控制器与适配器的接口,通过该接口场景控制器可以*选择不同的运动方式。
public interface IActionManager
{
void playDisk(Disk disk, bool Mode);
}
- PhysisFlyAction
物理运动动作,控制飞碟的运动轨迹,为刚体飞碟设置重力和初速度,使得飞碟以不同的初速度和重力的影响下飞行。
public class PhysisFlyAction : SSAction
{
public float Power = 10;//这个代表发射时的速度
private Vector3 MoveSpeed = new Vector3(10,0,0);//初速度
public DiskFactory diskfactory;
public UserGUI User;
public static PhysisFlyAction GetSSAction(float Power,float Angle,float Gravity,Vector3 MoveSpeed)
{
PhysisFlyAction action = ScriptableObject.CreateInstance<PhysisFlyAction>();
action.Power = Power;
action.MoveSpeed = MoveSpeed;
return action;
}
public override void Update()
{
}
public override void FixedUpdate(){
if(this.transform.position.y < -7 || this.transform.position.x > 10){
if(this.transform.position.x > 0 && User.HP > 0) User.HP--;
diskfactory.FreeDisk(this.gameobject);
this.destroy = true;
this.callback.SSActionEvent(this);
}
}
public override void Start(){
//User = gameObject.AddComponent<UserGUI>() as UserGUI;
gameobject.GetComponent<Rigidbody>().velocity = MoveSpeed;
gameobject.GetComponent<Rigidbody>().useGravity = true;
diskfactory = Singleton<DiskFactory>.Instance;
User = Singleton<UserGUI>.Instance;
}
}
- PhysisActionManager
物理动作管理类,与CCActionManager一样,通过PhysisFlyAction来管理飞碟的飞行运动。
public class PhysisActionManager : SSActionManager
{
private PhysisFlyAction diskfly;
protected new void Start()
{
}
public void fly_disk(Disk disk){
diskfly = PhysisFlyAction.GetSSAction(disk.Power,disk.Angle,disk.Gravity,disk.MoveSpeed);
this.RunAction(disk.getGameObject(), diskfly, this);
}
}
- Adapter
适配器,该类继承了IActionManager接口,可以通过Mode状态的不同来选择不同的动作管理器,从而实现不同的运动方式。
public class Adapter : MonoBehaviour,IActionManager
{
public MySceneActionManager actionManager;
public PhysisActionManager actionManagerPhysis;
public void playDisk(Disk disk, bool Mode){
if(Mode){
actionManagerPhysis.fly_disk(disk);
}
else{
actionManager.fly_disk(disk);
}
}
void Start (){
actionManager = gameObject.AddComponent<MySceneActionManager>() as MySceneActionManager;
actionManagerPhysis = gameObject.AddComponent<PhysisActionManager>() as PhysisActionManager;
}
}
- SSAction
由于刚体运动比较适合使用FixedUpdate,因此增加几行代码
public virtual void FixedUpdate()
{
throw new System.NotImplementedException();
}
- SSActionManager
调用SSAction的FixedUpdate和Update,增加的代码如下
protected void FixedUpdate(){
foreach (SSAction ac in waitingAdd)
{
actions[ac.GetInstanceID()] = ac;
}
waitingAdd.Clear();
foreach (KeyValuePair<int, SSAction> kv in actions)
{
SSAction ac = kv.Value;
if (ac.destroy)
{
waitingDelete.Add(ac.GetInstanceID());
}
else if (ac.enable)
{
ac.FixedUpdate();
}
}
foreach (int key in waitingDelete)
{
SSAction ac = actions[key];
actions.Remove(key);
DestroyObject(ac);
}
waitingDelete.Clear();
}
- Controll 动作管理类
需要将原先的动作管理器改成Adapter,需要飞碟运动时,调用playDisk方法即可。
//actionManager = gameObject.AddComponent<MySceneActionManager>() as MySceneActionManager;
actionManager = gameObject.AddComponent<Adapter>() as Adapter;
- UserGUI
在用户界面提供了一个按钮,用户可以点击按钮来实现物理学和运动学运动的转换
if(GUI.Button (new Rect (Screen.width-100, Screen.height-200, 100, 40), "ChangeMode")){
Mode = !Mode;
}
由于物理运动需要飞碟是刚体,所以为飞碟预制体增加一个刚体属性,并不勾选Use Gravity,这是防止运动学运动时飞碟受到一个初始重力。
运行截图
上一篇: HW5 与游戏世界交互