赞 | 342 |
VIP | 10 |
好人卡 | 8 |
积分 | 262 |
经验 | 235776 |
最后登录 | 2024-9-23 |
在线时间 | 2387 小时 |
Lv5.捕梦者 (版主) 遠航の猫咪
- 梦石
- 3
- 星屑
- 23191
- 在线时间
- 2387 小时
- 注册时间
- 2005-10-15
- 帖子
- 1166
|
本帖最后由 SailCat 于 2021-3-11 02:20 编辑
RMXP的bitmap处理效率不比RMVA差的,这个我很明确的测试过并得出结论
RMXP每帧纯做set_pixel能做8000次,你觉得你的血条里会有8000个像素点吗?就算有,能有16000个像素点吗?血不会每帧更新,刷血条时损失1帧又不是什么大不了的事。要知道不论RMXP还是RMVA,draw_text都是个奇慢的操作,你还经常一帧做几十次呢。
所以觉得RGSS直接做不了的,都是算法问题
有简易实现和完美实现两个办法
简易实现:特点是速度快,缺点是血条的水面是平的,不是正对圆心角的斜线。
首先制作2个空血条bitmap,作为底图传送成精灵,ox, oy设在圆心(也就是两个bitmap的左中点和右中点)(假设环直径100,底图都是50X100大小,例为血(50,50)和蓝(0,50)))
把它们的x, y设置在一起,显示出来就拼起来了
然后制作2个满血条bitmap,作为面图(z更高)传送成精灵,ox, oy,x,y也一起和前面的重合
然后根据你的血量蓝量百分比,改变两面图精灵的src_rect为高度的百分比,从底端算起,比如22%血,就传送(0,78,50,22)为血,40%蓝,就传送(0,60,50,40)为蓝
完毕了。
完美实现,底图一样,可简单用精灵做
面图的bitmap需要自己绘制:
血条直径100的话,需要执行至多100次bitmap#fill_rect(由于水平做比垂直做快,建议水平做)
以下改的是Window_Menustatus
总之不算难,效率也不差,水平做fill_rect一帧极限我记得是720次。垂直120次
这里有些复杂的三角函数运算,实际没那么多,反正在菜单中帧数大概36-37左右(我能说是被draw_text拖的么)
#-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh self.contents.clear @item_max = $game_party.actors.size for i in 0...$game_party.actors.size x = 64 y = i * 116 actor = $game_party.actors[i] draw_actor_graphic(actor, x - 40, y + 80) draw_actor_name(actor, x, y) draw_actor_class(actor, x + 144, y) draw_actor_level(actor, x, y + 32) draw_actor_state(actor, x + 90, y + 32) draw_actor_exp(actor, x, y + 64) draw_actor_hp(actor, x + 236, y + 32) draw_actor_sp(actor, x + 236, y + 64) outer = 50 # 外径 inner = 40 # 内径 ox = 300 # 血条ox oy = i * 116 + 50 # 血条oy hp_rate = actor.hp * 100.0 / actor.maxhp # HP 比例 sp_rate = actor.sp * 100.0 / actor.maxsp # SP 比例 hx_rate = hp_rate == 50 ? 0.0 : Math.tan((0.5 + hp_rate * 0.01) * Math::PI) sx_rate = sp_rate == 50 ? 0.0 : Math.tan((0.5 - sp_rate * 0.01) * Math::PI) hp_color = Color.new(232,90,90,255) sp_color = Color.new(90,90,232,255) outer.downto(-outer) do |by| fy = by.to_f x_in = (fy.abs >= inner ? 0 : inner * Math.sqrt([1 - (fy / inner) ** 2, 0].max)+0.5).to_i x_out = (outer * Math.sqrt([1 - (fy / outer) ** 2, 0].max)+0.5).to_i if by == 0 if hp_rate >= 50 contents.fill_rect(ox - x_out, oy, x_out - x_in, 1, hp_color) end if sp_rate >= 50 contents.fill_rect(ox + x_in, oy, x_out - x_in, 1, sp_color) end next end hx = hx_rate == 0.0 ? -999 * by : (fy / hx_rate).to_i sx = sx_rate == 0.0 ? 999 * by : (fy / sx_rate).to_i if hx.between?(-x_out, -x_in) if hp_rate >= 50 contents.fill_rect(ox - x_out, oy + by, hx + x_out, 1, hp_color) else contents.fill_rect(ox + hx, oy + by, -x_in - hx, 1, hp_color) end elsif (hx > -x_in) ^ (hp_rate <= 50) contents.fill_rect(ox - x_out, oy + by, x_out - x_in, 1, hp_color) end if sx.between?(x_in, x_out) if sp_rate >= 50 contents.fill_rect(ox + sx, oy + by, x_out - sx, 1, sp_color) else contents.fill_rect(ox + x_in, oy + by, sx - x_in, 1, sp_color) end elsif (sx < x_in) ^ (sp_rate <= 50) contents.fill_rect(ox + x_in, oy + by, x_out - x_in, 1, sp_color) end end end end
#--------------------------------------------------------------------------
# ● 刷新
#--------------------------------------------------------------------------
def refresh
self.contents.clear
@item_max = $game_party.actors.size
for i in 0...$game_party.actors.size
x = 64
y = i * 116
actor = $game_party.actors[i]
draw_actor_graphic(actor, x - 40, y + 80)
draw_actor_name(actor, x, y)
draw_actor_class(actor, x + 144, y)
draw_actor_level(actor, x, y + 32)
draw_actor_state(actor, x + 90, y + 32)
draw_actor_exp(actor, x, y + 64)
draw_actor_hp(actor, x + 236, y + 32)
draw_actor_sp(actor, x + 236, y + 64)
outer = 50 # 外径
inner = 40 # 内径
ox = 300 # 血条ox
oy = i * 116 + 50 # 血条oy
hp_rate = actor.hp * 100.0 / actor.maxhp # HP 比例
sp_rate = actor.sp * 100.0 / actor.maxsp # SP 比例
hx_rate = hp_rate == 50 ? 0.0 :
Math.tan((0.5 + hp_rate * 0.01) * Math::PI)
sx_rate = sp_rate == 50 ? 0.0 :
Math.tan((0.5 - sp_rate * 0.01) * Math::PI)
hp_color = Color.new(232,90,90,255)
sp_color = Color.new(90,90,232,255)
outer.downto(-outer) do |by|
fy = by.to_f
x_in = (fy.abs >= inner ? 0 : inner * Math.sqrt([1 - (fy / inner) ** 2,
0].max)+0.5).to_i
x_out = (outer * Math.sqrt([1 - (fy / outer) ** 2, 0].max)+0.5).to_i
if by == 0
if hp_rate >= 50
contents.fill_rect(ox - x_out, oy, x_out - x_in, 1, hp_color)
end
if sp_rate >= 50
contents.fill_rect(ox + x_in, oy, x_out - x_in, 1, sp_color)
end
next
end
hx = hx_rate == 0.0 ? -999 * by : (fy / hx_rate).to_i
sx = sx_rate == 0.0 ? 999 * by : (fy / sx_rate).to_i
if hx.between?(-x_out, -x_in)
if hp_rate >= 50
contents.fill_rect(ox - x_out, oy + by, hx + x_out, 1, hp_color)
else
contents.fill_rect(ox + hx, oy + by, -x_in - hx, 1, hp_color)
end
elsif (hx > -x_in) ^ (hp_rate <= 50)
contents.fill_rect(ox - x_out, oy + by, x_out - x_in, 1, hp_color)
end
if sx.between?(x_in, x_out)
if sp_rate >= 50
contents.fill_rect(ox + sx, oy + by, x_out - sx, 1, sp_color)
else
contents.fill_rect(ox + x_in, oy + by, sx - x_in, 1, sp_color)
end
elsif (sx < x_in) ^ (sp_rate <= 50)
contents.fill_rect(ox + x_in, oy + by, x_out - x_in, 1, sp_color)
end
end
end
end
多说两句,如果真嫌慢(实际上是伪命题,卡的话查其他地方),做0% 50% 100%三个基础环图,然后根据hp的比例在上面加加减减的fill_rect打补丁,因为补丁最多需要工作1/4的区间(平均期望1/8),故此能再快1/2左右,而且我现在这个算法是HP越满绘制量越高,正常玩家没有谁会放着黄血一直长时间不管的吧……但是实话说其实没啥继续优化的必要 |
评分
-
查看全部评分
|