Unity游戏设计模式(三)原型模式(Prototype Pattern)

思考并回答以下问题:

原型模式,顾名思义就是通过对象的原型克隆而产生的新的对象。原型模式在游戏中运用非常多。怪物,一张地图上有许许多多的怪物,这些怪物一般都具有共通性,同一种怪物就有可能拥有同样的模型,同样的攻击方式等。即使是不同类型的怪物他们也拥有许多共通性,例如都拥有攻击力,都拥有血量等。这些怪物就是以基类怪物为父本克隆出来的子物体。例如:一张地图上有野兽、有僵尸、有人形敌人,那么我们统称这些怪物为Monster,所有的怪物形态各异但是都是由于Monster为父本克隆出来的。

    下面以一个武器生成器为例子,有的游戏具有附魔功能,附魔后的武器在原有属性不变的基础上又增加了新的属性,这也是一种原型模式的应用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// <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的抽象方法,用以生成新的武器,其他的方法可以自行根据需求拓展。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/// <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方法,根据需求产生新的武器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    /// <summary>
/// 武器生成器,通过基类的Clone方法生成新武器
/// </summary>
/// <param name="sword"></param>
/// <returns></returns>
public Sword SwordSpawner(Sword sword)
{
return sword.Clone();
}
``
这段代码是一个武器生成器,通过返回Clone方法生成的新武器


完整代码:
```cs
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();
}
}
}

0%