您的位置:首页 > 移动开发 > Unity3D

一、策略模式(Unity3d演示)

2017-02-23 00:31 190 查看
转自:http://blog.csdn.net/wowkk/article/details/9865855  
先学设计模式还是先学数据结构算法?我还是选择前者。兴趣在应用层呵呵。
    不久前我还以为三层架构也是设计模式中的一种,现在才知道,开发模式和设计模式是不一样的。

    就我目前接触过的项目,基本都采用简单三层架构,最多加上工厂模式。感觉三层架构就像是“万金油”,哪里都能运用上,那为什么还要用到设计模式呢~我知道这肯是因为我碰到的场景不多。为了多点设计想法、多点学习英语,《head+first+设计模式》中英文一起看!

 
    策略模式(The Strategy pattern)
    设计模式中的策略模式是什么?要怎样应用策略模式?看看我的理解对不对吧^_^Unity3d游戏引擎演示。
    前半部分对策略模式的理解需要一些多态基础。后部分的演示需要Unity3d基础(写了一些关于Unity3d的教程了,以后成熟了再发吧。)
   
    定义:定义算法族,分别封装起来,让它们之前可以互相替换,此模式让算法的变化独立于使用算法的客户。

    场景:有一个游戏,游戏里有一个池塘,池塘里有一堆鸭子。有各种各样的鸭子,它们都继承自同一个基类,各自重写了基类的一些功能。以前,鸭子都会游,不同鸭子会有不同的叫声(多态Polymorphism)。现在,突然要给一些鸭子添加“飞”的功能。如果像以前那样,在基类实现“飞”的功能,那所有鸭子都会飞了。如果给不要飞的鸭子重写“飞”的函数让它不会飞或者只给要飞的鸭子写“飞”的功能,那将丢失代码的可重用性(Reuse)。

    策略模式将对象模型(Model)与对象的一些经常变动的行为(Behaviour)进行分离,将原有的“Is-A”(是一个类)模式改为“Has-A”(类包含类)模式。

    行为类,比如飞,也有一个共同接口(Interface)(相当于纯虚类?)。需要的话,可以多态成多种多样的飞行类。

    在对象模型里,比如鸭子。封装(Encapsulation)了一个飞行接口,然后在构造函数里,对这个接口进行实例化(Instantiase),让鸭子具有某种飞的功能。之后,给鸭子一个飞的方法,调用接口飞的行为,让鸭子飞起来。

    这样,我们在应用层中,实例化一个鸭子模型,需要飞时,直接使用该模型的飞方法即可。

    这是策略模式一个强大的优点。相对于普通的面向对象设计(Object - Oriented),大大提高代码的可重用性。

    另外一个优点,就是可以在程序运行时,改变对象模型的行为。只需要给模型写一个 setBehavior(NewBehavior n){替换将私有的行为变量;}方法,这样,就算新设计的飞行行为,也可以很迅速的分配给任何模型。

    下面试下能否利用unity3d来演示。(在我的理解中,其实游戏引擎已经完全做到了这一点!导入一个模型,里面的“动画组件”就是行为分离。需要让模型进行某些动作,只需要在“动画组件”里进行设计,然后赋给模型即可!)

    我专门找了一个鸭子模型:

    


    为了测试方便,就不使用鸭子模型继承了。

    首先创建一个飞行接口:

[csharp] view
plain copy

 print?





public interface IFly  

  

     {  

  

        void Fly(GameObject g); //GameObject参数指的是“鸭子”  

  

     }  

   
    以后新添加的飞行类型都继承自该接口。比如这里的“垂直上飞”行为

   

[csharp] view
plain copy

 print?





public class Fly1:IFly  

  

     {  

  

        //让物体垂直向上飞  

  

        void IFly.Fly(GameObject g) {  

  

            g.transform.Translate(0, 1 * Time.deltaTime, 0, Space.Self);  

  

        }  

  

     }  

 

[csharp] view
plain copy

 print?





public class Fly2:IFly  

{  

       //45度向前飞行  

       void IFly.Fly(GameObject g) {  

           g.transform.Translate(1 * Time.deltaTime, 1 * Time.deltaTime, 0, Space.Self);  

       }  

}  

 

    接着就是创建一个鸭子类了。

[csharp] view
plain copy

 print?





public class Duck {  

  

    private GameObject duck;//鸭子模型(在构造函数中赋值)  

  

    private IFly fly;//鸭子该如何飞?(在构造函数中初始化,或者在SetFlyBehavior()函数中设置)  

  

    public Duck(GameObject g)  

  

    {  

  

        duck = g;  

  

        fly = new Fly1();//多态的精髓!      

}  

  

    //让鸭子飞  

  

    public void Fly()  

  

    {  

  

        fly.Fly(duck);  

  

    }  

  

    //设置鸭子飞的方式  

  

    public void SetFlyBehavior(IFly f) {  

  

        fly = f;     

  

    }  

  

}  

    最后一个“类”,用来控制鸭子的。

   

[csharp] view
plain copy

 print?





public class Control : MonoBehaviour {  

  

    public GameObject g;  

  

    private Duck d;  

  

     // Use this for initialization  

  

     void Start () {  

  

        d = new Duck(g);  

  

     }  

  

      

  

     // Update is called once per frame  

  

     void Update () {  

  

        //按W键时飞行  

  

        if (Input.GetKey(KeyCode.W)) {  

  

            d.Fly();  

  

        }  

  

        //按空格键时改变飞行行为  

  

        if (Input.GetKey(KeyCode.Space)) {  

  

            d.SetFlyBehavior(new Fly2());  

  

        }  

  

     }  

  

}  

    最后!把“控制类”扔给相机,然后把“鸭子模型”扔给“控制类”的GameObject g变量!搞定!

    CSDN博客不能传视频,就录制下GIF凑合下吧。(飞到中间的时候,我按了空格键,然后就改变的飞行方式)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: