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/cn.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灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP