1. 程式人生 > >Unity遊戲設計模式(三)原型模式(Prototype Pattern)

Unity遊戲設計模式(三)原型模式(Prototype Pattern)

        原型模式,顧名思義就是通過物件的原型克隆而產生的新的物件。原型模式在遊戲中運用非常多。怪物,一張地圖上有許許多多的怪物,這些怪物一般都具有共通性,同一種怪物就有可能擁有同樣的模型,同樣的攻擊方式等。即使是不同型別的怪物他們也擁有許多共通性,例如都擁有攻擊力,都擁有血量等。這些怪物就是以基類怪物為父本克隆出來的子物體。例如:一張地圖上有野獸、有殭屍、有人形敵人,那麼我們統稱這些怪物為Monster,所有的怪物形態各異但是都是由於Monster為父本克隆出來的。

        下面以一個武器生成器為例子,有的遊戲具有附魔功能,附魔後的武器在原有屬性不變的基礎上又增加了新的屬性,這也是一種原型模式的應用。

    /// <summary>
    /// 定義一個基本武器型別,基本武器內含有子類共有的屬性,擁有Clone的抽象方法
    /// </summary>
    public abstract class Sword
    {
        protected string Name;
        protected int Atk;
        protected int Speed;
        public Sword()
        {
            Name =_Name;
            Atk =_Atk;
            Speed =_Speed;
        }
        public abstract Sword Clone();
        public abstract void ShowInfo();
    }

我們首先定義一個抽象類作為武器的父類,抽象類武器擁有所有武器的共同屬性,同時抽象類武器必須擁有一個Clone的抽象方法,用以生成新的武器,其他的方法可以自行根據需求拓展。
    /// <summary>
    /// 定義一個子類武器,子類武器可拓展其他屬性,通過Clone方法返回新生成的武器型別
    /// </summary>
    public class SacredSword : Sword
    {
        private int _heal;
        public int Heal
        {
            get { return _heal; }
            set { _heal = value; }
        }
        public override Sword Clone()
        {
            SacredSword sacredSword = new SacredSword();
            sacredSword.Heal = Random.Range(5, 20);
            return sacredSword;
        }
        public override void ShowInfo()
        {
            Debug.Log("聖神的" + Name + ":" + " 攻擊:" + Atk + " 攻擊速度:" + Speed + " 每秒恢復:" + Heal + "點血");
        }
    }

然後我們就是定義子類武器了子類武器繼承自基類武器且可以自行拓展各種屬性,同時子類武器完善Clone方法,根據需求產生新的武器。
    /// <summary>
    /// 武器生成器,通過基類的Clone方法生成新武器
    /// </summary>
    /// <param name="sword"></param>
    /// <returns></returns>
    public Sword SwordSpawner(Sword sword)
    {
        return sword.Clone();
    }

這段程式碼是一個武器生成器,通過返回Clone方法生成的新武器

完整程式碼:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Flyweight : MonoBehaviour
{
    private static string _Name;//父類武器名稱
    private static int _Atk;//父類武器攻擊力
    private static int _Speed;//父類武器攻擊速度
    private SacredSword sacredSword;//子類武器1
    private WickedSword wickedSword;//子類武器2
    private List<Sword> SwordList;//武器集合
    /// <summary>
    /// 定義一個基本武器型別,基本武器內含有子類共有的屬性,擁有Clone的抽象方法
    /// </summary>
    public abstract class Sword
    {
        protected string Name;
        protected int Atk;
        protected int Speed;
        public Sword()
        {
            Name =_Name;
            Atk =_Atk;
            Speed =_Speed;
        }
        public abstract Sword Clone();
        public abstract void ShowInfo();
    }
    /// <summary>
    /// 定義一個子類武器,子類武器可拓展其他屬性,通過Clone方法返回新生成的武器型別
    /// </summary>
    public class SacredSword : Sword
    {
        private int _heal;
        public int Heal
        {
            get { return _heal; }
            set { _heal = value; }
        }
        public override Sword Clone()
        {
            SacredSword sacredSword = new SacredSword();
            sacredSword.Heal = Random.Range(5, 20);
            return sacredSword;
        }
        public override void ShowInfo()
        {
            Debug.Log("聖神的" + Name + ":" + " 攻擊:" + Atk + " 攻擊速度:" + Speed + " 每秒恢復:" + Heal + "點血");
        }
    }

    public class WickedSword : Sword
    {
        private int _suck;

        public int Suck
        {
            get { return _suck; }
            set { _suck = value; }
        }
        public override Sword Clone()
        {
            WickedSword wickedSword = new WickedSword();
            wickedSword.Suck = Random.Range(1, 6);
            return wickedSword;
        }
        public override void ShowInfo()
        {
            Debug.Log("邪惡的" + Name + ":" + " 攻擊:" + Atk + " 攻擊速度:" + Speed + " 吸血:" +Suck+ "%");
        }
    }
    /// <summary>
    /// 武器生成器,通過基類的Clone方法生成新武器
    /// </summary>
    /// <param name="sword"></param>
    /// <returns></returns>
    public Sword SwordSpawner(Sword sword)
    {
        return sword.Clone();
    }
    /// <summary>
    /// 設定基類武器屬性
    /// </summary>
    /// <param name="name"></param>
    /// <param name="atk"></param>
    /// <param name="speed"></param>
    public void SetValue(string name,int atk,int speed)
    {
        _Name = name;
        _Atk = atk;
        _Speed = speed;
    }
    void Start()
    {
        SwordList = new List<Sword>();//例項化武器集合
        sacredSword = new SacredSword();//例項化武器1
        wickedSword = new WickedSword();//例項化武器2
        SetValue("短劍", 10, 5);        
    }
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            SwordList.Add(SwordSpawner(sacredSword));
        }
        if (Input.GetKeyDown(KeyCode.B))
        {
            SwordList.Add(SwordSpawner(wickedSword));
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            foreach (Sword sword in SwordList)
            {
                sword.ShowInfo();
            }

            SwordList.Clear();
        }
    }
}