查看: 4354|回复: 12

[胡扯] 简单的监听机制

[复制链接]
梦石
0
星屑
3703
在线时间
3081 小时
注册时间
2011-11-17
回帖
943
发表于 2014-7-22 23:35:37 | 显示全部楼层 |阅读模式

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

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

×
为了帮小伙伴做一套炫酷的ui 所以有了这东西 [pre lang="ruby" line="1"]class NotifyCenter
  def initialize
    @obsarray = [[],[]]
    @procarray = [[],[]]
    @desarr = [[],[]]
  end
  def addObserver(obs,proc,des)#增加监听
      @obsarray[obs.kind].push(obs)
      if obs.kind == 1#这里预留按钮机制 触摸优先级 可以无视
        @obsarray[obs.kind].sort! {|a,b|b.z - a.z}
        index = @obsarray[obs.kind].index(obs)
        @procarray[obs.kind].insert( index, proc)
        @desarr[obs.kind].insert( index, des)
      else
        @procarray[obs.kind].push(proc)
        @desarr[obs.kind].push(des)
      end
      
  end
  def removeObserver(obs)#移除监听
    loop do
      index = @obsarray[obs.kind].index(obs)
      break if index == nil
      @obsarray[obs.kind].delete_at(index)
      @procarray[obs.kind].delete_at(index)
      @desarr[obs.kind].delete_at(index)
    end
    #一个对象可能同时被观察多个请求 所以用了循环
  end
  
  def postmsg(kind,des)#发送通知 对所有被监听的小伙伴 回调
    for i in 0..@desarr[kind].size
      if @desarr[kind] == des
        @procarray[kind].call
      end
    end
  end

end
###################testclass##############
class Obstest
  attr_reader   :kind
  attr_reader   :testnum
  def initialize(testnum)
    @kind = 0
    @testnum = testnum
    $notifycenter.addObserver(self,Proc.new { self.test },"aaa")
    $notifycenter.addObserver(self,Proc.new { self.test2 },"bbb")
  end
  
  def test
    p "test"
  end
  def test2
    p @testnum.to_s
  end
end

class Obstest2
  attr_reader   :kind
  def initialize
    @kind = 0
    $notifycenter.addObserver(self,Proc.new { self.test },"ccc")
  end
  
  def test
    p "testccc"
  end

end


[/pre]

测试代码偷懒写在main里了
[pre lang="ruby" line="1"]#==============================================================================
# ■ Main
#------------------------------------------------------------------------------
#  各定义结束后、从这里开始实际处理。
#==============================================================================

begin
  # 准备过渡
  # 设置系统默认字体
  Font.default_name = (["黑体"])
  Graphics.freeze
  # 生成场景对像 (标题画面)
  $scene = Scene_Title.new
  
  ################################
  $notifycenter = NotifyCenter.new
  a = Obstest.new(0)
  $notifycenter.postmsg(0,"aaa")
  $notifycenter.postmsg(0,"ccc")
  p "step 1"
  #通知aaa 和 ccc需求  a对象绑定了 aaa 和 bbb需求 所以 aaa对应的函数会被执行 显示test
  #但并没有对象绑定ccc 所以 ccc这条消息发出去也是没意义的
  b = Obstest.new(1)
  $notifycenter.postmsg(0,"aaa")
  $notifycenter.postmsg(0,"bbb")
  p "step 2"
  #通知aaa 和 bbb需求 因为 增加了b对象 所以通知aaa需求的时候 会同时通知 a 和 b对象
  #先打印2个 test  再通知bbb需求 打印 0 和1
  $notifycenter.removeObserver(a)#将a对象移除监听
  $notifycenter.postmsg(0,"aaa")
  $notifycenter.postmsg(0,"bbb")
  p "step 3"
  #因为a对象被移除了 所以 通知 aaa 和 bbb时 只剩下 b对象了 打印 test 和 1
  c = Obstest2.new
  $notifycenter.postmsg(0,"ccc")
   p "over"
  #有了c对象 所以也就有了ccc的绑定 这时再通知 会显示testccc了
###############################



  # $scene 为有效的情况下调用 main 过程
  while $scene != nil
    $scene.main
  end
  # 淡入淡出
  Graphics.transition(20)
rescue Errno::ENOENT
  # 补充 Errno::ENOENT 以外错误
  # 无法打开文件的情况下、显示信息后结束
  filename = $!.message.sub("No such file or directory - ", "")
  print("找不到文件 #{filename}。 ")
end
[/pre]

老黄鸡

梦石
4
星屑
45765
在线时间
7953 小时
注册时间
2009-7-6
回帖
13338

MZ评测员RM创作大赛01组委会开拓者贵宾

发表于 2014-7-22 23:50:47 | 显示全部楼层
(ノ゚∀゚)ノ触手总是深夜出现

