设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 7040|回复: 12
打印 上一主题 下一主题

[RMVX发布] 仿DQ3标题菜单【多态命令代替case @index条件】

[复制链接]

Lv2.观梦者

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

跳转到指定楼层
1
发表于 2010-10-1 16:30:50 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
起因:写这个标题菜单最初是为了仿DQ3的标题,后来发现项目数从2-5变化,case语句在这种情况应用起来捉襟见肘

于是思考该怎么解决,最后决定用
s1 = "继续游戏"
def s1.sym
  :command_continue
end
然后在按下按钮后,send方法名的方式实现

【最近刚开始学习重构,术语叫多态替换条件语句

这样做的好处:以后可以任意修改菜单选项数量,在任意位置添加和删除,不会导致一系列的case语句都要修改

上效果图




最后是范例:
DQ_Title.rar (241.23 KB, 下载次数: 284)

点评

不错啊!  发表于 2013-10-8 15:55

评分

参与人数 1+2 收起 理由
小幽的马甲 + 2

查看全部评分

Lv1.梦旅人

梦石
0
星屑
50
在线时间
518 小时
注册时间
2010-6-16
帖子
1073
13
发表于 2010-10-5 15:05:36 | 只看该作者
发现问题!如果制作了新的冒险书,进去后打开菜单按返回标题画面,Scene_Title 就会变回默认!

点评

嘛,这个不算问题。愚者发布的只是标题菜单罢了,系统整合不在考虑之列【毕竟不是完整的游戏对么】  发表于 2010-10-5 16:23
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1342
在线时间
675 小时
注册时间
2009-11-11
帖子
2790
12
发表于 2010-10-3 17:37:00 | 只看该作者
- -收藏研究先
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
11
发表于 2010-10-3 00:54:36 | 只看该作者
本帖最后由 紫苏 于 2010-10-3 09:23 编辑

这个的确是设计模式的的问题。以前 6R 就有高手提出过,根据 UI 设计原理,我们应该把这些命令当做按钮控件,触发按钮时调用与控件相关联的回调函数,和六祈这里使用的思想不谋而合,只不过该高手用的是 Proc。

关于绑定,Method 对象在创建时会创建对象分配内存并绑定到其拥有者对象,send 的话少了这些过程,因为它触发的是本身就存在于对象虚表中的成员。
一个简单的测试:
  1. def foo
  2. end

  3. CASES = 1000000

  4. t = Time.now
  5. CASES.times {
  6.   send :foo
  7. }
  8. p Time.now - t

  9. t = Time.now
  10. CASES.times {
  11.   method(:foo).call
  12. }
  13. p Time.now - t
复制代码
刚才翻 Programming Ruby 1.9 才发现一个新东西,而这个东西也存在于 Ruby 1.8 中,但在老版的 Programming Ruby 里根本没提到:
Ruby supports two forms of objectified methods. Class Method is used to represent methods that are associated with a particular object: these method objects are bound to that object. Bound method objects for an object can be created using Object#method. Ruby also supports unbound methods, which are method objects that are not associated with a particular object. These can be created either by calling unbind on a bound method object or by calling Module#instance_method. Unbound methods can be called only after they are bound to an object. That object must be a kind_of? the method’s original class.

所以有时也可以使用 UnboundMethod 来最大化灵活性(可以随随意绑定到任何对象),同时也保证了不因为绑定而降低性能。

Ruby中不会发生,也不存在function.fun这种调用方式,只有对象才可以接收消息,而def的方法显然还不是一个对象

这个其实要做到也可以的,只不过会让读者觉得很困惑。Ruby 的一切动态绑定都和上下文有关,只要接受者的上下文能够响应请求的符号,就能调用到预期的方法:
  1. def foo
  2. public
  3.   def bar
  4.     p self
  5.   end
  6. end

  7. foo.bar
复制代码
为什么这里可以这样用?因为 foo 是在顶层定义的,所以 foo 内是 Object(XP 中是 NilClass,VX 和标准 Ruby 解释器下都是 Object)的实例上下文,在实例上下文里定义的 bar 方法自然也绑定到了这里,也就成了 Object 的实例方法。于是首先调用 foo 后,返回一个 nil(因为 foo 没有返回值),nil 是 Object 类型,所以这里就成功地响应了 Object#bar。之所以有那个 public,是因为用户在顶层中定义的方法加入到 Object 中后,其访问权限被设为了公有(public),然而在纯 Ruby 中,加入到 Object 后其访问权限应该是私有的(private)。具体可以参考:http://szsu.wordpress.com/2009/11/07/top_level_object_kernel/

