Unity实现鼠标打飞碟(Hit UFO)adapter模式

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,这是防止运动学运动时飞碟受到一个初始重力。

运行截图

在这里插入图片描述

视频链接
代码链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值