設計思路
提供一個單例腳本
SkillDatabase
,提供關于此技能的固定資料,如技能id, 技能名稱技能最大等級,技能描述,技能更新消耗等。
提供一個抽象節點,此節點用于描述一個技能,我将此節點注冊為一個GoDot新的類型,開發者通過擴充腳本功能完成技能的開發。
SkillDatabase
SkillDatabase
提供
get_skill_arg
函數來提取技能固定資料,實作如下:
#技能資料庫 用于提取技能資訊
extends Node
var skills:Dictionary = {}
func _ready():
init_skill_dic()
pass
func init_skill_dic() :
#在此處初始化技能資訊, 可以從其他資料庫,excel等載體中讀取,此處為了示例直接寫在代碼裡
#請這些技能資訊:并非完整的數值資訊和傷害邏輯
skills = { #id
"skill_0000001":{
#最大等級
"max_leve": 20,
#名稱
"name":"普通射擊",
#描述 展現你的傷害邏輯
"desp":"對目标位置進行射擊, 造成 {base_damage} 實體傷害,如果目标處于眩暈、虛弱、減速等移動受限狀态,則傷害提高 {ext_increment}%",
#等級提升所需消耗 此處隻消耗一項經驗值 可以自行擴充為字典,用以消耗多個資源
"leve_up_cost": [10,10,10,20,20,20,30,30,50,50,100,100,100,150,150,150,200,300,400]
},
"skill_0000002":{
#最大等級
"max_leve": 30,
#名稱
"name":"精準射擊",
#描述
"desp":"花費時間對這一擊精心準備,短暫延遲後,對目标進行精确打擊,造成 {base_damage} + {ext_incremnt}%額外實體傷害{damage_out} 此攻擊無視目标閃避率",
#等級提升所需消耗 此處隻消耗一項經驗值 可以自行擴充為字典,用以消耗多個資源
"leve_up_cost": [10,10,10,20,20,20,30,30,50,50,100,100,100,150,150,150,200,300,400]
}
}
pass
func get_skill_arg(arg_name:String, id:String) :
return skills[id][arg_name]
SkillBase
###############技能模型########################
#繼承此腳本用以建立新的技能
#需要你初始化的變量 skill_id , skill_level
#需要你重新實作的函數:
# _replace_skill_var
##############################################
extends Node
class_name SkillBase
###########以下成員繼承後需要子類進行初始化#################
onready var skill_id:String = "x"
onready var skill_level:int = 0
#技能面闆上展示的技能名稱
func _get_skill_title() -> String:
return SkillDatabase.get_skill_arg("name",skill_id) + "(LV" + String(skill_level) + ")"
pass
#如果你的技能描述中存在變量,例如 : 造成 {base_damage} 實體傷害
#則你必須重寫此函數 将_skill_raw_desp 中的 變量 {base_damage} 替換為此技能的實際數值
#預設的實作僅僅傳回參數而不做任何事
#func _replace_skill_var(_skill_raw_desp : String) ->String:
# return _skill_desp.format({"base_damage":20})
func _replace_skill_var(_skill_raw_desp : String) ->String:
return _skill_raw_desp
pass
func get_desp_string() -> String:
var raw_desp:String = SkillDatabase.get_skill_arg("desp", skill_id)
return _replace_skill_var(raw_desp)
pass
#計算技能影響乘區 請根據技能傷害邏輯在子類中實作傷害計算
func _get_skill_damage() -> float :
return 0.0
#如果是需要選中目标的技能 則傳回最大目标數
func _get_skill_target_count() -> int :
return 0
實作一個技能
建立一個節點,選擇新增的
SkillBase
節點
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5yNxUzM4U2M5QTN0cTM1IDOxYzX0ADOwcTMzAzLcFTMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
更改節點名稱為
Skill_0001
(實際項目不要這樣取名字...),并選擇擴充腳本
按照父節點要求,我們進行如下實作:
在這個腳本中,我們會實作一個簡單的技能,技能會擁有完整說明
extends SkillBase
var base_damage := 0.0
var target_state := "眩暈"
func _ready():
skill_id = "skill_0000001"
skill_level = 1
pass
#計算技能影響乘區 請根據技能傷害邏輯在子類中實作傷害計算
#"對目标位置進行射擊, 造成 {base_damage} 實體傷害,如果目标處于眩暈、虛弱、減速等移動受限狀态,則傷害提高 {ext_increment}%",
func _get_skill_damage() -> float :
base_damage = calc_base_damage() #此處可計算其他邏輯 比如傷害加成 什麼的。。。。
#注意 由于隻示範技能系統 是以代碼與其他系統互動存在不完善, 如此處 ["眩暈","減速","虛弱"] 僅僅是示例,
#應該提供一個函數傳回所有 移動受限狀态
#且 target_state 應由戰鬥系統給出 此處僅做示例!!
if ["眩暈","減速","虛弱"].has(target_state) :
base_damage += base_damage * calc_ext_increment() / 100.0
return 0.0
#如果你的技能描述中存在變量,例如 : 造成 {base_damage} 實體傷害
#則你必須重寫此函數 将 skill_var_list 中的 變量 {base_damage} 替換為此技能的實際數值
#預設的實作僅僅傳回參數而不做任何事
#func _replace_skill_var(_skill_raw_desp : String) ->String:
# return _skill_desp.format({"base_damage":20})
func _replace_skill_var(_skill_raw_desp : String) ->String:
_skill_raw_desp.format({"base_damage":calc_base_damage()})
_skill_raw_desp.format({"ext_increment":calc_ext_increment()})
return _skill_raw_desp
pass
#如果是需要選中目标的技能 則傳回最大目标數
func _get_skill_target_count() -> int :
#隻示範最簡單的情況
match skill_level :
1,5 :
return 1
6,20 :
return 2
return 0
func calc_base_damage() -> float:
return skill_level * 15.0
func calc_ext_increment() -> float:
return 20.0
測試
在場景中添加一個Sprite并添加以下腳本進行測試
extends Sprite
onready var skill = preload("res://Scene/Skill_0001.tscn").instance()
func _ready():
print("sprite ready")
add_child(skill)
skill.skill_level = 1
pass
func _process(delta):
if Input.is_action_just_pressed("ui_accept") :
print(skill.skill_id)
print(skill.skill_level)
print("技能名稱: ",skill._get_skill_title())
print("技能輸出: ",skill._get_skill_damage())
print("技能描述: ",skill.get_desp_string())
print("技能目标數: ", skill._get_skill_target_count())
if Input.is_action_just_pressed("ui_page_up") :
skill.skill_level += 1
print("技能更新!")