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

Project1

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

[推荐问答] 公共事件的一个疑问

[复制链接]

Lv4.逐梦者

梦石
0
星屑
13101
在线时间
3787 小时
注册时间
2013-7-18
帖子
2279
跳转到指定楼层
1
发表于 2019-11-28 09:55:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
公共事件并行处理为什么不卡,而地图并行有时候事件多了就会崩溃,这样来看,似乎可以用公共事件制作套装效果,也不至于卡。

评分

参与人数 1星屑 +20 收起 理由
RyanBern + 20 推荐问答

查看全部评分

山岚野人,快人快语,礼数不周,还望海涵....

Lv3.寻梦者

梦石
0
星屑
1027
在线时间
72 小时
注册时间
2019-11-25
帖子
12
来自 4楼
发表于 2019-12-3 15:58:40 | 只看该作者
guoxiaomi 发表于 2019-12-3 02:01
地图上的事件远比普通的公共事件要复杂,带来的计算量也是非常高的。
比如:
1. Game_Character 1中150行的 ...


(写给楼主)
针对上述1、3点有个行之有效的方法(前提你听得懂)
在Game_Map里维护一个至少定义了读方法的二维数组或一个Hash,以下简称坐标容器吧
在Event定义时将event对象加入到坐标容器中它的坐标的下标/键的位置
覆盖Game_Event的所有能使坐标变化的方法(为了保证坐标变化反映的实时性)(这些方法得从父类Game_Character找起,VA封装得不错,很多方法最终汇集到寥寥几个方法中改变坐标如move_straight,XP明显就分散多了,改坐标的方法一大堆……)
在变化前以坐标为索引删除Game_Map中坐标容器中的self引用,在变化后以新坐标插入self引用(如果你知道super的话一定懂怎么实现),无论坐标是否真的改变都这样做
最后将所有判断事件位置的地方都改为使用这个坐标容器参考

下面是我在VA上用的例子:
  1. class Game_Map
  2.   def setup_events
  3.     @events = {}
  4.     ...
  5.     @event_point = {}
  6.     @map.events.each do |id, event|
  7.         ...
  8.         @events[id] = Game_Event.new(@map_id, event)
  9.       end
  10.       if @events[id]
  11.         @event_point[[@events[id].x, @events[id].y]] ||= []
  12.         @event_point[[@events[id].x, @events[id].y]] << @events[id]
  13.       end
  14.     end
  15.     ...
  16.   end
复制代码
  1. class Game_Event < Game_Character
  2.   ...
  3.   def moveto(x, y)
  4.     location_remove
  5.     super
  6.     location_insert
  7.   end
  8.   def move_straight(d, turn_ok = true)
  9.     location_remove
  10.     super
  11.     location_insert
  12.   end
  13.   def move_diagonal(horz, vert)
  14.     location_remove
  15.     super
  16.     location_insert
  17.   end
  18.   def jump(x_plus, y_plus)
  19.     location_remove
  20.     super
  21.     location_insert
  22.   end
  23.   def location_remove
  24.     return if !$game_map.event_point[[@x, @y]]
  25.     $game_map.event_point[[@x, @y]].delete(self)
  26.   end
  27.   def location_insert
  28.     $game_map.event_point[[@x, @y]] ||= []
  29.     $game_map.event_point[[@x, @y]].push(self)
  30.   end
  31. end
复制代码
  1. class Game_Map
  2.   def events_xy(x, y)
  3.     @event_point[[x, y]] ||= []
  4.   end
  5.   def events_xy_any?(x, y, except = nil)
  6.     events_xy(x, y).any? {|event| event != except }
  7.   end
  8.   def events_xy_nt(x, y)
  9.     events_xy(x, y).select {|event| !event.through }
  10.   end
  11.   ............
  12. end
复制代码

可以简化坐标判定的计算,实测在VA上200事件的50*50地图都不会掉帧,当然这个可能有着RGD的加成
至于XP上那些坐标判断或坐标修改的方法具体在哪,一般多出现于Game_Map Game_Character Game_Event Game_Player(甚至Interpreter?),运用好全局搜索(就是在左边的脚本库栏目里右键搜索),关键字一般是@x =,@y =,for event in events.values之类的,更多的看你的理解吧。