换一个例子来看:
  1. class Klass
  2.   def foo
  3.     def bar
  4.       p self
  5.     end
  6.   end
  7. end

  8. Klass.new.foo.bar # error
复制代码
就不行了。因为 Klass.new.foo 返回的还是 nil,而 nil 却不是 Klass 类型,所以无法响应 Klass 的实例方法 bar。其它类型的上下文也是一个道理。如果让 bar 返回 self 就行了:
  1. class Klass
  2.   def foo
  3.     def bar
  4.       p self
  5.     end
  6.     self
  7.   end
  8. end

  9. Klass.new.foo.bar # OK
复制代码

评分

参与人数 1星屑 +176 收起 理由
DeathKing + 176 长见识了

查看全部评分

回复 支持 反对

使用道具 举报

Lv3.寻梦者 (暗夜天使)

名侦探小柯

梦石
0
星屑
3299
在线时间
3619 小时
注册时间
2006-9-6
帖子
37400

开拓者贵宾第3届短篇游戏大赛主流游戏组亚军第5届短篇游戏比赛亚军

10
发表于 2010-10-1 18:26:08 | 只看该作者
有点不大能理解具体功用……

点评

+1= =  发表于 2010-10-1 18:29
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
50
在线时间
33 小时
注册时间
2010-9-18
帖子
173
9
发表于 2010-10-1 17:59:53 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv1.梦旅人

前进之卒

梦石
0
星屑
55
在线时间
20 小时
注册时间
2010-8-17
帖子
176
8
发表于 2010-10-1 17:59:13 | 只看该作者
呃,不知道发在这里问合不合适。看到神尊的问题,也有一个问题想请问下67大人,类的定义说是可以嵌套定义,那么对嵌套里面类的方法该如何调用?如下,该如何调用function_1?
  1. class Test
  2.    def  function
  3.      p "function"
  4.    end
  5.   class Test_1
  6.     def  function_1
  7.       p 1
  8.     end
  9.   end
  10. end
复制代码

点评

谢谢。^_^  发表于 2010-10-1 18:22
a = Test::Test_1.new;a.function_1  发表于 2010-10-1 18:13
开始拼吧!
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
46
在线时间
10 小时
注册时间
2007-5-27
帖子
2558

第1届Title华丽大赛新人奖

7
发表于 2010-10-1 17:50:57 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv2.观梦者

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

6
 楼主| 发表于 2010-10-1 17:04:41 | 只看该作者
回复 九夜神尊 的帖子


    你的这种写法有点像javascript,在【函数约等于对象约等于类】的语言中可以存在

Ruby中不会发生,也不存在function.fun这种调用方式,只有对象才可以接收消息,而def的方法显然还不是一个对象

点评

灰常感谢。  发表于 2010-10-1 17:11
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1323
在线时间
831 小时
注册时间
2007-12-25
帖子
1558
5
发表于 2010-10-1 17:00:02 | 只看该作者
回复 六祈 的帖子

突然想到一点东西我就懒得自己动手了,直接问67大人好了

def 里面再def 叫什么呢

那么调用的时候会不会就是用xxx.xxx来调用呢

更定义xxx.xxx一个道理呢?

然而如果

def funtion

n = rand(2)
if n == 0
  def  fun
    p 1
end
else
  def  fun
    p 2
end
end


end


funtion.fun

会死机么?

点评

你说的  发表于 2010-10-1 17:04
def内的东西会在方法被调用时运行,所以def里的def在执行前没有def,执行之后就def了  发表于 2010-10-1 17:01
精卫赤龙腾   
总是存在一种强大,去完成似乎不可能的事情.
无畏战乾程   
或是需要一种勇气,去挑战几乎不存在的胜利.
一味玄真魂     
这是拥有一种恒心,去化解根本没有解的困难.
烈卫开天径    
只是带着一种决心,去争取残存的最后的希望。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-15 01:19

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表