赞 | 6 |
VIP | 0 |
好人卡 | 0 |
积分 | 10 |
经验 | 0 |
最后登录 | 2024-7-15 |
在线时间 | 90 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1021
- 在线时间
- 90 小时
- 注册时间
- 2022-12-26
- 帖子
- 102
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 爱羊真知己 于 2023-1-24 19:46 编辑
我在使用Kahs的灯光脚本后,直接使用脚本DataManager.setup_new_game会崩溃。请问怎么避免这个情况呢?
脚本如下:=begin #------------------------------------------------------------------------------- # * [ACE] Khas Awesome Light Effects #------------------------------------------------------------------------------- # * 作者 Khas Arcthunder - arcthunder.site40.net # * 版本: 1.0 EN # * Released on: 17/01/2012 # #------------------------------------------------------------------------------- # * Terms of Use #------------------------------------------------------------------------------- # When using any Khas script, you agree with the following terms: # 1. You must give credit to Khas; # 2. All Khas scripts are licensed under a Creative Commons license; # 3. All Khas scripts are for non-commercial projects. If you need some script # for your commercial project (I accept requests for this type of project), # 4. All Khas scripts are for personal use, you can use or edit for your own # project, but you are not allowed to post any modified version; # 5. You can’t give credit to yourself for posting any Khas script; # 6. If you want to share a Khas script, don’t post the direct download link, # please redirect the user to arcthunder.site40.net # #------------------------------------------------------------------------------- # * 特点 #------------------------------------------------------------------------------- # - 真实的灯光 # - 灯光不会穿过墙、遮挡物和天花板 # - 静态光源 # - 动态光源(角色手电) # - 多种效果 # - 使用简单 (注释) # #------------------------------------------------------------------------------- # * 警告 - 表现效果 #------------------------------------------------------------------------------- # 这个脚本对于老人机杀伤力巨大! 本脚本测试于 Core 2 Duo E4500 和 Core i5, # 以下为会影响表现效果的地方: # # 1. 地图大小 # 本脚本会在地图表面搜索,为了剪切灯光图片.大地图会增加表面的读取,影响动态光源 的表现效果。地图大小不会影响静态灯光的效果。 # # 2. 灯光效果数量 # 本脚本在屏幕上绘制,绘制之前还会判断灯光效果是否在屏幕之外。 (在地图外的话脚本将不会绘制超出的灯光效果). 太多灯光将会使游戏卡吨,这是我猜的。 # 3. 灯光效果图片大小 # 图片越大,将其绘制成动态光源耗时越长,建议图片最大为200x200像素 #------------------------------------------------------------------------------- # * 注意 - 灯光的图片 #------------------------------------------------------------------------------- # 1. 图片大小必须是2的倍数 例如: 150x150 # 2. 图片长宽相等,例如: 156x156 # 3. 图片颜色必须要反色 #------------------------------------------------------------------------------- # * 介绍 - 1. 设定你的效果! #------------------------------- ------------------------------------------------ # # 189行为灯光设定 # 查看默认效果来学习如何使用. # #------------------------------------------------------------------------------- # * 介绍 - 2. 使用你设定的效果! #------------------------------------------------------------------------------- # 在事件中添加注释 # # [light x] # # x为效果ID # #------------------------------------------------------------------------------- # * 介绍 - 3. 灯笼效果! #------------------------------------------------------------------------------- # 动态光源(灯笼)默认是不可见的,这需要你使用脚本呼出来显示灯笼T: # # l = $game_map.lantern # 将手灯放入变量 # l.set_graphic(i) # # 设定灯笼的图片为i,i为在Graphics/Lights 里的灯笼图片名 # l.set_multiple_graphics(h) # 将灯笼的图片设定为 h, h必须在下面的哈希表中填写有 # 结构: # # h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"} # # 其中: # "ld" 当用灯笼的角色向下看时的灯光图片 # "ll" 当用灯笼的角色向左看时的灯光图片 # "lr" 当用灯笼的角色向右看时的灯光图片 # "lu" 当用灯笼的角色向上看时的灯光图片 # # l.change_owner(角色) # 将灯笼的主人交给某一角色. 角色必须为以下: # $game_player <= 玩家 # self_event <= 事件 # $game_map.events[x] <= 事件ID # # l.set_opacity(o,p) # 设定灯笼不透明度, # o 自身的不透明度; # p 是透明度的变化(闪烁). # # l.show # 以上命令都打完后要以此命令作为结束。 # # l.hide # 设定灯笼不可见. # #------------------------------------------------------------------------------- # * 介绍 - 4. 修改画面颜色(黑夜、黄昏效果)! #------------------------------------------------------------------------------- # 在灯光之下、游戏画面之上还需要有一层暗暗的画面来突出灯光效果,这层画面默认的 不透明度为0,你可以用以下脚本来修改画面颜色: # # s = $game_map.effect_surface 以这个脚本为开头 # 将画面表面设置变量 # # s.set_color(r,g,b) # 立即改变画面颜色, 其中: # r => 红色含量; # g => 绿色含量; # b => 蓝色含量; # # s.set_alpha(a) # 立即改变画面颜色为 a. # # s.change_color(时间,r,g,b) # 在一定时间内逐渐改变画面颜色, 其中: # 时间 => 变成黑夜的时间 (帧); # r => 红色含量; # g => 绿色含量; # b => 蓝色含量; # # s.change_color(时间,r,g,b,a) # 在一定时间内逐渐改变画面颜色和不透明度, 其中: # 时间 => 变成黑夜的时间 (帧); # r => 红色含量; # g => 绿色含量; # b => 蓝色含量; # a => 不透明度 # # s.change_alpha(时间,a) # 在一定时间内逐渐改变表面不透明度, where: # 时间 => 变成黑夜的时间 (帧); # a => 不透明度 # #------------------------------------------------------------------------------- # * 介绍 - 5. 更改画面色调! #------------------------------------------------------------------------------- # 你可以使用事件命令中的更改画面色调,请将204行的"Surface_UE" 设定改为 true. # # 如果你决定使用这个功能, 请设置一些细节: # 1. 颜色的数值必须在 0 到 255; # 2. 时间按帧计算; # 3. "灰色" 值将等同于不透明度的数值 # #------------------------------------------------------------------------------- # * Instructions - 6. 设定你的图块标志! #------------------------------------------------------------------------------- # 为了使效果图片有遮挡效果, 地图有三种遮挡效果: 墙, 障碍和屋顶. # 墙会和真的墙一样有影子, 所以要和障碍与屋顶区分开来. # # #------------------------------------------------------------------------------- # * Setup Part #------------------------------------------------------------------------------- =end module Light_Core Effects = { # <= 不要碰这个 #------------------------------------------------------------------------------- # 效果设定 #------------------------------------------------------------------------------- # 格式:X => [图片,不透明度,变化,裁剪图片], <= 记得在这里加一个逗号! # # X => 在事件中使用,效果的ID. # 图片 => 在 Graphics/Lights 文件夹里; # 不透明度 => 灯光效果的不透明度; # 变化 => 灯光效果的不透明度变化(闪烁); # 裁剪图片 => true:裁剪,false:不裁剪;(制造光线被墙壁遮挡的效果) # X => [图片,不透明度,变化,裁剪] 0 => ["light",255,0,true], 1 => ["torch",200,20,true], 2 => ["torch_m",180,30,true], 3 => ["light_s",255,0,true], #------------------------------------------------------------------------------- # 其他设定 #------------------------------------------------------------------------------- } # <= 不要碰这个! # 灯光效果的z轴坐标 Surface_Z = 600 # 是否允许使用事件的更改画面色调命令? Surface_UE = true # 屋顶的地形标志 Roof_Tag = 5 # 墙壁的地形标志 Wall_Tag = 6 # 障碍物的地形标志 Block_Tag = 7 # 别动它! ACC = Math.tan(Math::PI/26) end #------------------------------------------------------------------------------- # Script #------------------------------------------------------------------------------- module Cache def self.light(filename) load_bitmap("Graphics/Lights/", filename) end end module Light_Bitcore include Light_Core def self.initialize @@buffer = {} Effects.values.each { |effect| Light_Bitcore.push(effect[0])} end def self::[](key) return @@buffer[key] end def self.push(key) return if @@buffer.keys.include?(key) @@buffer[key] = Cache.light(key) end end Light_Bitcore.initialize class Light_SSource attr_reader :real_x attr_reader :real_y attr_reader :range attr_accessor :bitmap attr_reader :w attr_reader :h attr_reader :hs def initialize(char,bitmap,opacity,plus,hs) sync(char) @key = bitmap @bitmap = Light_Bitcore[@key].clone @range = @bitmap.width/2 @w = @bitmap.width @h = @bitmap.height @mr = @range - 16 @opacity = opacity @plus = plus @hs = hs render if @hs end def render tx = x ty = y tsx = x + @range tsy = y + @range dr = @range*2 for s in $game_map.surfaces next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr) s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap) end end def restore return unless @bitmap.nil? @bitmap = Light_Bitcore[@key].clone render if @hs end def opacity @plus == 0 ? @opacity : (@opacity + rand(@plus)) end def sx return $game_map.adjust_x(@real_x)*32-@mr end def sy return $game_map.adjust_y(@real_y)*32-@mr end def sync(char) @real_x = char.real_x @real_y = char.real_y end def x return (@real_x*32 - @mr).to_f end def y return (@real_y*32 - @mr).to_f end def dispose return if @bitmap.nil? @bitmap.dispose @bitmap = nil end end class Light_DSource < Light_SSource attr_reader :bitmap attr_reader :visible def initialize @key = nil @bitmap = nil @opacity = 255 @plus = 0 @char = $game_player @visible = false end def set_opacity(o,p) @opacity = o @plus = p end def set_graphic(sb) dispose @key = {2=>sb,4=>sb,6=>sb,8=>sb} Light_Bitcore.push(sb) @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone} @range = @bitmap[2].width/2 @w = @bitmap[2].width @h = @bitmap[2].height @mr = @range - 16 end def set_multiple_graphics(ba) dispose @key = ba @key.values.each {|key| Light_Bitcore.push(key)} @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone} @range = @bitmap[2].width/2 @w = @bitmap[2].width @h = @bitmap[2].height @mr = @range - 16 end def get_graphic return @bitmap[@char.direction].clone end def show return if @bitmap.nil? @visible = true end def hide @visible = false end def restore return if @key.nil? @key.values.each {|key| Light_Bitcore.push(key)} @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone} end def dispose return if @bitmap.nil? @bitmap.values.each { |b| b.dispose } @bitmap = nil end def change_owner(char) @char = char end def render end def sx return $game_map.adjust_x(@char.real_x)*32-@mr end def sy return $game_map.adjust_y(@char.real_y)*32-@mr end def x return (@char.real_x*32 - @mr).to_f end def y return (@char.real_y*32 - @mr).to_f end end class Light_Surface def initialize @ta = @a = 0 @tr = @r = 255 @tg = @g = 255 @tb = @b = 255 @va = @vr = @vg = @vb = 0.0 @timer = 0 end def refresh return if @timer == 0 @a += @va @r += @vr @g += @vg @b += @vb $game_map.light_surface.opacity = @a @timer -= 1 end def change_color(time,r,g,b,a=nil) r = 0 if r < 0; r = 255 if r > 255 g = 0 if g < 0; g = 255 if g > 255 b = 0 if b < 0; b = 255 if b > 255 unless a.nil? a = 0 if a < 0; a = 255 if a > 255 end @timer = time @tr = 255-r @tg = 255-g @tb = 255-b @va = (a.nil? ? 0 : (a-@a).to_f/@timer) @vr = (@tr - @r).to_f/@timer @vg = (@tg - @g).to_f/@timer @vb = (@tb - @b).to_f/@timer end def change_alpha(time,a) a = 0 if a < 0; a = 255 if a > 255 @timer = time @ta = a @vr = @vg = @vb = 0.0 @va = (a-@a).to_f/@timer end def set_color(r,g,b) r = 0 if r < 0; r = 255 if r > 255 g = 0 if g < 0; g = 255 if g > 255 b = 0 if b < 0; b = 255 if b > 255 @tr = @r = 255-r @tg = @g = 255-g @tb = @b = 255-b @va = @vr = @vg = @vb = 0.0 @timer = 0 end def set_alpha(a) a = 0 if a < 0; a = 255 if a > 255 @ta = @a = a $game_map.light_surface.opacity = @a @va = @vr = @vg = @vb = 0.0 @timer = 0 end def alpha return @a end def color return Color.new(@r,@g,@b) end end class Game_Map include Light_Core attr_accessor :light_surface attr_accessor :light_sources attr_accessor :surfaces attr_accessor :effect_surface attr_accessor :lantern alias kbl_setup_events setup_events alias kbl_initialize initialize alias kbl_update update def initialize kbl_initialize @effect_surface = Light_Surface.new @lantern = Light_DSource.new end def update(arg) @effect_surface.refresh if arg kbl_update(arg) end def first_tag(x,y) tag = tileset.flags[tile_id(x,y,0)] >> 12 return tag > 0 ? tag : 0 end def setup_events @light_sources.nil? ? @light_sources = [] : @light_sources.clear setup_surfaces merge_surfaces kbl_setup_events end def setup_surfaces @surfaces = [] for x in 0..(width-1) for y in 0..(height-1) tag = first_tag(x,y) if tag == Wall_Tag i = tile_id(x,y,0) if i & 0x02 == 0x02 @surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32) end if i & 0x04 == 0x04 @surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32) @surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32) end if i & 0x01 == 0x01 @surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32) @surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32) end elsif tag == Roof_Tag i = tile_id(x,y,0) @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if i & 0x02 == 0x02 @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if i & 0x04 == 0x04 @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if i & 0x01 == 0x01 elsif tag == Block_Tag f = tileset.flags[tile_id(x,y,0)] @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if f & 0x02 == 0x02 @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if f & 0x04 == 0x04 @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if f & 0x08 == 0x08 end end end end def merge_surfaces new_surfaces = [] hs = []; vs = [] ws = []; is = [] for surface in @surfaces if surface.type & 0x05 == 0 hs << surface else if surface.type & 0x010 == 0 vs << surface else if surface.type & 0x08 == 0 ws << surface else is << surface end end end end for surface in hs surface.ready ? next : surface.ready = true for s in hs next if s.ready || s.y1 != surface.y1 || surface.type != s.type if s.x2 == surface.x1 surface.x1 = s.x1 s.trash = true s.ready = true surface.ready = false elsif s.x1 == surface.x2 surface.x2 = s.x2 s.trash = true s.ready = true surface.ready = false end end end hs.each { |s| @surfaces.delete(s) if s.trash} for surface in vs surface.ready ? next : surface.ready for s in vs next if s.ready || s.x1 != surface.x1 if s.y2 == surface.y1 surface.y1 = s.y1 s.trash = true s.ready = true surface.ready = false elsif s.y1 == surface.y2 surface.y2 = s.y2 s.trash = true s.ready = true surface.ready = false end end end vs.each { |s| @surfaces.delete(s) if s.trash} for surface in ws surface.ready ? next : surface.ready for s in ws next if s.ready || s.x1 != surface.x1 if s.y2 == surface.y1 surface.y1 = s.y1 s.trash = true s.ready = true surface.ready = false elsif s.y1 == surface.y2 surface.y2 = s.y2 s.trash = true s.ready = true surface.ready = false end end end ws.each { |s| @surfaces.delete(s) if s.trash} for surface in is surface.ready ? next : surface.ready for s in is next if s.ready || s.x1 != surface.x1 if s.y2 == surface.y1 surface.y1 = s.y1 s.trash = true s.ready = true surface.ready = false elsif s.y1 == surface.y2 surface.y2 = s.y2 s.trash = true s.ready = true surface.ready = false end end end is.each { |s| @surfaces.delete(s) if s.trash} end end class Game_Event < Game_Character alias kbl_initialize initialize alias kbl_setup_page setup_page def initialize(m,e) @light = nil kbl_initialize(m,e) end def setup_page(np) kbl_setup_page(np) setup_light(np.nil?) end def setup_light(dispose) unless @light.nil? $game_map.light_sources.delete(self) @light.dispose @light = nil end unless dispose && @list.nil? for command in @list if command.code == 108 && command.parameters[0].include?("[light") command.parameters[0].scan(/\[light ([0.0-9.9]+)\]/) effect = Light_Core::Effects[$1.to_i] @light = Light_SSource.new(self,effect[0],effect[1],effect[2],effect[3]) $game_map.light_sources << self return end end end end def draw_light sx = @light.sx sy = @light.sy w = @light.w h = @light.h return if sx > 544 && sy > 416 && sx + w < 0 && sy + h < 0 $game_map.light_surface.bitmap.blt(sx,sy,@light.bitmap,Rect.new(0,0,w,h),@light.opacity) end def dispose_light @light.dispose end def restore_light @light.restore end end if Light_Core::Surface_UE class Game_Interpreter def command_223 $game_map.effect_surface.change_color(@params[1],@params[0].red,@params[0].green,@params[0].blue,@params[0].gray) wait(@params[1]) if @params[2] end end end class Game_Interpreter def self_event return $game_map.events[@event_id] end end class Block_Surface include Light_Core attr_accessor :x1 attr_accessor :y1 attr_accessor :x2 attr_accessor :y2 attr_accessor :ready attr_accessor :trash def initialize(x1,y1,x2,y2) @x1 = x1 @y1 = y1 @x2 = x2 @y2 = y2 @ready = false @trash = false end def within?(min_x,max_x,min_y,max_y) return @x2 > min_x && @x1 < max_x && @y2 > min_y && @y1 < max_y end end class Block_SL < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x01 end def visible?(sx,sy) return sx < @x1 end def render_shadow(phx,phy,sx,sy,range,bitmap) @m1 = (@y1-sy)/(@x1-sx) @n1 = sy - @m1*sx @m2 = (@y2-sy)/(@x2-sx) @n2 = sy - @m2*sx for x in @x1..(sx+range) init = shadow_iy(x) bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3) end end def shadow_iy(x) return @m1*x+@n1 end def shadow_fy(x) return @m2*x+@n2 end end class Block_SR < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x04 end def visible?(sx,sy) return sx > @x1 end def render_shadow(phx,phy,sx,sy,range,bitmap) @m1 = (@y1-sy)/(@x1-sx) @n1 = sy - @m1*sx @m2 = (@y2-sy)/(@x2-sx) @n2 = sy - @m2*sx for x in (sx-range).to_i..@x1 init = shadow_iy(x) bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3) end end def shadow_iy(x) return @m1*x+@n1 end def shadow_fy(x) return @m2*x+@n2 end end class Block_IL < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x019 end def visible?(sx,sy) return sx < @x1 && sy > @y1 end def render_shadow(phx,phy,sx,sy,range,bitmap) @m1 = (@y1-sy)/(@x1-sx) @n1 = @y1 - @m1*@x1 @m2 = (@y2-sy)/(@x2-sx) @m2 = 0 if @m2 > 0 @n2 = @y2 - @m2*@x2 for x in @x1..(sx+range) init = shadow_iy(x).floor bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3) end end def shadow_iy(x) return @m1*x+@n1 end def shadow_fy(x) return @m2*x+@n2 end end class Block_IR < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x01c end def visible?(sx,sy) return sx > @x1 && sy > @y1 end def render_shadow(phx,phy,sx,sy,range,bitmap) @m1 = (@y1-sy)/(@x1-sx) @n1 = @y1 - @m1*@x1 @m2 = (@y2-sy)/(@x2-sx) @m2 = 0 if @m2 < 0 @n2 = @y2 - @m2*@x2 for x in (sx-range).to_i..@x1 init = shadow_iy(x).floor bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3) end end def shadow_iy(x) return @m1*x+@n1 end def shadow_fy(x) return @m2*x+@n2 end end class Block_WL < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x011 end def visible?(sx,sy) return sx < @x1 && sy < @y2 end def render_shadow(phx,phy,sx,sy,range,bitmap) @m1 = (@y1-sy)/(@x1-sx) @n1 = sy - @m1*sx @m2 = (@y2-sy)/(@x2-sx) @n2 = sy - @m2*sx for x in @x1..(sx+range) init = shadow_iy(x) bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2) end end def shadow_iy(x) return @m1*x+@n1 end def shadow_fy(x) return @m2*x+@n2 end end class Block_WR < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x014 end def visible?(sx,sy) return sx > @x1 && sy < @y2 end def render_shadow(phx,phy,sx,sy,range,bitmap) @m1 = (@y1-sy)/(@x1-sx) @n1 = sy - @m1*sx @m2 = (@y2-sy)/(@x2-sx) @n2 = sy - @m2*sx for x in (sx-range).to_i..@x1 init = shadow_iy(x) bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2) end end def shadow_iy(x) return @m1*x+@n1 end def shadow_fy(x) return @m2*x+@n2 end end class Block_SU < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x02 end def visible?(sx,sy) return sy < @y1 end def render_shadow(phx,phy,sx,sy,range,bitmap) if @x1 == sx @m1 = nil else @m1 = (@y1-sy)/(@x1-sx) @m1 += ACC if @m1 < -ACC @n1 = @y1 - @m1*@x1 end if @x2 == sx @m2 = nil else @m2 = (@y2-sy)/(@x2-sx) @n2 = sy - @m2*sx end for y in @y1..(sy+range) init = shadow_ix(y) bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1) end end def shadow_ix(y) return @m1.nil? ? @x1 : (y-@n1)/@m1 end def shadow_fx(y) return @m2.nil? ? @x2 : (y-@n2)/@m2 end end class Block_SD < Block_Surface attr_reader :type def initialize(x1,y1,x2,y2) super(x1,y1,x2,y2) @type = 0x08 end def visible?(sx,sy) return sy > @y1 end def render_shadow(phx,phy,sx,sy,range,bitmap) if @x1 == sx @m1 = nil else @m1 = (@y1-sy)/(@x1-sx) @m1 -= ACC if @m1 > ACC @n1 = sy - @m1*sx end if x2 == sx @m2 = nil else @m2 = (@y2-sy)/(@x2-sx) @n2 = sy - @m2*sx end for y in (sy-range).to_i..@y1 init = shadow_ix(y) bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1) end end def shadow_ix(y) return @m1.nil? ? @x1 : (y-@n1)/@m1 end def shadow_fx(y) return @m2.nil? ? @x2 : (y-@n2)/@m2 end end class Spriteset_Map include Light_Core alias kbl_initialize initialize alias kbl_update update alias kbl_dispose dispose def initialize setup_lights kbl_initialize end def update kbl_update update_lights end def dispose kbl_dispose dispose_lights end def dispose_lights $game_map.lantern.dispose $game_map.light_sources.each { |source| source.dispose_light } $game_map.light_surface.bitmap.dispose $game_map.light_surface.dispose $game_map.light_surface = nil end def update_lights $game_map.light_surface.bitmap.clear $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color) $game_map.light_sources.each { |source| source.draw_light } return unless $game_map.lantern.visible @btr = $game_map.lantern.get_graphic x = $game_map.lantern.x y = $game_map.lantern.y r = $game_map.lantern.range sx = x + r sy = y + r dr = r*2 $game_map.surfaces.each { |s| s.render_shadow(x,y,sx,sy,r,@btr) if s.visible?(sx,sy) && s.within?(x,x+dr,y,y+dr) } $game_map.light_surface.bitmap.blt($game_map.lantern.sx,$game_map.lantern.sy,@btr,Rect.new(0,0,dr,dr),$game_map.lantern.opacity) end def setup_lights @btr = nil $game_map.lantern.restore $game_map.light_sources.each { |source| source.restore_light } $game_map.light_surface = Sprite.new $game_map.light_surface.bitmap = Bitmap.new(544,416) $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color) $game_map.light_surface.blend_type = 2 $game_map.light_surface.opacity = $game_map.effect_surface.alpha $game_map.light_surface.z = Surface_Z end end
=begin
#-------------------------------------------------------------------------------
# * [ACE] Khas Awesome Light Effects
#-------------------------------------------------------------------------------
# * 作者 Khas Arcthunder - arcthunder.site40.net
# * 版本: 1.0 EN
# * Released on: 17/01/2012
#
#-------------------------------------------------------------------------------
# * Terms of Use
#-------------------------------------------------------------------------------
# When using any Khas script, you agree with the following terms:
# 1. You must give credit to Khas;
# 2. All Khas scripts are licensed under a Creative Commons license;
# 3. All Khas scripts are for non-commercial projects. If you need some script
# for your commercial project (I accept requests for this type of project),
# 4. All Khas scripts are for personal use, you can use or edit for your own
# project, but you are not allowed to post any modified version;
# 5. You can’t give credit to yourself for posting any Khas script;
# 6. If you want to share a Khas script, don’t post the direct download link,
# please redirect the user to arcthunder.site40.net
#
#-------------------------------------------------------------------------------
# * 特点
#-------------------------------------------------------------------------------
# - 真实的灯光
# - 灯光不会穿过墙、遮挡物和天花板
# - 静态光源
# - 动态光源(角色手电)
# - 多种效果
# - 使用简单 (注释)
#
#-------------------------------------------------------------------------------
# * 警告 - 表现效果
#-------------------------------------------------------------------------------
# 这个脚本对于老人机杀伤力巨大! 本脚本测试于 Core 2 Duo E4500 和 Core i5,
# 以下为会影响表现效果的地方:
#
# 1. 地图大小
# 本脚本会在地图表面搜索,为了剪切灯光图片.大地图会增加表面的读取,影响动态光源
的表现效果。地图大小不会影响静态灯光的效果。
#
# 2. 灯光效果数量
# 本脚本在屏幕上绘制,绘制之前还会判断灯光效果是否在屏幕之外。
(在地图外的话脚本将不会绘制超出的灯光效果). 太多灯光将会使游戏卡吨,这是我猜的。
# 3. 灯光效果图片大小
# 图片越大,将其绘制成动态光源耗时越长,建议图片最大为200x200像素
#-------------------------------------------------------------------------------
# * 注意 - 灯光的图片
#-------------------------------------------------------------------------------
# 1. 图片大小必须是2的倍数 例如: 150x150
# 2. 图片长宽相等,例如: 156x156
# 3. 图片颜色必须要反色
#-------------------------------------------------------------------------------
# * 介绍 - 1. 设定你的效果!
#------------------------------- ------------------------------------------------
#
# 189行为灯光设定
# 查看默认效果来学习如何使用.
#
#-------------------------------------------------------------------------------
# * 介绍 - 2. 使用你设定的效果!
#-------------------------------------------------------------------------------
# 在事件中添加注释
#
# [light x]
#
# x为效果ID
#
#-------------------------------------------------------------------------------
# * 介绍 - 3. 灯笼效果!
#-------------------------------------------------------------------------------
# 动态光源(灯笼)默认是不可见的,这需要你使用脚本呼出来显示灯笼T:
#
# l = $game_map.lantern
#
将手灯放入变量
# l.set_graphic(i)
#
# 设定灯笼的图片为i,i为在Graphics/Lights 里的灯笼图片名
# l.set_multiple_graphics(h)
# 将灯笼的图片设定为 h, h必须在下面的哈希表中填写有
# 结构:
#
# h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}
#
# 其中:
# "ld" 当用灯笼的角色向下看时的灯光图片
# "ll" 当用灯笼的角色向左看时的灯光图片
# "lr" 当用灯笼的角色向右看时的灯光图片
# "lu" 当用灯笼的角色向上看时的灯光图片
#
# l.change_owner(角色)
# 将灯笼的主人交给某一角色. 角色必须为以下:
# $game_player <= 玩家
# self_event <= 事件
# $game_map.events[x] <= 事件ID
#
# l.set_opacity(o,p)
# 设定灯笼不透明度,
# o 自身的不透明度;
# p 是透明度的变化(闪烁).
#
# l.show
# 以上命令都打完后要以此命令作为结束。
#
# l.hide
# 设定灯笼不可见.
#
#-------------------------------------------------------------------------------
# * 介绍 - 4. 修改画面颜色(黑夜、黄昏效果)!
#-------------------------------------------------------------------------------
# 在灯光之下、游戏画面之上还需要有一层暗暗的画面来突出灯光效果,这层画面默认的
不透明度为0,你可以用以下脚本来修改画面颜色:
#
# s = $game_map.effect_surface 以这个脚本为开头
# 将画面表面设置变量
#
# s.set_color(r,g,b)
# 立即改变画面颜色, 其中:
# r => 红色含量;
# g => 绿色含量;
# b => 蓝色含量;
#
# s.set_alpha(a)
# 立即改变画面颜色为 a.
#
# s.change_color(时间,r,g,b)
# 在一定时间内逐渐改变画面颜色, 其中:
# 时间 => 变成黑夜的时间 (帧);
# r => 红色含量;
# g => 绿色含量;
# b => 蓝色含量;
#
# s.change_color(时间,r,g,b,a)
# 在一定时间内逐渐改变画面颜色和不透明度, 其中:
# 时间 => 变成黑夜的时间 (帧);
# r => 红色含量;
# g => 绿色含量;
# b => 蓝色含量;
# a => 不透明度
#
# s.change_alpha(时间,a)
# 在一定时间内逐渐改变表面不透明度, where:
# 时间 => 变成黑夜的时间 (帧);
# a => 不透明度
#
#-------------------------------------------------------------------------------
# * 介绍 - 5. 更改画面色调!
#-------------------------------------------------------------------------------
# 你可以使用事件命令中的更改画面色调,请将204行的"Surface_UE" 设定改为 true.
#
# 如果你决定使用这个功能, 请设置一些细节:
# 1. 颜色的数值必须在 0 到 255;
# 2. 时间按帧计算;
# 3. "灰色" 值将等同于不透明度的数值
#
#-------------------------------------------------------------------------------
# * Instructions - 6. 设定你的图块标志!
#-------------------------------------------------------------------------------
# 为了使效果图片有遮挡效果, 地图有三种遮挡效果: 墙, 障碍和屋顶.
# 墙会和真的墙一样有影子, 所以要和障碍与屋顶区分开来.
#
#
#-------------------------------------------------------------------------------
# * Setup Part
#-------------------------------------------------------------------------------
=end
module Light_Core
Effects = { # <= 不要碰这个
#-------------------------------------------------------------------------------
# 效果设定
#-------------------------------------------------------------------------------
# 格式:X => [图片,不透明度,变化,裁剪图片], <= 记得在这里加一个逗号!
#
# X => 在事件中使用,效果的ID.
# 图片 => 在 Graphics/Lights 文件夹里;
# 不透明度 => 灯光效果的不透明度;
# 变化 => 灯光效果的不透明度变化(闪烁);
# 裁剪图片 => true:裁剪,false:不裁剪;(制造光线被墙壁遮挡的效果)
# X => [图片,不透明度,变化,裁剪]
0 => ["light",255,0,true],
1 => ["torch",200,20,true],
2 => ["torch_m",180,30,true],
3 => ["light_s",255,0,true],
#-------------------------------------------------------------------------------
# 其他设定
#-------------------------------------------------------------------------------
} # <= 不要碰这个!
# 灯光效果的z轴坐标
Surface_Z = 600
# 是否允许使用事件的更改画面色调命令?
Surface_UE = true
# 屋顶的地形标志
Roof_Tag = 5
# 墙壁的地形标志
Wall_Tag = 6
# 障碍物的地形标志
Block_Tag = 7
# 别动它!
ACC = Math.tan(Math::PI/26)
end
#-------------------------------------------------------------------------------
# Script
#-------------------------------------------------------------------------------
module Cache
def self.light(filename)
load_bitmap("Graphics/Lights/", filename)
end
end
module Light_Bitcore
include Light_Core
def self.initialize
@@buffer = {}
Effects.values.each { |effect| Light_Bitcore.push(effect[0])}
end
def self::[](key)
return @@buffer[key]
end
def self.push(key)
return if @@buffer.keys.include?(key)
@@buffer[key] = Cache.light(key)
end
end
Light_Bitcore.initialize
class Light_SSource
attr_reader :real_x
attr_reader :real_y
attr_reader :range
attr_accessor :bitmap
attr_reader :w
attr_reader :h
attr_reader :hs
def initialize(char,bitmap,opacity,plus,hs)
sync(char)
@key = bitmap
@bitmap = Light_Bitcore[@key].clone
@range = @bitmap.width/2
@w = @bitmap.width
@h = @bitmap.height
@mr = @range - 16
@opacity = opacity
@plus = plus
@hs = hs
render if @hs
end
def render
tx = x
ty = y
tsx = x + @range
tsy = y + @range
dr = @range*2
for s in $game_map.surfaces
next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr)
s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap)
end
end
def restore
return unless @bitmap.nil?
@bitmap = Light_Bitcore[@key].clone
render if @hs
end
def opacity
@plus == 0 ? @opacity : (@opacity + rand(@plus))
end
def sx
return $game_map.adjust_x(@real_x)*32-@mr
end
def sy
return $game_map.adjust_y(@real_y)*32-@mr
end
def sync(char)
@real_x = char.real_x
@real_y = char.real_y
end
def x
return (@real_x*32 - @mr).to_f
end
def y
return (@real_y*32 - @mr).to_f
end
def dispose
return if @bitmap.nil?
@bitmap.dispose
@bitmap = nil
end
end
class Light_DSource < Light_SSource
attr_reader :bitmap
attr_reader :visible
def initialize
@key = nil
@bitmap = nil
@opacity = 255
@plus = 0
@char = $game_player
@visible = false
end
def set_opacity(o,p)
@opacity = o
@plus = p
end
def set_graphic(sb)
dispose
@key = {2=>sb,4=>sb,6=>sb,8=>sb}
Light_Bitcore.push(sb)
@bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
@range = @bitmap[2].width/2
@w = @bitmap[2].width
@h = @bitmap[2].height
@mr = @range - 16
end
def set_multiple_graphics(ba)
dispose
@key = ba
@key.values.each {|key| Light_Bitcore.push(key)}
@bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
@range = @bitmap[2].width/2
@w = @bitmap[2].width
@h = @bitmap[2].height
@mr = @range - 16
end
def get_graphic
return @bitmap[@char.direction].clone
end
def show
return if @bitmap.nil?
@visible = true
end
def hide
@visible = false
end
def restore
return if @key.nil?
@key.values.each {|key| Light_Bitcore.push(key)}
@bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
end
def dispose
return if @bitmap.nil?
@bitmap.values.each { |b| b.dispose }
@bitmap = nil
end
def change_owner(char)
@char = char
end
def render
end
def sx
return $game_map.adjust_x(@char.real_x)*32-@mr
end
def sy
return $game_map.adjust_y(@char.real_y)*32-@mr
end
def x
return (@char.real_x*32 - @mr).to_f
end
def y
return (@char.real_y*32 - @mr).to_f
end
end
class Light_Surface
def initialize
@ta = @a = 0
@tr = @r = 255
@tg = @g = 255
@tb = @b = 255
@va = @vr = @vg = @vb = 0.0
@timer = 0
end
def refresh
return if @timer == 0
@a += @va
@r += @vr
@g += @vg
@b += @vb
$game_map.light_surface.opacity = @a
@timer -= 1
end
def change_color(time,r,g,b,a=nil)
r = 0 if r < 0; r = 255 if r > 255
g = 0 if g < 0; g = 255 if g > 255
b = 0 if b < 0; b = 255 if b > 255
unless a.nil?
a = 0 if a < 0; a = 255 if a > 255
end
@timer = time
@tr = 255-r
@tg = 255-g
@tb = 255-b
@va = (a.nil? ? 0 : (a-@a).to_f/@timer)
@vr = (@tr - @r).to_f/@timer
@vg = (@tg - @g).to_f/@timer
@vb = (@tb - @b).to_f/@timer
end
def change_alpha(time,a)
a = 0 if a < 0; a = 255 if a > 255
@timer = time
@ta = a
@vr = @vg = @vb = 0.0
@va = (a-@a).to_f/@timer
end
def set_color(r,g,b)
r = 0 if r < 0; r = 255 if r > 255
g = 0 if g < 0; g = 255 if g > 255
b = 0 if b < 0; b = 255 if b > 255
@tr = @r = 255-r
@tg = @g = 255-g
@tb = @b = 255-b
@va = @vr = @vg = @vb = 0.0
@timer = 0
end
def set_alpha(a)
a = 0 if a < 0; a = 255 if a > 255
@ta = @a = a
$game_map.light_surface.opacity = @a
@va = @vr = @vg = @vb = 0.0
@timer = 0
end
def alpha
return @a
end
def color
return Color.new(@r,@g,@b)
end
end
class Game_Map
include Light_Core
attr_accessor :light_surface
attr_accessor :light_sources
attr_accessor :surfaces
attr_accessor :effect_surface
attr_accessor :lantern
alias kbl_setup_events setup_events
alias kbl_initialize initialize
alias kbl_update update
def initialize
kbl_initialize
@effect_surface = Light_Surface.new
@lantern = Light_DSource.new
end
def update(arg)
@effect_surface.refresh if arg
kbl_update(arg)
end
def first_tag(x,y)
tag = tileset.flags[tile_id(x,y,0)] >> 12
return tag > 0 ? tag : 0
end
def setup_events
@light_sources.nil? ? @light_sources = [] : @light_sources.clear
setup_surfaces
merge_surfaces
kbl_setup_events
end
def setup_surfaces
@surfaces = []
for x in 0..(width-1)
for y in 0..(height-1)
tag = first_tag(x,y)
if tag == Wall_Tag
i = tile_id(x,y,0)
if i & 0x02 == 0x02
@surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32)
end
if i & 0x04 == 0x04
@surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32)
@surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32)
end
if i & 0x01 == 0x01
@surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32)
@surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32)
end
elsif tag == Roof_Tag
i = tile_id(x,y,0)
@surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if i & 0x02 == 0x02
@surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if i & 0x04 == 0x04
@surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if i & 0x01 == 0x01
elsif tag == Block_Tag
f = tileset.flags[tile_id(x,y,0)]
@surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if f & 0x02 == 0x02
@surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if f & 0x04 == 0x04
@surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if f & 0x08 == 0x08
end
end
end
end
def merge_surfaces
new_surfaces = []
hs = []; vs = []
ws = []; is = []
for surface in @surfaces
if surface.type & 0x05 == 0
hs << surface
else
if surface.type & 0x010 == 0
vs << surface
else
if surface.type & 0x08 == 0
ws << surface
else
is << surface
end
end
end
end
for surface in hs
surface.ready ? next : surface.ready = true
for s in hs
next if s.ready || s.y1 != surface.y1 || surface.type != s.type
if s.x2 == surface.x1
surface.x1 = s.x1
s.trash = true
s.ready = true
surface.ready = false
elsif s.x1 == surface.x2
surface.x2 = s.x2
s.trash = true
s.ready = true
surface.ready = false
end
end
end
hs.each { |s| @surfaces.delete(s) if s.trash}
for surface in vs
surface.ready ? next : surface.ready
for s in vs
next if s.ready || s.x1 != surface.x1
if s.y2 == surface.y1
surface.y1 = s.y1
s.trash = true
s.ready = true
surface.ready = false
elsif s.y1 == surface.y2
surface.y2 = s.y2
s.trash = true
s.ready = true
surface.ready = false
end
end
end
vs.each { |s| @surfaces.delete(s) if s.trash}
for surface in ws
surface.ready ? next : surface.ready
for s in ws
next if s.ready || s.x1 != surface.x1
if s.y2 == surface.y1
surface.y1 = s.y1
s.trash = true
s.ready = true
surface.ready = false
elsif s.y1 == surface.y2
surface.y2 = s.y2
s.trash = true
s.ready = true
surface.ready = false
end
end
end
ws.each { |s| @surfaces.delete(s) if s.trash}
for surface in is
surface.ready ? next : surface.ready
for s in is
next if s.ready || s.x1 != surface.x1
if s.y2 == surface.y1
surface.y1 = s.y1
s.trash = true
s.ready = true
surface.ready = false
elsif s.y1 == surface.y2
surface.y2 = s.y2
s.trash = true
s.ready = true
surface.ready = false
end
end
end
is.each { |s| @surfaces.delete(s) if s.trash}
end
end
class Game_Event < Game_Character
alias kbl_initialize initialize
alias kbl_setup_page setup_page
def initialize(m,e)
@light = nil
kbl_initialize(m,e)
end
def setup_page(np)
kbl_setup_page(np)
setup_light(np.nil?)
end
def setup_light(dispose)
unless @light.nil?
$game_map.light_sources.delete(self)
@light.dispose
@light = nil
end
unless dispose && @list.nil?
for command in @list
if command.code == 108 && command.parameters[0].include?("[light")
command.parameters[0].scan(/\[light ([0.0-9.9]+)\]/)
effect = Light_Core::Effects[$1.to_i]
@light = Light_SSource.new(self,effect[0],effect[1],effect[2],effect[3])
$game_map.light_sources << self
return
end
end
end
end
def draw_light
sx = @light.sx
sy = @light.sy
w = @light.w
h = @light.h
return if sx > 544 && sy > 416 && sx + w < 0 && sy + h < 0
$game_map.light_surface.bitmap.blt(sx,sy,@light.bitmap,Rect.new(0,0,w,h),@light.opacity)
end
def dispose_light
@light.dispose
end
def restore_light
@light.restore
end
end
if Light_Core::Surface_UE
class Game_Interpreter
def command_223
$game_map.effect_surface.change_color(@params[1],@params[0].red,@params[0].green,@params[0].blue,@params[0].gray)
wait(@params[1]) if @params[2]
end
end
end
class Game_Interpreter
def self_event
return $game_map.events[@event_id]
end
end
class Block_Surface
include Light_Core
attr_accessor :x1
attr_accessor :y1
attr_accessor :x2
attr_accessor :y2
attr_accessor :ready
attr_accessor :trash
def initialize(x1,y1,x2,y2)
@x1 = x1
@y1 = y1
@x2 = x2
@y2 = y2
@ready = false
@trash = false
end
def within?(min_x,max_x,min_y,max_y)
return @x2 > min_x && @x1 < max_x && @y2 > min_y && @y1 < max_y
end
end
class Block_SL < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x01
end
def visible?(sx,sy)
return sx < @x1
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
@m1 = (@y1-sy)/(@x1-sx)
@n1 = sy - @m1*sx
@m2 = (@y2-sy)/(@x2-sx)
@n2 = sy - @m2*sx
for x in @x1..(sx+range)
init = shadow_iy(x)
bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
end
end
def shadow_iy(x)
return @m1*x+@n1
end
def shadow_fy(x)
return @m2*x+@n2
end
end
class Block_SR < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x04
end
def visible?(sx,sy)
return sx > @x1
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
@m1 = (@y1-sy)/(@x1-sx)
@n1 = sy - @m1*sx
@m2 = (@y2-sy)/(@x2-sx)
@n2 = sy - @m2*sx
for x in (sx-range).to_i..@x1
init = shadow_iy(x)
bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
end
end
def shadow_iy(x)
return @m1*x+@n1
end
def shadow_fy(x)
return @m2*x+@n2
end
end
class Block_IL < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x019
end
def visible?(sx,sy)
return sx < @x1 && sy > @y1
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
@m1 = (@y1-sy)/(@x1-sx)
@n1 = @y1 - @m1*@x1
@m2 = (@y2-sy)/(@x2-sx)
@m2 = 0 if @m2 > 0
@n2 = @y2 - @m2*@x2
for x in @x1..(sx+range)
init = shadow_iy(x).floor
bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
end
end
def shadow_iy(x)
return @m1*x+@n1
end
def shadow_fy(x)
return @m2*x+@n2
end
end
class Block_IR < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x01c
end
def visible?(sx,sy)
return sx > @x1 && sy > @y1
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
@m1 = (@y1-sy)/(@x1-sx)
@n1 = @y1 - @m1*@x1
@m2 = (@y2-sy)/(@x2-sx)
@m2 = 0 if @m2 < 0
@n2 = @y2 - @m2*@x2
for x in (sx-range).to_i..@x1
init = shadow_iy(x).floor
bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
end
end
def shadow_iy(x)
return @m1*x+@n1
end
def shadow_fy(x)
return @m2*x+@n2
end
end
class Block_WL < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x011
end
def visible?(sx,sy)
return sx < @x1 && sy < @y2
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
@m1 = (@y1-sy)/(@x1-sx)
@n1 = sy - @m1*sx
@m2 = (@y2-sy)/(@x2-sx)
@n2 = sy - @m2*sx
for x in @x1..(sx+range)
init = shadow_iy(x)
bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
end
end
def shadow_iy(x)
return @m1*x+@n1
end
def shadow_fy(x)
return @m2*x+@n2
end
end
class Block_WR < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x014
end
def visible?(sx,sy)
return sx > @x1 && sy < @y2
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
@m1 = (@y1-sy)/(@x1-sx)
@n1 = sy - @m1*sx
@m2 = (@y2-sy)/(@x2-sx)
@n2 = sy - @m2*sx
for x in (sx-range).to_i..@x1
init = shadow_iy(x)
bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
end
end
def shadow_iy(x)
return @m1*x+@n1
end
def shadow_fy(x)
return @m2*x+@n2
end
end
class Block_SU < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x02
end
def visible?(sx,sy)
return sy < @y1
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
if @x1 == sx
@m1 = nil
else
@m1 = (@y1-sy)/(@x1-sx)
@m1 += ACC if @m1 < -ACC
@n1 = @y1 - @m1*@x1
end
if @x2 == sx
@m2 = nil
else
@m2 = (@y2-sy)/(@x2-sx)
@n2 = sy - @m2*sx
end
for y in @y1..(sy+range)
init = shadow_ix(y)
bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
end
end
def shadow_ix(y)
return @m1.nil? ? @x1 : (y-@n1)/@m1
end
def shadow_fx(y)
return @m2.nil? ? @x2 : (y-@n2)/@m2
end
end
class Block_SD < Block_Surface
attr_reader :type
def initialize(x1,y1,x2,y2)
super(x1,y1,x2,y2)
@type = 0x08
end
def visible?(sx,sy)
return sy > @y1
end
def render_shadow(phx,phy,sx,sy,range,bitmap)
if @x1 == sx
@m1 = nil
else
@m1 = (@y1-sy)/(@x1-sx)
@m1 -= ACC if @m1 > ACC
@n1 = sy - @m1*sx
end
if x2 == sx
@m2 = nil
else
@m2 = (@y2-sy)/(@x2-sx)
@n2 = sy - @m2*sx
end
for y in (sy-range).to_i..@y1
init = shadow_ix(y)
bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
end
end
def shadow_ix(y)
return @m1.nil? ? @x1 : (y-@n1)/@m1
end
def shadow_fx(y)
return @m2.nil? ? @x2 : (y-@n2)/@m2
end
end
class Spriteset_Map
include Light_Core
alias kbl_initialize initialize
alias kbl_update update
alias kbl_dispose dispose
def initialize
setup_lights
kbl_initialize
end
def update
kbl_update
update_lights
end
def dispose
kbl_dispose
dispose_lights
end
def dispose_lights
$game_map.lantern.dispose
$game_map.light_sources.each { |source| source.dispose_light }
$game_map.light_surface.bitmap.dispose
$game_map.light_surface.dispose
$game_map.light_surface = nil
end
def update_lights
$game_map.light_surface.bitmap.clear
$game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)
$game_map.light_sources.each { |source| source.draw_light }
return unless $game_map.lantern.visible
@btr = $game_map.lantern.get_graphic
x = $game_map.lantern.x
y = $game_map.lantern.y
r = $game_map.lantern.range
sx = x + r
sy = y + r
dr = r*2
$game_map.surfaces.each { |s| s.render_shadow(x,y,sx,sy,r,@btr) if s.visible?(sx,sy) && s.within?(x,x+dr,y,y+dr) }
$game_map.light_surface.bitmap.blt($game_map.lantern.sx,$game_map.lantern.sy,@btr,Rect.new(0,0,dr,dr),$game_map.lantern.opacity)
end
def setup_lights
@btr = nil
$game_map.lantern.restore
$game_map.light_sources.each { |source| source.restore_light }
$game_map.light_surface = Sprite.new
$game_map.light_surface.bitmap = Bitmap.new(544,416)
$game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)
$game_map.light_surface.blend_type = 2
$game_map.light_surface.opacity = $game_map.effect_surface.alpha
$game_map.light_surface.z = Surface_Z
end
end
|
|