嗨,各位程式碼冒險家!歡迎來到我的「順著感覺走!從零開始的 Python & Vibe Coding 遊戲創作」第十八天。如果說 GameManager
是遊戲的心臟,那麼今天我們要深入探討的 trigger_card_effect
方法,就是將卡牌從一張靜態圖片,轉化為能夠撼動戰局的強大力量的關鍵。這個方法是整個戰鬥系統的核心,負責解析卡牌效果並精準地將其應用到目標身上。
在先前的設計中,我們使用一個名為 SkillEffect
的字典(Dictionary),集中管理了所有卡牌的技能效果。這種設計的優勢在今天將完全體現出來:它讓技能觸發邏輯變得極其靈活且易於維護。現在,讓我們深入 gamemanager.py
,剖析這個賦予卡牌生命的方法。
trigger_card_effect
方法trigger_card_effect
方法位於 GameManager
類別中,其職責非常明確:接收觸發的卡牌類型、施法者與目標,然後根據 SkillEffect
字典的定義,執行一系列對應的遊戲邏輯。
gamemanager.py
)def trigger_card_effect(self, card_type, caster, target):
if card_type not in SkillEffect:
return
effect = SkillEffect[card_type]
log_message = f"卡牌 {card_type.value} 效果觸發:"
effects_list = []
# 處理傷害 (Damage) 邏輯
if "damage" in effect:
damage = effect["damage"]
is_piercing = "pierce_shield" in effect and effect["pierce_shield"]
if is_piercing:
target.health = max(target.health - damage, 0)
effects_list.append(f"對 {target.name} 造成 {damage} 穿透傷害")
else:
damage_dealt = target.take_damage(damage)
effects_list.append(f"對 {target.name} 造成 {damage_dealt} 傷害")
# 處理治療 (Heal) 邏輯
if "heal" in effect:
heal_amount = effect["heal"]
caster.heal(heal_amount)
effects_list.append(f"{caster.name} 恢復 {heal_amount} HP")
# 處理護盾 (Shield) 邏輯
if "shield" in effect:
shield_amount = effect["shield"]
caster.add_shield(shield_amount)
effects_list.append(f"{caster.name} 增加 {shield_amount} 護盾")
# 處理額外行動 (Extra Moves) 邏輯
if "extra_moves" in effect:
self.action_count = max(0, self.action_count - effect["extra_moves"])
effects_list.append(f"{caster.name} 獲得 {effect['extra_moves']} 次額外行動")
# 整合並記錄到戰鬥日誌
log_message += ",".join(effects_list)
self.add_to_log(log_message)
SkillEffect
字典的運用card_type
, caster
, target
:這三個參數是方法執行的基礎,清楚定義了「哪張牌 (card_type
)」由「誰 (caster
)」對「誰 (target
)」產生了效果。effect = SkillEffect[card_type]
:這是整個方法的查詢核心。程式碼利用傳入的 card_type
作為鍵(Key),直接從 SkillEffect
字典中獲取對應的效果描述(一個包含具體效果的子字典)。例如,當 card_type
是 CardType.SWORDSMAN
時,effect
就會是 {"damage": 15}
。這種鍵值對查詢的方式,讓我們無需使用冗長的 if/elif/else
結構來判斷卡牌類型,大幅提升了程式碼的可讀性與擴充性。這是最複雜的邏輯區塊,體現了條件判斷的精妙之處。
if "damage" in effect:
:首先檢查效果字典中是否存在 "damage"
這個鍵。pierce_shield
):程式會進一步檢查 "pierce_shield"
鍵是否存在且其值為 True
。如果是,則直接扣減目標的 health
屬性,完全繞過護盾的計算邏輯。這正是魔法師卡牌(造成10點無視護盾傷害)的實現方式。Player
物件的 take_damage
方法。這個方法內部已經封裝了優先扣除護盾、再扣生命值的完整邏輯,確保了傷害計算的準確性。這種職責分離的設計(GameManager
負責觸發,Player
負責承受)讓程式碼結構更清晰。if "heal" in effect:
:當效果字典包含 "heal"
鍵時,程式會取出治療數值,並呼叫施法者 (caster
) 自己的 heal
方法。heal
方法會確保生命值不會超過 max_health
上限。例如,祭司卡牌能恢復 15 點生命。if "shield" in effect:
:同理,若有 "shield"
鍵,則呼叫施法者的 add_shield
方法增加護盾值。例如,元素使在造成傷害的同時,還能為自己增加 10 點護盾。self.action_count = max(0, self.action_count - effect['extra_moves'])
:這個實現非常巧妙。遊戲規則是每回合最多 5 次行動。與其增加總行動上限,程式選擇直接減少「已消耗」的行動次數 (self.action_count
)。action_count
為 3),此時打出盜賊卡(提供 1 次額外行動)。action_count
會變成 max(0, 3 - 1)
,也就是 2。這相當於「返還」了一次行動機會,讓玩家在本回合中可以再行動 3 次(5 - 2 = 3),完美實現了額外行動的效果。self.add_to_log(log_message)
:在所有效果處理完畢後,程式會將生成的日誌訊息 (log_message
) 加入到 self.combat_log
這個清單中。這不僅方便開發者進行除錯,也為後續打造可回顧的戰鬥紀錄介面提供了數據基礎。透過 trigger_card_effect
這個精心設計的方法,我們成功地將遊戲的核心機制——卡牌技能——模組化且高效地實現了。它與 SkillEffect
字典的完美結合,不僅讓當前的程式碼清晰易懂,更為未來新增卡牌、調整平衡性留下了極大的彈性空間。
明天,我們將探討牌組的流轉機制,看看遊戲是如何處理抽牌、棄牌以及手牌上限等重要規則的。敬請期待!