Project1
标题:
求更简便的检索法
[打印本页]
作者:
Wind2010
时间:
2011-6-6 19:56
标题:
求更简便的检索法
本帖最后由 Wind2010 于 2011-6-6 20:04 编辑
def get_xy_array(actor,kind,max,min=[])
get = []
# ...................中间省略几百行脚本
if kind == "圆"
min = [0] if min.size != 1
for x in -max[0]-1..max[0]+1
next if actor.x+x < 0
break if actor.x+x >= $game_map.width
for y in -max[0]..max[0]
next if actor.y+y < 0
break if actor.y+y >= $game_map.height
next if (x**2 + y**2) >= (max[0]+1)**2
next if (x**2 + y**2) < min[0]**2
get.push([actor.x+x,actor.y+y])
end
end
end
return get
end
复制代码
这个是获得一个圆的数组,求一种写法,可以将数组按照与actor的距离的远近来进行排序(不要跟我说得到数组后再排序,这样会慢很多)
作者:
沙漠点灰
时间:
2011-6-7 13:46
本人脑袋笨,没懂lz看懂意思,得到数组后再排序慢...?的确会慢,不过可以无视掉...
以半径100为例,会耗时0.4秒(约3.14w个单位),而我用的是inject,相对于for..in,效率低了那么一点点,
0.4秒完全可以无视...测试代码如下:
#==============================================================================
# ■ Game_Character (分割定义 1)
#------------------------------------------------------------------------------
# 处理角色的类。本类作为 Game_Player 类与 Game_Event
# 类的超级类使用。
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# ● 获取圆坐标(整数)的
#--------------------------------------------------------------------------
def make_circle(ox, oy, r)
raise(RGSSError,"无用半径") if r < 1
h=(-r..r).inject({}){|a,x|(-r..r).each{|y|key=(self.x-x-ox)**2+(self.y-y-oy)**2;a[key]||=[];a[key]<<[x+ox,y+oy] if x**2+y**2<r**2};a}
h.keys.sort.inject([]){|a,i|a+h[i]}
end
end
复制代码
ox, oy为圆初始x,y坐标,r为半径...
$game_player.make_circle(0,0,100)=>........此处略去几万行脚本..
没有对超过地图范围删除,lz可自行修改...
作者:
enghao_lim
时间:
2011-6-9 01:10
用圆形方程式:
(x-a)^2 + (x-b)^2 = r^2
a,b 是圆形中心点。
用这个方程式比对半经,一边侦测一边排序即可。
纯理论,没测试,不过应该会快一点,以前写slg时是使用这个方法计算的,估计差不多。
作者:
沙漠点灰
时间:
2011-6-10 17:31
1帧处理10多次...?先汗一下...就算这个脚本耗时0.01秒,1帧处理10多次,FPS可以掉到1位数(理论)....,
比起什么什么函数来说,查表是最快的(貌似查表也算函数,f(x)嘛!返回一个值),
我之所以把所有坐标列出来,就是为了查表,所以,这个脚本只运行1次就好了,
重要的
相对坐标
,因为不知道lz到底干什么,
我现在假设lz是排列100个事件
...脚本如下:
#==============================================================================
# ■ Game_Map
#------------------------------------------------------------------------------
# 处理地图的类。包含卷动以及可以通行的判断功能。
# 本类的实例请参考 $game_map 。
#==============================================================================
class Game_Map
attr_reader :hash
alias _setup setup #可以不写什么unless,因为 ||=
def setup(map_id)
_setup(map_id)
@hash ||= make_hash
end
#--------------------------------------------------------------------------
# ● 远近坐标...
#--------------------------------------------------------------------------
def make_hash(w=self.width, h=self.height)
t = 0
z=(-w..w).inject({}){|a,x|(-h..h).each{|y|k=x*x+y*y;a[k]||=[];a[k]<<[x,y]};a}
@hash = z.keys.sort.inject({}){|a,i|z[i].each{|j|a[j]=t;t+=1};a}
end
#--------------------------------------------------------------------------
# ● 事件排序
#--------------------------------------------------------------------------
def sort_events(e_id, x=$game_player)
(e_id.inject([]){|a,i|a[@hash[[x.x-@events[i].x,x.y-@events[i].y]]]=i;a}).compact
end
end
复制代码
本人测试80*80地图,因为相对坐标原因会计算80*80*4个坐标出来,每次换地图计算一次,建议加入Loading画面,因为超过
100000个地图单位(314*315左右)会计算超过10秒(可能,没测试),
测试代码如下:
p $game_map.sort_events(1..100)
复制代码
不过严格来说应该是
p $game_map.sort_events((1..100).to_a, $game_player)
复制代码
是数组,而非范围,表示事件编号,100个事件耗时0.0秒(没法计算..太短了..)
所以,lz尝试用Hash查表吧!
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1