起因
我在寫技能相關的代碼
class 技能 {
List<效果> Effects;
virtual bool 檢查(object args) {return True;}
virtual void 釋放(object args) {
if (!檢查(args)) return;
foreach(var e in Effects){
e.執行(args)
}
}
}
class 效果 {
virtual void 執行(object args) {}
}
後面我發現可能需要加一個參數: 玩家,
也就是要改成這樣
class 技能 {
List<效果> Effects;
virtual bool 檢查( /*增加*/ 玩家 player, object args) {return True;}
virtual void 釋放( /*增加*/ 玩家 player, object args) {
if (!檢查( /*增加*/ player, args)) return;
foreach(var e in Effects){
e.執行( /*增加*/ player, args)
}
}
}
class 效果 {
virtual void 執行( /*增加*/ 玩家 player, object args) {}
}
我覺得這很麻煩.
我發現類中調用函數this.檢查(args)可以省略this.
類中聲明函數 void 檢查(object args),
實際上也省略了一個參數 void 檢查(this 技能 skill, object args)
於是我想可以讓一個函數屬於多個類, 進而省略多個參數.
概覽
具體設計下面説, 先看一下新代碼的樣子.
struct 技能 {
List<效果> Effects;
}
struct 效果 {}
env (技能 skill) {
檢查,
釋放,
}
env (效果 effect) {
執行,
}
env ( /*只需要修改這裏*/ 玩家 player, object args) {
檢查,
釋放,
執行,
}
fn bool 檢查() {return True;}
fn void 釋放() {
if (!檢查()) return;
foreach(var e in Effects){
執行(effect = e)
}
}
fn void 執行() {}
具體設計
結構體
// struct中不能有函數了
struct 技能 {
int 威力,
};
// 可以有繼承
struct 範圍技能 : 技能{
int 範圍,
};
struct 角色 {
string 名字,
};
struct 召喚角色: 角色{
角色 主人,
}
環境(新東西)
// 新概念: 環境
// 環境是多個函數所共享的參數
env (角色 起始) {
釋放技能,
播放釋放動畫,
承受傷害
};
// 同一個函數可以屬於多個環境
env (技能 當前技能) {
釋放技能,
播放釋放動畫,
承受傷害
};
函數(新東西)
// 環境參數名必須與環境聲明時相同.
fn void 釋放技能(角色 起始, 技能 當前技能, 角色 目標){
// 環境參數的順序不重要. (但其他參數的順序很重要)
播放釋放技能動畫(起始 = 起始, 當前技能 = 當前技能);
承受傷害(起始 = 目標);
}
// 與上面的效果相同
// 環境參數可以部分省略, 或全部省略.
fn void 釋放技能(技能 當前技能, 角色 目標){
// 同名的環境參數會自動傳參
播放釋放技能動畫();
// 自動傳參失效的時候, 需要手動設置環境參數
承受傷害(起始 = 目標);
}
override (還沒設計好)
fn void 播放釋放動畫() {
// 默認實現
}
fn void 播放釋放動畫(範圍技能 當前技能) {
// 範圍技能的實現
}
fn void 播放釋放動畫(召喚角色 起始) {
// 召喚角色的實現
}
// 為了解決衝突, 可以增加這個.
// 但不是必須的, 用到了但是沒有, 就運行時拋出錯誤.
fn void 播放釋放動畫(召喚角色 起始, 範圍技能 當前技能){
// ...
}
// 還在想更好的解決方式, 我想把兩個函數自動組合起來.