点评

不懂,脚本是外行  发表于 2019-12-8 10:28

评分

参与人数 1星屑 +150 +1 收起 理由
RyanBern + 150 + 1 赞认真回答,可lz脚本外行

查看全部评分

回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13559
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

来自 5楼
发表于 2019-12-3 22:48:24 | 只看该作者
本帖最后由 SixRC 于 2019-12-3 22:50 编辑
guoxiaomi 发表于 2019-12-3 02:01
地图上的事件远比普通的公共事件要复杂,带来的计算量也是非常高的。
比如:
1. Game_Character 1中150行的 ...


我想的和四楼几乎一样
然后被抢先啦
那我就写一个
开始测试的时候和原版效率几乎一样 后来发现是我创建事件的时候选了可穿透...
event_opt.zip (211.94 KB, 下载次数: 62)

仅用于测试思路效果

默认打开是没有任何优化的
在 测试用 代码页 $EVEOPT = false
决定了是否开启按坐标切分事件
其后四个代码页分别是对
Game_Map    Game_Character   Game_Event   Game_Player  的覆盖修改
涉及到的地方其实并不多
保留了旧的 @events 新加了个 @events_new
因为只有涉及坐标判定的地方需要优化  别的可以照旧
思路 应该还算清晰吧..
在改动的地方我注出来了

很好奇为什么之前没有人写这个...

fps_unlimit 代码页是之前写的 防卡有奇效 用于103J dll

点评

你永远都不知道缺乏编程知识的人会做出什么样的东西出来……  发表于 2019-12-8 21:05
我在想 除非真有几百个事件 不然哪有那么卡..  发表于 2019-12-8 13:01
其实可以标记一些事件不刷新,比如识别事件的名称,以#开头的事件不刷新不计算碰撞和触发  发表于 2019-12-8 03:37
我查了下之前的防卡脚本好像是对一定范围外的事件不做刷新 图书馆的那个就是 思路不如你给的清晰 啊 不过这个东西 除非默认脚本 适应性确实不好..  发表于 2019-12-7 23:27
那可以大概整理一份呀!以后遇到了就能 详见xxxxx(像我其实对原脚本系统不熟 不是你说我也不知道事件=大卡器 更不知道卡在哪儿)  发表于 2019-12-7 23:23

评分

参与人数 1星屑 +150 +1 收起 理由
RyanBern + 150 + 1 醋瞎

查看全部评分

回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
14048
在线时间
2070 小时
注册时间
2016-9-20
帖子
844
2
发表于 2019-11-28 17:55:42 | 只看该作者
公共事件多了一樣会卡, 就算全腳本化一樣会卡, 不过你使用轉換VX,和VX ACE引擎的話可以流暢
内容仅供参考,
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

3
发表于 2019-12-3 02:01:10 | 只看该作者
地图上的事件远比普通的公共事件要复杂,带来的计算量也是非常高的。
比如:
1. Game_Character 1中150行的 passable? 方法内。此处对全部的事件进行了循环处理,判断此事件是否位于Player的正前方。
2. Game_Event的 refresh 方法会便利整个事件的全部事件页,并选出满足触发条件的唯一事件页。
3. Game_Player中120行的check_event_trigger_here方法内,此处同样对全部的事件进行了循环,判断此事件是否在角色脚下。

以上1会在每次事件或主角移动时触发,2和3会在每帧触发,这些都会拖累执行效率。

点评

地图上做了20多个事件,每个事件一个独立开关,第二页独立开关打开的情况下100帧后并行取消独立开关,结果直接崩溃,不是独立开关是单独计算的么  发表于 2019-12-8 10:27
确实不是每帧执行,但是在事件页多的时候很拖累速度,尤其是有一大堆不会执行的事件的时候  发表于 2019-12-7 04:06
2不是每帧执行吧,XP也有@need_refresh控制,一般是只当开关/变量/独立开关改变的时候才执行,不过这个改变执行并没有像VA那样封装到Game_Switches类罢了  发表于 2019-12-3 15:39

评分

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

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-27 01:34

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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