Unity肉鸽卡牌开发记录02-手牌

功能需求

手牌会在手牌区域内展示给玩家,其主要功能包括:

  • 显示卡牌的法术力消耗、名称、卡图、类别、效果、攻击力和生命值(针对怪兽卡)

  • 鼠标移动到卡牌上时,卡牌边框高亮,并在屏幕显示卡牌的详情

  • 鼠标可以拖拽卡牌,当卡牌被拖拽出卡牌区并松开鼠标时,视为出牌

  • 若卡牌没有被拖拽出卡牌区,则不视为出牌

  • 预留卡牌被抽取时(类似万智牌的奇迹)、被展示时(通联古咒)、被弃掉时(疯魔)、被使用时(类似炉石传说的战吼)的方法

CardInHand基类

CardInHand基类中主要实现Awake和OnEnable。其中Awake方法中通过GetComponent为各个TextMeshPro变量赋值以便显示卡牌信息,OnEnable方法中则利用多态将card转换为对应的子类并将其信息转换为string赋值给各个TextMeshPro。

另外,CardInHand基类实现IPointerEnterHandler,IPointerExitHandler,IDragHandler,IEndDragHandler,IPointerClickHandler接口,实现其中的方法对鼠标进入、离开、拖拽等做出响应。

其他诸如OnPlayCard方法(当手牌被打出时)交由子类实现。

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

//TODO: 优化卡牌悬停高亮、选中效果
public class CardInHand : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IDragHandler,IEndDragHandler,IPointerClickHandler
{
public Card card;
public TMPro.TextMeshPro pointCost;
public TMPro.TextMeshPro cardName;
public TMPro.TextMeshPro cardType;
public TMPro.TextMeshPro cardAbility;
public TMPro.TextMeshPro cardAtk;
public TMPro.TextMeshPro cardHp;

virtual protected void Awake()
{
pointCost = transform.Find("Cost").GetComponent<TMPro.TextMeshPro>();
cardName = transform.Find("Name").GetComponent<TMPro.TextMeshPro>();
cardType = transform.Find("Type").GetComponent<TMPro.TextMeshPro>();
cardAbility = transform.Find("Ability").GetComponent<TMPro.TextMeshPro>();
cardAtk = transform.Find("Atk").GetComponent<TMPro.TextMeshPro>();
cardHp = transform.Find("Health").GetComponent<TMPro.TextMeshPro>();
}

virtual protected void OnEnable()
{
if(card is Monster)
{
Monster monster = (Monster)card;
pointCost.text = monster.pointCost.ToString();
cardName.text = monster.cardName;
cardAbility.text = monster.ability;
cardAtk.text = monster.atk.ToString();
cardHp.text = monster.hp.ToString();
cardType.text = "怪兽~"+CardEnumConvertor.GetInstance().MonsterRaceEnumToString(monster.race)
+ CardEnumConvertor.GetInstance().MonsterDutyEnumToString(monster.duty);
}
if(card is Magic)
{
Magic magic = (Magic)card;
pointCost.text = magic.pointCost.ToString();
cardName.text = magic.cardName;
cardAbility.text = magic.ability;
cardType.text = "魔法";
}
if(card is Equipment)
{
Equipment equipment = (Equipment)card;
pointCost.text = equipment.pointCost.ToString();
cardName.text = equipment.cardName;
cardAbility.text = equipment.ability;
cardHp.text = equipment.hp.ToString();
cardType.text = "装备";
}
if(card is Weapon)
{
Weapon weapon = (Weapon)card;
pointCost.text = weapon.pointCost.ToString();
cardName.text = weapon.cardName;
cardAbility.text = weapon.ability;
cardAtk.text = weapon.atk.ToString();
cardHp.text = weapon.hp.ToString();
cardType.text = "武器";
}
if(card is Trap)
{
Trap trap = (Trap)card;
pointCost.text = trap.pointCost.ToString();
cardName.text = trap.cardName;
cardAbility.text = trap.ability;
cardAtk.text = "0";
cardHp.text = trap.hp.ToString();
cardType.text = "陷阱";
}
if(card is Arena)
{
Arena arena = (Arena)card;
pointCost.text = arena.pointCost.ToString();
cardName.text = arena.cardName;
cardAbility.text = arena.ability;
cardAtk.text = "";
cardHp.text = "";
cardType.text = "场地";
}
}

/// <summary>
/// 当牌张被抓起时
/// </summary>
virtual protected void OnDrawToHand()
{

}

/// <summary>
/// 当牌张被展示时
/// </summary>
virtual protected void OnRevealed()
{

}

/// <summary>
/// 当牌张被弃掉时
/// </summary>
virtual protected void OnDiscard()
{

}

/// <summary>
/// 当牌张被打出时
/// </summary>
virtual protected void OnPlayCard()
{
CardRevealTool.GetInstance().showCardInfo(card, false);
Debug.Log("打出:"+card.cardName);
}

/// <summary>
/// 当牌张被放逐时
/// </summary>
virtual protected void OnExile()
{

}

/// <summary>
/// 当牌张被洗回牌库时
/// </summary>
virtual protected void OnShuffleBack()
{

}

/// <summary>
/// 当鼠标悬停在卡牌上时:展示卡牌详情
/// </summary>
/// <param name="eventData"></param>
virtual public void OnPointerEnter(PointerEventData eventData)
{
transform.Find("Background").GetComponent<SpriteRenderer>().color = Color.yellow;
CardRevealTool.GetInstance().showCardInfo(card, true);
}

/// <summary>
/// 当鼠标从卡牌上移开时:取消展示卡牌详情
/// </summary>
/// <param name="eventData"></param>
virtual public void OnPointerExit(PointerEventData eventData)
{
CardRevealTool.GetInstance().showCardInfo(card, false);
transform.Find("Background").GetComponent<SpriteRenderer>().color = new Color32(0,204,253,255);
}

/// <summary>
/// 当鼠标拖拽卡牌时:卡牌随鼠标移动,准备出牌
/// </summary>
/// <param name="eventData"></param>
virtual public void OnDrag(PointerEventData eventData)
{
Vector3 temp = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(temp.x, temp.y, transform.position.z);
}

/// <summary>
/// 当鼠标停止拖拽卡牌时:判断卡牌位置,如果超出手牌区域即出牌
/// </summary>
/// <param name="eventData"></param>
virtual public void OnEndDrag(PointerEventData eventData)
{
if(transform.localPosition.y > 0.5f)
{
//TODO: 法术力消耗判断
transform.SetParent(null);
CardAreaManager.GetInstance().PlayACard(card);
OnPlayCard();
Destroy(gameObject);
}
else
{
CardRevealTool.GetInstance().ListHand();
}
}

/// <summary>
/// 当鼠标点击卡牌时:显示卡牌详情+出牌提示(待定)
/// </summary>
/// <param name="eventData"></param>
virtual public void OnPointerClick(PointerEventData eventData)
{

}
}

各卡牌的InHand类

各张卡牌的InHand类继承CardInHand,新增属性cardId并在Awake方法中通过cardId获取对应的Card(SO)。

示例:StormDragon的InHand类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StormDragonInHand : CardInHand
{
public int cardId = 0;

protected override void Awake()
{
base.Awake();
card = CardAreaManager.GetInstance().AllCardList.cardList[cardId];
}
}

TODO

  • [ ] 优化卡牌悬停高亮、选中效果。