GameDesign 板


LINE

※ 引述《etrexetrex (moonet)》之銘言: : 我把這些對應到物件導向程式 : 1.選人 = 選物件 : 2.選行為 = 選方法 : 3.選對象 = 選參數 : 4.行動 = call 物件.方法(參數) [...] : 我希望做出來的系統是容易對人物,行為,對象或目標作異動的系統 : 所以我以為系統應該寫成一般式,步驟不一定只有4步 不是很清楚你想作成什麼樣子,根據不同的遊戲系統, 我想寫出來的東西可以大相逕庭。你可以從你希望怎麼操作你的東西開始思索, 像是我會希望能夠這樣做(in Ruby): > unit_pool = {} # a hash map > godfat = Unit.new "godfat" > godfat.hp = godfat.mp = 10 > # active ability > godfat.obtain_ability Heal.new(:level => 10, :cooldown => 29) > # passive ability > godfat.obtain_ability Flying.new(:height => 2) 像這樣就可以任意指定某個單位有哪些能力,事後也能修改單位的屬性和能力。 存起來以便事後 clone 出來: > unit_pool["godfat"] = godfat 治療自己: > action = godfat.abilities["heal"].targets(godfat) > action.apply 反治療: > action.unapply 這裡有一個重點,就是 unapply 不可能自己生出來, 必須針對每一個 ability 都寫一次。除非不用這種 undo 法, 而是把整個狀態記錄下來,然後重新寫回去,像是: > before_heal = godfat.dump_state > action.apply 反治療: > godfat.restore_state before_heal 不過我是不太建議這種作法,因為這樣你就必須知道被影響的單位有哪些, 像是在這裡只有影響到 godfat, 所以只要這樣做就好了。 要全面回復,可能就會有: > targets_to_restore = action.target_list > before_heals = targets_to_restore.map{ |t| t.dump_state } > action.apply 反治療: > targets_to_restore.zip( before_heals ).each{ |t, s| t.restore s } 唔,zip 和 map 的用法我就先不說了,總之這樣會有很多要處理的。 或是乾脆全場記下來,可能還簡單些: > last_step = game.dump_state > action.apply 反治療: > game.restore_state last_step 不過我不知道你是不是要做這麼複雜的 undo, 還是只是單純取消之前下達的命令,例如換人之類的,而不是說「悔棋」 如果只是要取消之前下達的命令,那根本不用 undo, 只要不要執行就好了... 等到「回合結算」的時候才真的去執行,那就很單純。 其他程式碼:(我隨手寫的,所以其實很粗糙) class Unit attr_reader :name, :abilities attr_accessor :cooldown, :hp, :mp def initialize name @name = name @abilities = {} @cooldown = @hp = @mp = 0 end def obtain_ability ability ability.owner = self @abilities[ability.name] = ability end end class Ability attr_accessor :owner attr_reader :name, :target_list def targets *list # 這表示引數可以無限多 @target_list = list self end def apply end def unapply end protected def initialize name @name = name end end class Heal < Ability def initialize opts super "heal" @opts = opts end def apply self.owner.mp -= (opts[:level] * 1.5).round self.target_list.each{ |t| t.hp += opts[:level] * 2 } self.owner.cooldown += opts[:cooldown] end def unapply self.owner.cooldown -= opts[:cooldown] self.target_list.each{ |t| t.hp -= opts[:level] * 2 } self.owner.mp += (opts[:level] * 1.5).round end private attr_reader :opts end class Flying < Ability # 略... end 上面那個 unapply, 其實可以寫得更抽象化一點,像是: > apply_steps << subtract 'self.owner.mp', '(opts[:level] * 1.5).round' > << lambda{ self.target_list.each{ |t| ....略 } } > << addition 'self.owner.cooldown', 'opts[:cooldown]' 然後 apply / unapply 就能這樣寫: > def apply > apply_steps.each &:apply > end > def unapply > apply_steps.reverse_each &:unapply > end 然後 subtract 的 unapply 當然就是 addition, addition 的 unapply 當然就是 subtract. 中間的 lambda 會複雜許多,所以我就不寫了... 當然這樣是有點走火入魔啦,只是要大量使用 undo 的話就得做徹底一點。 補充: 這邊每 apply 一次,就會洗掉上一個 target_list, 所以如果需要直接放入 stack 做 undo list 的話, Ability#targets 可能要這樣寫: class Ability def targets *list @target_list = list self.clone end end 這樣就可以直接放到 stack 去不怕影響到別人了 (當然,那個 clone 在 Heal/Flying 那些 class 裡要定義) -- #!/usr/bin/env ruby [露比] /Programming (Kn|N)ight/ 看板《Ruby》 # if a dog nailed extra legs that http://webptt.com/m.aspx?n=bbs/Ruby/index.html # walks like an octopus, and Welcome ~Ruby@ptt~ # talks like an octopus, then ◢█◣ http://www.ruby-lang.org/ # we are happy to treat it as http://www.ruby-doc.org/ # if it were an octopus. http://www.rubyforge.org/ --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.28.18 ※ 編輯: godfat 來自: 220.135.28.18 (04/09 17:21)
1F:推 etrexetrex:我想我說的undo在這篇文章是指你說的很簡單的部分 04/09 19:34
2F:→ etrexetrex:"取消之前下達的命令"這個部分而已 04/09 19:35
3F:→ etrexetrex:只是我在想一個命令要怎麼存才好分段undo 04/09 19:35
4F:推 sunneo:你只要實作一個循環式的stack就好了... 04/09 21:58
5F:→ sunneo:循環式的stack有出現在作業系統的分頁演算法計算 04/09 21:58
6F:→ sunneo:或者是一種queue跟stack合併的一種具有最大指令數目的stack 04/09 21:59







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP