[回到版面]
回應模式
名 稱
E-mail
標 題
內 文
附加圖檔[] []
刪除用密碼(刪除文章用。英數字8字元以內)
  • 可附加圖檔類型:GIF, JPG, PNG, JPEG,瀏覽器才能正常附加圖檔
  • 附加圖檔最大上傳資料量為 10000 KB。當回文時E-mail填入sage為不推文功能
  • 當檔案超過寬 125 像素、高 125 像素時會自動縮小尺寸顯示
  • 程式碼可使用 [code][/code] 以 google-code-prettify 標亮 (程式自動判斷語言類別)

  • 公告、舉報、建議請向DB管理室辦理。
  • 本板討論遊戲製作為主,改造方面也可討論,但如果牽涉到版權,請自重。
  • 3D建模請至3D板, 3D遊戲製作(Ex.怎麼用DirectX跑3D?)則可在這討論。
  • 本板為一般向板面,禁止張貼上車圖。

檔名:1494435175749.jpg-(90 KB, 850x478) [以預覽圖顯示]
90 KB如何寫容易管理的Buff功能 名稱: 無名氏 [17/05/11(四)00:52 ID:HeLzLkl6] No.12725  
最近想試著寫類似Buff的功能,類似中毒、麻痺、詛咒、受擊反彈等等
但同一時間可能有很多Buff同時存在,判斷的地方也相差很多

以前有聽學長說用二進位的方法,但當時沒有仔細聽...
有人可以給一些建議或方向嗎?

Buff的觸發時間點像麻痺可能是行動前、中毒可能是行動後
類似這種時間點不一樣的Buff判斷,目前只單純的在判斷式前加if

但總覺得異常狀態很多或有疊加等複雜狀況,變得很難管理
無標題 名稱: 無名氏 [17/05/12(五)19:58 ID:VIByVJ6c] No.12733   
二進位的方法是老方法,叫做位元運算,>> << & |。

假設狀態一 1 狀態二 10 狀態三 100。
X = 111 
if (X & 1) //是否是狀態一
if (X & 2) //是否是狀態二
if (X & 4) //是否是狀態三
X |= 1; //X加入狀態一
X |= 2; //X加入狀態二
X |= 4; //X加入狀態三


然後你的異常狀態可以寫成資料庫,一開始直接窮舉丟入陣列裡。
把異常狀態的不同通通抓出來弄成資料庫欄位每個欄位放入,再把IF判斷式用陣列去循環判斷。
無標題 名稱: 無名氏 [17/05/13(六)10:12 ID:XyxnOzfU] No.12734 1推  
>>No.12733
如果有一種buff或debuff
會因為人物屬性變化的話
那也可以這樣寫嗎?

例如依照使用buff人物的力量跟智力
決定你被扣防的程度跟時間
無名氏: 當然是不行 最多只有32種狀況 (72EIRlu6 17/05/13 11:44)
無標題 名稱: 無名氏 [17/05/13(六)11:57 ID:72EIRlu6] No.12736   
struct BaseBuffer
{
AActor* _owner; //施法
AActor* _target;//目標
uint32_t _flag;//作用於 行動前 行動後 被攻擊 frame
uint32_t _type; //effect of time? count
int _count;
float _time; //啟動時間
float _end_time; //結束時間
virtual void update(float deltatime)=0;
};

struct HealOfTime:public BaseBuffer
{
float _lev;//等級
float _heal_ratio;//比例
float _heal_point;//一次回多少血
void update(float deltatime);
};
無標題 名稱: 無名氏 [17/05/13(六)15:03 ID:VuU.WRhc] No.12737   
二進位是古老時代運算資源不足時的做法
只能支援固定、沒變化性的狀態
中毒就是中毒
不管是誰放的、用哪招放,扣血量都一樣,也沒有持續時間

如果你要自由度比較高的Buff
能在裡面有動態參數、狀態能改變、能隨著版本更新大量增加新狀態
那就要把狀態包成一個struct(或class)
然後用陣列或串列儲存

兩種例子上面都有範例了
顯然是>>No.12733的版本程式比較短
>>No.12736可以支援的功能比較多元
除非你的遊戲本來就是低成本小遊戲,否則一般來說會建議用後者
無標題 名稱: 原PO [17/05/13(六)16:44 ID:CnCfR53s] No.12738   
感謝大家回覆,原本以為沒人回了QQ。
----
想在尋問一下關於後者的方法BaseBuffer
所以如果我有一隻角色可能同是有一堆Buff狀態
class Character
{
BaseBuffer buff[BUFF的總數量];
}

然後判斷的時候是,for迴圈
for (int i=0;i=buffMAX;i++)
if (Buff[i].flag == 行動前)
.....

這樣的設計方式是可以的嗎? 謝謝(或是有什麼更好的方法)
無標題 名稱: 無名氏 [17/05/13(六)17:39 ID:VuU.WRhc] No.12740   
這種東西本來就沒有很固定的寫法
能滿足你需求就行

以比較原始的做法來說,大概像是
//at turn end
for(int ci=0;ci<charaMax;ci++)
for(int bi=0;bi<chara[ci].buffMax;bi++)
switch(chara[ci].buff[bi].type)
{
case POISON:
case BURN:
chara[ci].damage(chara[ci].buff[bi].arg[0]);
break;
case AUTO_HEAL:
chara[ci].heal(chara[ci].buff[bi].arg[0]);
break;
case FREEZE:
if(rand()%100<10)
chara[ci].deleteBuff(bi);
break;
}

在各個時機去檢查buff並做出對應的處理
但這樣的缺點是buff種類一多起來程式碼就很髒

要改善這點,可以把buff效果用多型處理
class Buff{
//...
virtual void atStart(){}
virtual void atAttack(){}
virtual void atAttacked(){}
virtual void atEnd(){}
virtual bool isActable(){return true;}
};

class Poison:public Buff{
int poisonLevel;
void atEnd()
{
chara.damage(poisonLevel);
}
};

class Stun:public Buff{
bool isActable()
{
return false;
}
};

在不同時候呼叫對應的virtual function,處理該buff的效果
如果該buff在該時機沒有特別的效果,就會呼叫預設的空白函式
好處是主要戰鬥流程部分的code比較簡潔
可以把各種buff自己的code集中在一起,方便管理
但這種語法比較依賴程式語言
上例是C++的版本,如果是其他語言可能要用不同的語法關鍵字,甚至根本不支援這種做法
無標題 名稱: 無名氏 [17/05/13(六)21:11 ID:sdjiqK2A] No.12741   
這邊有一個MMO RPG 範例
裡面滿滿 buffer 技能 附魔 寫法
https://github.com/DarkstarProject/darkstar

抓一下來觀摩一下
無標題 名稱: 原PO [17/05/14(日)16:29 ID:HxxrZjh.] No.12745   
感謝各位,收獲良多
我這幾天會改成這樣的方式製作 m(_ _)m

【刪除文章】[]
刪除用密碼:
第一頁[0] 最後一頁