点评

为了哲♂学  发表于 2014-7-23 00:03
RGDirect - DirectX驱动的RGSS,点我了解.
(排满,暂停)RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复

使用道具 举报

名侦探小柯

梦石
10
星屑
4410
在线时间
3740 小时
注册时间
2006-9-6
回帖
36596

极短27获奖MZ评测员开拓者贵宾第3届短篇游戏大赛主流游戏组亚军第5届短篇游戏比赛亚军

发表于 2014-7-22 23:55:01 | 显示全部楼层
虽然完全不明白是什么但是看到LZ的头像总是令我浮想联翩

点评

看来你有哲♂学的心  发表于 2014-7-23 00:03
不定期回归 ~ 游戏开发之旅
———————————————————————————————
回复

使用道具 举报


  • 更新完成啦
  • 梦石
    0
    星屑
    894
    在线时间
    6267 小时
    注册时间
    2006-6-7
    回帖
    8173
发表于 2014-7-22 23:55:28 | 显示全部楼层
妈蛋完全看不懂啊

点评

不用在意这些细节  发表于 2014-7-23 00:04
回复

使用道具 举报

梦石
0
星屑
3703
在线时间
3081 小时
注册时间
2011-11-17
回帖
943
 楼主| 发表于 2014-7-23 00:02:18 | 显示全部楼层
至于为毛要这东西 举个简单的例子 假如角色升级了  我有n个界面 要对lv进行刷新 但我又不确定 n个界面里 到底有几个是现在存在的  这时 可能会写出这样的 代码[pre lang="ruby" line="1"]if 升级
界面1.refresh if 界面1 !=nil
界面2.refresh if 界面2 !=nil
...
end
[/pre]

如果在界面生成的时候绑定监听 我在升级的时候根本不用在意 到底要刷新哪些 仅仅发一条消息就可以了
回复

使用道具 举报

  /) /)<

梦石
0
星屑
4262
在线时间
4894 小时
注册时间
2009-2-16
回帖
8198

超评测评委开拓者短篇七成年组季军

发表于 2014-7-23 00:03:27 | 显示全部楼层
给大神跪了

点评

↓ 基柯遮住你的眼睛!这楼什么都没有!  发表于 2014-7-23 00:14
你怎么不搞素材改主攻脚本了orz  发表于 2014-7-23 00:11
可乐……你竟然还有这种地下恋情(不  发表于 2014-7-23 00:11
你开始玩视频了啊 这么娘咋跟叔混的 说好的猥琐呢。。。  发表于 2014-7-23 00:07
回复

使用道具 举报

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2014-7-23 06:22:58 | 显示全部楼层
本帖最后由 taroxd 于 2014-7-23 06:28 编辑
yagami 发表于 2014-7-23 00:02
至于为毛要这东西 举个简单的例子 假如角色升级了  我有n个界面 要对lv进行刷新 但我又不确定 n个界面里 到 ...


我可能会写出这样的代码[pre lang="ruby" line="1"]instance_variables.each do |ivar_name|
  ivar = instance_variable_get ivar_name
  ivar.refresh if ivar.respond_to? :refresh
end[/pre]

另外,不要用 nil 来表示界面不存在。
你可以使用 hide,xxx.visible = false 这些方法。
这样的话直接每个都刷新一遍就没有问题了,不需要判断是否为 nil。
因此我也会写出这样的代码
[pre lang="ruby" line="1"]
界面1.refresh
界面2.refresh
#...

[/pre]
回复

使用道具 举报

梦石
0
星屑
122
在线时间
552 小时
注册时间
2012-8-18
回帖
1392
发表于 2014-7-23 09:19:56 | 显示全部楼层
给大触跪了|д゚ )
我要填坑!我要背单词!我要学日语!我要每天锻炼!
好吧呵呵= =
回复

使用道具 举报

孤独守望

梦石
0
星屑
3144
在线时间
1535 小时
注册时间
2006-10-16
回帖
4223

开拓者贵宾

发表于 2014-7-23 09:30:14 | 显示全部楼层
proc 放后面去,写成 &block。
亲以前是写Java的吧。

评分

参与人数 1星屑 +50 收起 理由
taroxd + 50 我很赞同

查看全部评分

菩提本非树,明镜本非台。回头自望路漫漫。不求姻缘,但求再见。
本来无一物,何处惹尘埃。风打浪吹雨不来。荒庭遍野,扶摇难接。
不知道多久更新一次的博客
回复

使用道具 举报

梦石
0
星屑
50
在线时间
60 小时
注册时间
2014-7-12
回帖
526
发表于 2014-7-23 10:10:27 | 显示全部楼层
我居然真的以为这个是用来监听的脚本(ノ゚∀゚)ノ

传送门:https://rpg.blue/thread-368721-1-1.html
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部