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

Project1

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

[已经解决] Khas Awesome Light Effects 脚本的使用教程

[复制链接]

Lv2.观梦者

梦石
0
星屑
465
在线时间
34 小时
注册时间
2018-7-26
帖子
37
跳转到指定楼层
1
发表于 2018-8-23 11:44:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
50星屑
本帖最后由 Blois233 于 2018-8-23 11:46 编辑

我是很早以前不知道在哪找的。。
站里大多是一些使用脚本时出现的问题,没有具体教程
因为RGSS3只学了皮毛所以半看半蒙试了一下发现并不行
所以想求个具体教程
下面附上脚本


#-------------------------------------------------------------------------------
# * [ACE] Khas Awesome Light Effects
#-------------------------------------------------------------------------------
# * By Khas Arcthunder - arcthunder.site40.net
# * Version: 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),
#    send an email to [email protected] with your request;
# 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
#
#-------------------------------------------------------------------------------
# * Features
#-------------------------------------------------------------------------------
# - Realistic Light
# - Light does not pass over walls, blocks and roofs
# - Static Light Sources
# - Dynamic Light Sources (like a player's lantern)
# - Multiple effects
# - Easy to use (comments)
#
#-------------------------------------------------------------------------------
# * WARNING - Performance
#-------------------------------------------------------------------------------
# This script may be too heavy to old processors! The Awesome Light Effects was
# tested on a Core 2 Duo E4500 and on a Core i5, without any lag. However,
# there's other factors that may influence the script performance:
#
# 1. Map size
# This script searches surfaces on the map, in order to cut the light pictures.
# In a huge map, the number of surfaces may increase a lot, affecting the
# DYNAMIC LIGHT SOURCE only. Map size does not influence the static sources.
#
# 2. Number of effects
# This script draws the effects on the screen, but before drawing, it checks
# if the effect is out of screen (in this case, the script will skip the
# light drawing). Too much effects may cause lag, but this is just a prevision.
#
# 3. Effect's picture size
# The picture size of the DYNAMIC LIGHT SOURCE influences directly on your
# game's performace. The bigger is the picture, the slower it will be to
# draw it dynamically. The recommended maximum size is 200x200 pixels
#
#-------------------------------------------------------------------------------
# * WARNING - Light pictures
#-------------------------------------------------------------------------------
# In order to run this script correctly, the light pictures MUST obey the
# following conditions:
# 1. The picture's size MUST be multiple of 2. Example: 150x150
# 2. The picture's width MUST be equal to it's height. Example: 156x156
# 3. The picture's colors MUST be inverted! This is necessary because
#    the script inverts the colors to draw the effect. The black color
#    will be transparent!
#
#-------------------------------------------------------------------------------
# * Instructions - 1. Setup your effects!
#-------------------------------------------------------------------------------
# In order to setup your static effects, go to the setup part and define your
# effects inside the Effects hash. Do as the following mode:
#
# X => [picture,opacity,variation,cut],   <= Remember to put a comma here!
#
# Where:
# picture => Picture's name, inside the Graphics/Lights folder;
# opacity => Effect's opacity;
# variation => Effect's opacity variation;
# cut => Put true to cut the effect or false to don't;
# X => The effect's ID, it will be used on events.
#
# Check the default effects to understand how they work.
#
#-------------------------------------------------------------------------------
# * Instructions - 2. Use your effects!
#-------------------------------------------------------------------------------
# In order to use a effect, put the following comment on a event:
#
# [light x]
#
# Where x must be the Effect's ID.
#
#-------------------------------------------------------------------------------
# * Instructions - 3. Use an awesome lantern!
#-------------------------------------------------------------------------------
# The dynamic light source (lantern) is initialized invisible by default.
# You may call the following commands:
#
# l = $game_map.lantern
# Gets the lantern into a variable

# l.set_graphic(i)
# Sets the lantern's graphic to i, where i must be the picture's file name on
# Graphics/Lights folder.
#
# l.set_multiple_graphics(h)
# Sets the lantern's graphics to h, where h must be a hash with the following
# structure:
#
# h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}
#
# Where:
# "ld" is the name of the picture when the lantern's owner is looking down;
# "ll" is the name of the picture when the lantern's owner is looking left;
# "lr" is the name of the picture when the lantern's owner is looking right;
# "lu" is the name of the picture when the lantern's owner is looking up.
#
# l.change_owner(char)
# Sets the lantern's owner to char. Char must be ONE of the following commands:
# $game_player           <= The player itself;
# self_event             <= The event where the command was called;
# $game_map.events[x]    <= The event ID x.
#
# l.set_opacity(o,p)
# Sets the lantern's opacity, where:
# o is the opacity itself;
# p is the opacity variation.
#
# l.show
# After setting the lantern with the commands above, you may set it to visible
# using this command.
#
# l.hide
# Use this command to set the lantern as invisible.
#
#-------------------------------------------------------------------------------
# * Instructions - 4. Use the effect's surface!
#-------------------------------------------------------------------------------
# The Awesome Light Effects draws the effects on a surface. In order to make
# the effects visible, the effect's surface MUST be visible. The Effect's
# Surface is initialized with it's opacity set to zero. You can call the
# following commands:
#
# s = $game_map.effect_surface
# Gets the Effect's Surface into a variable
#
# s.set_color(r,g,b)
# Changes the Effect's Surface color instantly, where:
# r => red level;
# g => green level;
# b => blue level;
#
# s.set_alpha(a)
# Changes the Effect's Surface opacity instantly to a.
#
# s.change_color(time,r,g,b)
# Changes the Effect's Surface color ONLY in a certain time, where:
# time => The change's time (frames);
# r => red level;
# g => green level;
# b => blue level;
#
# s.change_color(time,r,g,b,a)
# Changes the Effect's Surface color and it's opacity in a certain time, where:
# time => The change's time (frames);
# r => red level;
# g => green level;
# b => blue level;
# a => opacity
#
# s.change_alpha(time,a)
# Changes the Effect's Surface opacity in a certain time, where:
# time => The change's time (frames);
# a => opacity
#
#-------------------------------------------------------------------------------
# * Instructions - 5. Use the effect's surface with Tone command!
#-------------------------------------------------------------------------------
# You can access the Effect's Surface with the "Screen Tone" command. In order
# to turn this feature on, set the "Surface_UE" constant to true.
#
# If you decided to use this feature, please note some details:
# 1. The colors values must be between 0 and 255;
# 2. The time is in frames;
# 3. The "gray" value will be sent as the opacity value
#
#-------------------------------------------------------------------------------
# * Instructions - 6. Setup your Tileset Tags!
#-------------------------------------------------------------------------------
# In order to cut the effect's picture correctly, there's 3 types of behavior
# for a tile: wall, block and roof. Walls will make shadows as real walls,
# blocks as blocks and roofs as roofs. So, the tileset tags MUST be configured.
# Check the demo to understand how this system works. If the tilesets aren't
# configured correctly, the script won't cut the effects correctly.
#
#-------------------------------------------------------------------------------
# * Setup Part
#-------------------------------------------------------------------------------
module Light_Core
  Effects = { #  <= DON'T change this!
#-------------------------------------------------------------------------------
# PUT YOUR EFFECTS HERE!
#-------------------------------------------------------------------------------
  0 => ["light",255,0,true],
  1 => ["torch",200,20,true],
  2 => ["torch_m",180,30,true],
  3 => ["light_s",255,0,true],

#-------------------------------------------------------------------------------
# End of effecs configuration
#-------------------------------------------------------------------------------
  } #  <= DON'T change this!

  # Z coordinate of the Effect's Surface
  Surface_Z = 180
  # Enable Effect's Surface control by "Screen Tone" command?
  Surface_UE = true

  # Roof behavior tag
  Roof_Tag = 5
  # Wall behavior tag
  Wall_Tag = 6
  # Block behavior tag
  Block_Tag = 7

  # Don't change this!
  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
个人现代风游戏制作中。

Lv4.逐梦者

梦石
1
星屑
14503
在线时间
2086 小时
注册时间
2017-9-28
帖子
662
2
发表于 2018-8-23 11:44:40 | 只看该作者
  1. =begin
  2. #-------------------------------------------------------------------------------
  3. # * [ACE] Khas Awesome Light Effects
  4. #-------------------------------------------------------------------------------
  5. # * 作者 Khas Arcthunder - arcthunder.site40.net
  6. # * 版本: 1.0 EN
  7. # * Released on: 17/01/2012
  8. #
  9. #-------------------------------------------------------------------------------
  10. # * Terms of Use
  11. #-------------------------------------------------------------------------------
  12. # When using any Khas script, you agree with the following terms:
  13. # 1. You must give credit to Khas;
  14. # 2. All Khas scripts are licensed under a Creative Commons license;
  15. # 3. All Khas scripts are for non-commercial projects. If you need some script
  16. #    for your commercial project (I accept requests for this type of project),
  17. #    send an email to [email protected] with your request;
  18. # 4. All Khas scripts are for personal use, you can use or edit for your own
  19. #    project, but you are not allowed to post any modified version;
  20. # 5. You can’t give credit to yourself for posting any Khas script;
  21. # 6. If you want to share a Khas script, don’t post the direct download link,
  22. #    please redirect the user to arcthunder.site40.net
  23. #
  24. #-------------------------------------------------------------------------------
  25. # * 特点
  26. #-------------------------------------------------------------------------------
  27. # - 真实的灯光
  28. # - 灯光不会穿过墙、遮挡物和天花板
  29. # - 静态光源
  30. # - 动态光源(角色手电)
  31. # - 多种效果
  32. # - 使用简单 (注释)
  33. #
  34. #-------------------------------------------------------------------------------
  35. # * 警告 - 表现效果
  36. #-------------------------------------------------------------------------------
  37. # 这个脚本对于老人机杀伤力巨大! 本脚本测试于 Core 2 Duo E4500 和 Core i5,
  38. # 以下为会影响表现效果的地方:
  39. #
  40. # 1. 地图大小
  41. # 本脚本会在地图表面搜索,为了剪切灯光图片.大地图会增加表面的读取,影响动态光源
  42.   的表现效果。地图大小不会影响静态灯光的效果。

  43. #
  44. # 2. 灯光效果数量
  45. # 本脚本在屏幕上绘制,绘制之前还会判断灯光效果是否在屏幕之外。
  46. (在地图外的话脚本将不会绘制超出的灯光效果). 太多灯光将会使游戏卡吨,这是我猜的。

  47. # 3. 灯光效果图片大小
  48. # 图片越大,将其绘制成动态光源耗时越长,建议图片最大为200x200像素
  49. #-------------------------------------------------------------------------------
  50. # * 注意 - 灯光的图片
  51. #-------------------------------------------------------------------------------
  52. #      1. 图片大小必须是2的倍数 例如: 150x150
  53. #      2. 图片长宽相等,例如: 156x156
  54. #      3. 图片颜色必须要反色
  55. #-------------------------------------------------------------------------------
  56. # * 介绍 - 1. 设定你的效果!
  57. #-------------------------------  ------------------------------------------------
  58. #
  59. # 189行为灯光设定
  60. # 查看默认效果来学习如何使用.
  61. #
  62. #-------------------------------------------------------------------------------
  63. # * 介绍 - 2. 使用你设定的效果!
  64. #-------------------------------------------------------------------------------
  65. # 在事件中添加注释
  66. #
  67. # [light x]
  68. #
  69. # x为效果ID
  70. #
  71. #-------------------------------------------------------------------------------
  72. # * 介绍 - 3. 灯笼效果!
  73. #-------------------------------------------------------------------------------
  74. # 动态光源(灯笼)默认是不可见的,这需要你使用脚本呼出来显示灯笼T:
  75. #
  76. # l = $game_map.lantern
  77. #
  78.    将灯笼放入变量

  79. # l.set_graphic(i)
  80. #
  81. #   设定灯笼的图片为i,i为在Graphics/Lights  里的灯笼图片名

  82. # l.set_multiple_graphics(h)
  83. # 将灯笼的图片设定为 h, h必须在下面的哈希表中填写有
  84. # 结构:
  85. #
  86. # h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}
  87. #
  88. # 其中:
  89. # "ld" 当用灯笼的角色向下看时的灯光图片
  90. # "ll" 当用灯笼的角色向左看时的灯光图片
  91. # "lr" 当用灯笼的角色向右看时的灯光图片
  92. # "lu" 当用灯笼的角色向上看时的灯光图片
  93. #
  94. # l.change_owner(角色)
  95. # 将灯笼的主人交给某一角色. 角色必须为以下:
  96.   
  97. # $game_player           <= 玩家
  98. # self_event             <= 事件
  99. # $game_map.events[x]    <= 事件ID
  100. #
  101. # l.set_opacity(o,p)
  102. # 设定灯笼不透明度,
  103. # o 自身的不透明度;
  104. # p 是透明度的变化(闪烁).
  105. #
  106. # l.show
  107. # 以上命令都打完后要以此命令作为结束。
  108. #
  109. # l.hide
  110. # 设定灯笼不可见.
  111. #
  112. #-------------------------------------------------------------------------------
  113. # * 介绍 - 4. 修改画面颜色(黑夜、黄昏效果)!
  114. #-------------------------------------------------------------------------------
  115. # 在灯光之下、游戏画面之上还需要有一层暗暗的画面来突出灯光效果,这层画面默认的
  116.    不透明度为0,你可以用以下脚本来修改画面颜色:
  117. #
  118. # s = $game_map.effect_surface  以这个脚本为开头
  119. #  将画面表面设置变量
  120. #
  121. # s.set_color(r,g,b)
  122. # 立即改变画面颜色, 其中:
  123. # r => 红色含量;
  124. # g => 绿色含量;
  125. # b => 蓝色含量;
  126. #
  127. # s.set_alpha(a)
  128. # 立即改变画面颜色为 a.
  129. #
  130. # s.change_color(时间,r,g,b)
  131. # 在一定时间内逐渐改变画面颜色, 其中:
  132. # 时间 => 变成黑夜的时间 (帧);
  133. # r => 红色含量;
  134. # g => 绿色含量;
  135. # b => 蓝色含量;
  136. #
  137. # s.change_color(时间,r,g,b,a)
  138. # 在一定时间内逐渐改变画面颜色和不透明度, 其中:
  139. # 时间 => 变成黑夜的时间 (帧);
  140. # r => 红色含量;
  141. # g => 绿色含量;
  142. # b => 蓝色含量;
  143. # a => 不透明度
  144. #
  145. # s.change_alpha(时间,a)
  146. # 在一定时间内逐渐改变表面不透明度,其中:
  147. # 时间 => 变成黑夜的时间 (帧);
  148. # a => 不透明度
  149. #
  150. #-------------------------------------------------------------------------------
  151. # * 介绍 - 5. 更改画面色调!
  152. #-------------------------------------------------------------------------------
  153. # 你可以使用事件命令中的更改画面色调,请将204行的"Surface_UE" 设定改为 true.
  154. #
  155. # 如果你决定使用这个功能, 请设置一些细节:
  156. # 1. 颜色的数值必须在 0 到 255;
  157. # 2. 时间按帧计算;
  158. # 3. "灰色" 值将等同于不透明度的数值
  159. #
  160. #-------------------------------------------------------------------------------
  161. # * Instructions - 6. 设定你的图块标志!
  162. #-------------------------------------------------------------------------------
  163. # 为了使效果图片有遮挡效果, 地图有三种遮挡效果: 墙, 障碍和屋顶.
  164. #   墙会和真的墙一样有影子, 所以要和障碍与屋顶区分开来.
  165. #
  166. #
  167. #-------------------------------------------------------------------------------
  168. # * Setup Part
  169. #-------------------------------------------------------------------------------
  170. =end
  171. module Light_Core
  172.   Effects = { #  <= 不要碰这个
  173. #-------------------------------------------------------------------------------
  174. # 效果设定
  175. #-------------------------------------------------------------------------------
  176. # 格式:X => [图片,不透明度,变化,裁剪图片],   <= 记得在这里加一个逗号!
  177. #
  178. # X => 在事件中使用,效果的ID.
  179. # 图片 => 在 Graphics/Lights 文件夹里;
  180. # 不透明度 => 灯光效果的不透明度;
  181. # 变化 => 灯光效果的不透明度变化(闪烁);
  182. # 裁剪图片 => true:裁剪,false:不裁剪;(制造光线被墙壁遮挡的效果)

  183. # X => [图片,不透明度,变化,裁剪]
  184.   0 => ["light",255,0,true],
  185.   1 => ["torch",200,20,true],
  186.   2 => ["torch_m",180,30,true],
  187.   3 => ["light_s",255,0,true],
  188.   4 => ["light",255,0,false],

  189.   
  190. #-------------------------------------------------------------------------------
  191. # 其他设定
  192. #-------------------------------------------------------------------------------
  193.   } #  <= 不要碰这个!
  194.   
  195.   # 灯光效果的z轴坐标
  196.   Surface_Z = 600
  197.   
  198.   # 是否允许使用事件的更改画面色调命令?
  199.   Surface_UE = true
  200.   
  201.   # 屋顶的地形标志
  202.   Roof_Tag = 5
  203.   # 墙壁的地形标志
  204.   Wall_Tag = 6
  205.   # 障碍物的地形标志
  206.   Block_Tag = 7
  207.   
  208.   # 别动它!
  209.   ACC = Math.tan(Math::PI/26)
  210. end
  211. #-------------------------------------------------------------------------------
  212. # Script
  213. #-------------------------------------------------------------------------------
  214. module Cache
  215.   def self.light(filename)
  216.     load_bitmap("Graphics/Lights/", filename)
  217.   end
  218. end
  219. module Light_Bitcore
  220.   include Light_Core
  221.   def self.initialize
  222.     @@buffer = {}
  223.     Effects.values.each { |effect| Light_Bitcore.push(effect[0])}
  224.   end
  225.   def self::[](key)
  226.     return @@buffer[key]
  227.   end
  228.   def self.push(key)
  229.     return if @@buffer.keys.include?(key)
  230.     @@buffer[key] = Cache.light(key)
  231.   end
  232. end
  233. Light_Bitcore.initialize
  234. class Light_SSource
  235.   attr_reader :real_x
  236.   attr_reader :real_y
  237.   attr_reader :range
  238.   attr_accessor :bitmap
  239.   attr_reader :w
  240.   attr_reader :h
  241.   attr_reader :hs
  242.   def initialize(char,bitmap,opacity,plus,hs)
  243.     sync(char)
  244.     @key = bitmap
  245.     @bitmap = Light_Bitcore[@key].clone
  246.     @range = @bitmap.width/2
  247.     @w = @bitmap.width
  248.     @h = @bitmap.height
  249.     @mr = @range - 16
  250.     @opacity = opacity
  251.     @plus = plus
  252.     @hs = hs
  253.     render if @hs
  254.   end
  255.   def render
  256.     tx = x
  257.     ty = y
  258.     tsx = x + @range
  259.     tsy = y + @range
  260.     dr = @range*2
  261.     for s in $game_map.surfaces
  262.       next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr)
  263.       s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap)
  264.     end
  265.   end
  266.   def restore
  267.     return unless @bitmap.nil?
  268.     @bitmap = Light_Bitcore[@key].clone
  269.     render if @hs
  270.   end
  271.   def opacity
  272.     @plus == 0 ? @opacity : (@opacity + rand(@plus))
  273.   end
  274.   def sx
  275.     return $game_map.adjust_x(@real_x)*32-@mr
  276.   end
  277.   def sy
  278.     return $game_map.adjust_y(@real_y)*32-@mr
  279.   end
  280.   def sync(char)
  281.     @real_x = char.real_x
  282.     @real_y = char.real_y
  283.   end
  284.   def x
  285.     return (@real_x*32 - @mr).to_f
  286.   end
  287.   def y
  288.     return (@real_y*32 - @mr).to_f
  289.   end
  290.   def dispose
  291.     return if @bitmap.nil?
  292.     @bitmap.dispose
  293.     @bitmap = nil
  294.   end
  295. end
  296. class Light_DSource < Light_SSource
  297.   attr_reader :bitmap
  298.   attr_reader :visible
  299.   def initialize
  300.     @key = nil
  301.     @bitmap = nil
  302.     @opacity = 255
  303.     @plus = 0
  304.     @char = $game_player
  305.     @visible = false
  306.   end
  307.   def set_opacity(o,p)
  308.     @opacity = o
  309.     @plus = p
  310.   end
  311.   def set_graphic(sb)
  312.     dispose
  313.     @key = {2=>sb,4=>sb,6=>sb,8=>sb}
  314.     Light_Bitcore.push(sb)
  315.     @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}
  316.     @range = @bitmap[2].width/2
  317.     @w = @bitmap[2].width
  318.     @h = @bitmap[2].height
  319.     @mr = @range - 16
  320.   end
  321.   def set_multiple_graphics(ba)
  322.     dispose
  323.     @key = ba
  324.     @key.values.each {|key| Light_Bitcore.push(key)}
  325.     @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}
  326.     @range = @bitmap[2].width/2
  327.     @w = @bitmap[2].width
  328.     @h = @bitmap[2].height
  329.     @mr = @range - 16
  330.   end
  331.   def get_graphic
  332.     return @bitmap[@char.direction].clone
  333.   end
  334.   def show
  335.     return if @bitmap.nil?
  336.     @visible = true
  337.   end
  338.   def hide
  339.     @visible = false
  340.   end
  341.   def restore
  342.     return if @key.nil?
  343.     @key.values.each {|key| Light_Bitcore.push(key)}
  344.     @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}
  345.   end
  346.   def dispose
  347.     return if @bitmap.nil?
  348.     @bitmap.values.each { |b| b.dispose }
  349.     @bitmap = nil
  350.   end
  351.   def change_owner(char)
  352.     @char = char
  353.   end
  354.   def render
  355.   end
  356.   def sx
  357.     return $game_map.adjust_x(@char.real_x)*32-@mr
  358.   end
  359.   def sy
  360.     return $game_map.adjust_y(@char.real_y)*32-@mr
  361.   end
  362.   def x
  363.     return (@char.real_x*32 - @mr).to_f
  364.   end
  365.   def y
  366.     return (@char.real_y*32 - @mr).to_f
  367.   end
  368. end
  369. class Light_Surface
  370.   def initialize
  371.     @ta = @a = 0
  372.     @tr = @r = 255
  373.     @tg = @g = 255
  374.     @tb = @b = 255
  375.     @va = @vr = @vg = @vb = 0.0
  376.     @timer = 0
  377.   end
  378.   def refresh
  379.     return if @timer == 0
  380.     @a += @va
  381.     @r += @vr
  382.     @g += @vg
  383.     @b += @vb
  384.     $game_map.light_surface.opacity = @a
  385.     @timer -= 1
  386.   end
  387.   def change_color(time,r,g,b,a=nil)
  388.     r = 0 if r < 0; r = 255 if r > 255
  389.     g = 0 if g < 0; g = 255 if g > 255
  390.     b = 0 if b < 0; b = 255 if b > 255
  391.     unless a.nil?
  392.       a = 0 if a < 0; a = 255 if a > 255
  393.     end
  394.     @timer = time
  395.     @tr = 255-r
  396.     @tg = 255-g
  397.     @tb = 255-b
  398.     @va = (a.nil? ? 0 : (a-@a).to_f/@timer)
  399.     @vr = (@tr - @r).to_f/@timer
  400.     @vg = (@tg - @g).to_f/@timer
  401.     @vb = (@tb - @b).to_f/@timer
  402.   end
  403.   def change_alpha(time,a)
  404.     a = 0 if a < 0; a = 255 if a > 255
  405.     @timer = time
  406.     @ta = a
  407.     @vr = @vg = @vb = 0.0
  408.     @va = (a-@a).to_f/@timer
  409.   end
  410.   def set_color(r,g,b)
  411.     r = 0 if r < 0; r = 255 if r > 255
  412.     g = 0 if g < 0; g = 255 if g > 255
  413.     b = 0 if b < 0; b = 255 if b > 255
  414.     @tr = @r = 255-r
  415.     @tg = @g = 255-g
  416.     @tb = @b = 255-b
  417.     @va = @vr = @vg = @vb = 0.0
  418.     @timer = 0
  419.   end
  420.   def set_alpha(a)
  421.     a = 0 if a < 0; a = 255 if a > 255
  422.     @ta = @a = a
  423.     $game_map.light_surface.opacity = @a
  424.     @va = @vr = @vg = @vb = 0.0
  425.     @timer = 0
  426.   end
  427.   def alpha
  428.     return @a
  429.   end
  430.   def color
  431.     return Color.new(@r,@g,@b)
  432.   end
  433. end
  434. class Game_Map
  435.   include Light_Core
  436.   attr_accessor :light_surface
  437.   attr_accessor :light_sources
  438.   attr_accessor :surfaces
  439.   attr_accessor :effect_surface
  440.   attr_accessor :lantern
  441.   alias kbl_setup_events setup_events
  442.   alias kbl_initialize initialize
  443.   alias kbl_update update
  444.   def initialize
  445.     kbl_initialize
  446.     @effect_surface = Light_Surface.new
  447.     @lantern = Light_DSource.new
  448.   end
  449.   def update(arg)
  450.     @effect_surface.refresh if arg
  451.     kbl_update(arg)
  452.   end
  453.   def first_tag(x,y)
  454.     tag = tileset.flags[tile_id(x,y,0)] >> 12
  455.     return tag > 0 ? tag : 0
  456.   end
  457.   def setup_events
  458.     @light_sources.nil? ? @light_sources = [] : @light_sources.clear
  459.     setup_surfaces
  460.     merge_surfaces
  461.     kbl_setup_events
  462.   end
  463.   def setup_surfaces
  464.     @surfaces = []
  465.     for x in 0..(width-1)
  466.       for y in 0..(height-1)
  467.         tag = first_tag(x,y)
  468.         if tag == Wall_Tag
  469.           i = tile_id(x,y,0)
  470.           if i & 0x02 == 0x02
  471.             @surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32)
  472.           end
  473.           if i & 0x04 == 0x04
  474.             @surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32)
  475.             @surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32)
  476.           end
  477.           if i & 0x01 == 0x01
  478.             @surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32)
  479.             @surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32)
  480.           end
  481.         elsif tag == Roof_Tag
  482.           i = tile_id(x,y,0)
  483.           @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if i & 0x02 == 0x02
  484.           @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if i & 0x04 == 0x04
  485.           @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if i & 0x01 == 0x01
  486.         elsif tag == Block_Tag
  487.           f = tileset.flags[tile_id(x,y,0)]
  488.           @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if f & 0x02 == 0x02
  489.           @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if f & 0x04 == 0x04
  490.           @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if f & 0x08 == 0x08
  491.         end
  492.       end
  493.     end
  494.   end
  495.   def merge_surfaces
  496.     new_surfaces = []
  497.     hs = []; vs = []
  498.     ws = []; is = []
  499.     for surface in @surfaces
  500.       if surface.type & 0x05 == 0
  501.         hs << surface
  502.       else
  503.         if surface.type & 0x010 == 0
  504.           vs << surface
  505.         else
  506.           if surface.type & 0x08 == 0
  507.             ws << surface
  508.           else
  509.             is << surface
  510.           end
  511.         end
  512.       end
  513.     end
  514.     for surface in hs
  515.       surface.ready ? next : surface.ready = true
  516.       for s in hs
  517.         next if s.ready || s.y1 != surface.y1 || surface.type != s.type
  518.         if s.x2 == surface.x1
  519.           surface.x1 = s.x1
  520.           s.trash = true
  521.           s.ready = true
  522.           surface.ready = false
  523.         elsif s.x1 == surface.x2
  524.           surface.x2 = s.x2
  525.           s.trash = true
  526.           s.ready = true
  527.           surface.ready = false
  528.         end
  529.       end
  530.     end
  531.     hs.each { |s| @surfaces.delete(s) if s.trash}
  532.     for surface in vs
  533.       surface.ready ? next : surface.ready
  534.       for s in vs
  535.         next if s.ready || s.x1 != surface.x1
  536.         if s.y2 == surface.y1
  537.           surface.y1 = s.y1
  538.           s.trash = true
  539.           s.ready = true
  540.           surface.ready = false
  541.         elsif s.y1 == surface.y2
  542.           surface.y2 = s.y2
  543.           s.trash = true
  544.           s.ready = true
  545.           surface.ready = false
  546.         end
  547.       end
  548.     end
  549.     vs.each { |s| @surfaces.delete(s) if s.trash}
  550.     for surface in ws
  551.       surface.ready ? next : surface.ready
  552.       for s in ws
  553.         next if s.ready || s.x1 != surface.x1
  554.         if s.y2 == surface.y1
  555.           surface.y1 = s.y1
  556.           s.trash = true
  557.           s.ready = true
  558.           surface.ready = false
  559.         elsif s.y1 == surface.y2
  560.           surface.y2 = s.y2
  561.           s.trash = true
  562.           s.ready = true
  563.           surface.ready = false
  564.         end
  565.       end
  566.     end
  567.     ws.each { |s| @surfaces.delete(s) if s.trash}
  568.     for surface in is
  569.       surface.ready ? next : surface.ready
  570.       for s in is
  571.         next if s.ready || s.x1 != surface.x1
  572.         if s.y2 == surface.y1
  573.           surface.y1 = s.y1
  574.           s.trash = true
  575.           s.ready = true
  576.           surface.ready = false
  577.         elsif s.y1 == surface.y2
  578.           surface.y2 = s.y2
  579.           s.trash = true
  580.           s.ready = true
  581.           surface.ready = false
  582.         end
  583.       end
  584.     end
  585.     is.each { |s| @surfaces.delete(s) if s.trash}
  586.   end
  587. end
  588. class Game_Event < Game_Character
  589.   alias kbl_initialize initialize
  590.   alias kbl_setup_page setup_page
  591.   def initialize(m,e)
  592.     @light = nil
  593.     kbl_initialize(m,e)
  594.   end
  595.   def setup_page(np)
  596.     kbl_setup_page(np)
  597.     setup_light(np.nil?)
  598.   end
  599.   def setup_light(dispose)
  600.     unless @light.nil?
  601.       $game_map.light_sources.delete(self)
  602.       @light.dispose
  603.       @light = nil
  604.     end
  605.     unless dispose && @list.nil?
  606.       for command in @list
  607.         if command.code == 108 && command.parameters[0].include?("[light")
  608.           command.parameters[0].scan(/\[light ([0.0-9.9]+)\]/)
  609.           effect = Light_Core::Effects[$1.to_i]
  610.           @light = Light_SSource.new(self,effect[0],effect[1],effect[2],effect[3])
  611.           $game_map.light_sources << self
  612.           return
  613.         end
  614.       end
  615.     end
  616.   end
  617.   def draw_light
  618.     sx = @light.sx
  619.     sy = @light.sy
  620.     w = @light.w
  621.     h = @light.h
  622.     return if sx > 544 && sy > 416 && sx + w < 0 && sy + h < 0
  623.     $game_map.light_surface.bitmap.blt(sx,sy,@light.bitmap,Rect.new(0,0,w,h),@light.opacity)
  624.   end
  625.   def dispose_light
  626.     @light.dispose
  627.   end
  628.   def restore_light
  629.     @light.restore
  630.   end
  631. end
  632. if Light_Core::Surface_UE
  633.   class Game_Interpreter
  634.     def command_223
  635.       $game_map.effect_surface.change_color(@params[1],@params[0].red,@params[0].green,@params[0].blue,@params[0].gray)
  636.       wait(@params[1]) if @params[2]
  637.     end
  638.   end
  639. end
  640. class Game_Interpreter
  641.   def self_event
  642.     return $game_map.events[@event_id]
  643.   end
  644. end
  645. class Block_Surface
  646.   include Light_Core
  647.   attr_accessor :x1
  648.   attr_accessor :y1
  649.   attr_accessor :x2
  650.   attr_accessor :y2
  651.   attr_accessor :ready
  652.   attr_accessor :trash
  653.   def initialize(x1,y1,x2,y2)
  654.     @x1 = x1
  655.     @y1 = y1
  656.     @x2 = x2
  657.     @y2 = y2
  658.     @ready = false
  659.     @trash = false
  660.   end
  661.   def within?(min_x,max_x,min_y,max_y)
  662.     return @x2 > min_x && @x1 < max_x && @y2 > min_y && @y1 < max_y
  663.   end
  664. end
  665. class Block_SL < Block_Surface
  666.   attr_reader :type
  667.   def initialize(x1,y1,x2,y2)
  668.     super(x1,y1,x2,y2)
  669.     @type = 0x01
  670.   end
  671.   def visible?(sx,sy)
  672.     return sx < @x1
  673.   end
  674.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  675.     @m1 = (@y1-sy)/(@x1-sx)
  676.     @n1 = sy - @m1*sx
  677.     @m2 = (@y2-sy)/(@x2-sx)
  678.     @n2 = sy - @m2*sx
  679.     for x in @x1..(sx+range)
  680.       init = shadow_iy(x)
  681.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
  682.     end
  683.   end
  684.   def shadow_iy(x)
  685.     return @m1*x+@n1
  686.   end
  687.   def shadow_fy(x)
  688.     return @m2*x+@n2
  689.   end
  690. end
  691. class Block_SR < Block_Surface
  692.   attr_reader :type
  693.   def initialize(x1,y1,x2,y2)
  694.     super(x1,y1,x2,y2)
  695.     @type = 0x04
  696.   end
  697.   def visible?(sx,sy)
  698.     return sx > @x1
  699.   end
  700.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  701.     @m1 = (@y1-sy)/(@x1-sx)
  702.     @n1 = sy - @m1*sx
  703.     @m2 = (@y2-sy)/(@x2-sx)
  704.     @n2 = sy - @m2*sx
  705.     for x in (sx-range).to_i..@x1
  706.       init = shadow_iy(x)
  707.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
  708.     end
  709.   end
  710.   def shadow_iy(x)
  711.     return @m1*x+@n1
  712.   end
  713.   def shadow_fy(x)
  714.     return @m2*x+@n2
  715.   end
  716. end
  717. class Block_IL < Block_Surface
  718.   attr_reader :type
  719.   def initialize(x1,y1,x2,y2)
  720.     super(x1,y1,x2,y2)
  721.     @type = 0x019
  722.   end
  723.   def visible?(sx,sy)
  724.     return sx < @x1 && sy > @y1
  725.   end
  726.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  727.     @m1 = (@y1-sy)/(@x1-sx)
  728.     @n1 = @y1 - @m1*@x1
  729.     @m2 = (@y2-sy)/(@x2-sx)
  730.     @m2 = 0 if @m2 > 0
  731.     @n2 = @y2 - @m2*@x2
  732.     for x in @x1..(sx+range)
  733.       init = shadow_iy(x).floor
  734.       bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
  735.     end
  736.   end
  737.   def shadow_iy(x)
  738.     return @m1*x+@n1
  739.   end
  740.   def shadow_fy(x)
  741.     return @m2*x+@n2
  742.   end
  743. end
  744. class Block_IR < Block_Surface
  745.   attr_reader :type
  746.   def initialize(x1,y1,x2,y2)
  747.     super(x1,y1,x2,y2)
  748.     @type = 0x01c
  749.   end
  750.   def visible?(sx,sy)
  751.     return sx > @x1 && sy > @y1
  752.   end
  753.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  754.     @m1 = (@y1-sy)/(@x1-sx)
  755.     @n1 = @y1 - @m1*@x1
  756.     @m2 = (@y2-sy)/(@x2-sx)
  757.     @m2 = 0 if @m2 < 0
  758.     @n2 = @y2 - @m2*@x2
  759.     for x in (sx-range).to_i..@x1
  760.       init = shadow_iy(x).floor
  761.       bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
  762.     end
  763.   end
  764.   def shadow_iy(x)
  765.     return @m1*x+@n1
  766.   end
  767.   def shadow_fy(x)
  768.     return @m2*x+@n2
  769.   end
  770. end
  771. class Block_WL < Block_Surface
  772.   attr_reader :type
  773.   def initialize(x1,y1,x2,y2)
  774.     super(x1,y1,x2,y2)
  775.     @type = 0x011
  776.   end
  777.   def visible?(sx,sy)
  778.     return sx < @x1 && sy < @y2
  779.   end
  780.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  781.     @m1 = (@y1-sy)/(@x1-sx)
  782.     @n1 = sy - @m1*sx
  783.     @m2 = (@y2-sy)/(@x2-sx)
  784.     @n2 = sy - @m2*sx
  785.     for x in @x1..(sx+range)
  786.       init = shadow_iy(x)
  787.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
  788.     end
  789.   end
  790.   def shadow_iy(x)
  791.     return @m1*x+@n1
  792.   end
  793.   def shadow_fy(x)
  794.     return @m2*x+@n2
  795.   end
  796. end
  797. class Block_WR < Block_Surface
  798.   attr_reader :type
  799.   def initialize(x1,y1,x2,y2)
  800.     super(x1,y1,x2,y2)
  801.     @type = 0x014
  802.   end
  803.   def visible?(sx,sy)
  804.     return sx > @x1 && sy < @y2
  805.   end
  806.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  807.     @m1 = (@y1-sy)/(@x1-sx)
  808.     @n1 = sy - @m1*sx
  809.     @m2 = (@y2-sy)/(@x2-sx)
  810.     @n2 = sy - @m2*sx
  811.     for x in (sx-range).to_i..@x1
  812.       init = shadow_iy(x)
  813.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
  814.     end
  815.   end
  816.   def shadow_iy(x)
  817.     return @m1*x+@n1
  818.   end
  819.   def shadow_fy(x)
  820.     return @m2*x+@n2
  821.   end
  822. end
  823. class Block_SU < Block_Surface
  824.   attr_reader :type
  825.   def initialize(x1,y1,x2,y2)
  826.     super(x1,y1,x2,y2)
  827.     @type = 0x02
  828.   end
  829.   def visible?(sx,sy)
  830.     return sy < @y1
  831.   end
  832.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  833.     if @x1 == sx
  834.       @m1 = nil
  835.     else
  836.       @m1 = (@y1-sy)/(@x1-sx)
  837.       @m1 += ACC if @m1 < -ACC
  838.       @n1 = @y1 - @m1*@x1
  839.     end
  840.     if @x2 == sx
  841.       @m2 = nil
  842.     else
  843.       @m2 = (@y2-sy)/(@x2-sx)
  844.       @n2 = sy - @m2*sx
  845.     end
  846.     for y in @y1..(sy+range)
  847.       init = shadow_ix(y)
  848.       bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
  849.     end
  850.   end
  851.   def shadow_ix(y)
  852.     return @m1.nil? ? @x1 : (y-@n1)/@m1
  853.   end
  854.   def shadow_fx(y)
  855.     return @m2.nil? ? @x2 : (y-@n2)/@m2
  856.   end
  857. end
  858. class Block_SD < Block_Surface
  859.   attr_reader :type
  860.   def initialize(x1,y1,x2,y2)
  861.     super(x1,y1,x2,y2)
  862.     @type = 0x08
  863.   end
  864.   def visible?(sx,sy)
  865.     return sy > @y1
  866.   end
  867.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  868.     if @x1 == sx
  869.       @m1 = nil
  870.     else
  871.       @m1 = (@y1-sy)/(@x1-sx)
  872.       @m1 -= ACC if @m1 > ACC
  873.       @n1 = sy - @m1*sx
  874.     end
  875.     if x2 == sx
  876.       @m2 = nil
  877.     else
  878.       @m2 = (@y2-sy)/(@x2-sx)
  879.       @n2 = sy - @m2*sx
  880.     end
  881.     for y in (sy-range).to_i..@y1
  882.       init = shadow_ix(y)
  883.       bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
  884.     end
  885.   end
  886.   def shadow_ix(y)
  887.     return @m1.nil? ? @x1 : (y-@n1)/@m1
  888.   end
  889.   def shadow_fx(y)
  890.     return @m2.nil? ? @x2 : (y-@n2)/@m2
  891.   end
  892. end
  893. class Spriteset_Map
  894.   include Light_Core
  895.   alias kbl_initialize initialize
  896.   alias kbl_update update
  897.   alias kbl_dispose dispose
  898.   def initialize
  899.     setup_lights
  900.     kbl_initialize
  901.   end
  902.   def update
  903.     kbl_update
  904.     update_lights
  905.   end
  906.   def dispose
  907.     kbl_dispose
  908.     dispose_lights
  909.   end
  910.   def dispose_lights
  911.     $game_map.lantern.dispose
  912.     $game_map.light_sources.each { |source| source.dispose_light }
  913.     $game_map.light_surface.bitmap.dispose
  914.     $game_map.light_surface.dispose
  915.     $game_map.light_surface = nil
  916.   end
  917.   def update_lights
  918.     $game_map.light_surface.bitmap.clear
  919.     $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)
  920.     $game_map.light_sources.each { |source| source.draw_light }
  921.     return unless $game_map.lantern.visible
  922.     @btr = $game_map.lantern.get_graphic
  923.     x = $game_map.lantern.x
  924.     y = $game_map.lantern.y
  925.     r = $game_map.lantern.range
  926.     sx = x + r
  927.     sy = y + r
  928.     dr = r*2
  929.     $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) }
  930.     $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)
  931.   end
  932.   def setup_lights
  933.     @btr = nil
  934.     $game_map.lantern.restore
  935.     $game_map.light_sources.each { |source| source.restore_light }
  936.     $game_map.light_surface = Sprite.new
  937.     $game_map.light_surface.bitmap = Bitmap.new(544,416)
  938.     $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)
  939.     $game_map.light_surface.blend_type = 2
  940.     $game_map.light_surface.opacity = $game_map.effect_surface.alpha
  941.     $game_map.light_surface.z = Surface_Z
  942.   end
  943. end
复制代码

评分

参与人数 1+1 收起 理由
淡淡一杯冷咖啡 + 1 塞糖

查看全部评分

VA外站脚本汉化群:226308173   |    部分远古文件备份:https://wwzv.lanzoue.com/b02rac5pc  密码:acgm
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3559
在线时间
2337 小时
注册时间
2015-8-25
帖子
960

开拓者

3
发表于 2018-8-23 12:59:05 | 只看该作者
前面那段英文就是教程。
khas主页有个配套的范例工程。

回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
465
在线时间
34 小时
注册时间
2018-7-26
帖子
37
4
 楼主| 发表于 2018-8-23 21:25:37 | 只看该作者
七重 发表于 2018-8-23 12:59
前面那段英文就是教程。
khas主页有个配套的范例工程。

谢谢,这我知道。但是当时机翻出来很混乱,也出现了一堆莫名奇妙的冲突,所以想要个有图文的教程。
我会去khas的主页看下范例工程的
个人现代风游戏制作中。
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3559
在线时间
2337 小时
注册时间
2015-8-25
帖子
960

开拓者

5
发表于 2018-8-23 22:32:38 | 只看该作者
Blois233 发表于 2018-8-23 21:25
谢谢,这我知道。但是当时机翻出来很混乱,也出现了一堆莫名奇妙的冲突,所以想要个有图文的教程。
我会 ...

这样啊。。

话说我觉得灯光脚本里面半生那个也挺好用的,要说的话,说不定论坛里面比较多人用的是这个。
khas里面有个方便的手电筒功能,如果是半生的话手电筒要自己写脚本。
半生的光效是正片叠底的。(虽然我也没有分出来和khas那个有什么大的区别。)

https://rpg.blue/forum.php?mod=v ... 0782&highlight=烛光脚本
回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
465
在线时间
34 小时
注册时间
2018-7-26
帖子
37
6
 楼主| 发表于 2018-8-24 18:11:01 | 只看该作者
七重 发表于 2018-8-23 22:32
这样啊。。

话说我觉得灯光脚本里面半生那个也挺好用的,要说的话,说不定论坛里面比较多人用的是这个。 ...

试过半生的。。事实上以前都在用半生的
但是好像做不出影子的效果?(雾)
而且动态光源也还khas的稍微好一点

点评

哦 对哦 刚打开工程看了下,khas还有个自动的影子。不过半生的不嫌麻烦其实可以自己做影子,描画大图片的效率貌似还高很多,因为有外部DLL。  发表于 2018-8-24 21:22
个人现代风游戏制作中。
回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
899
在线时间
5 小时
注册时间
2016-8-1
帖子
1
7
发表于 2018-8-25 14:19:53 | 只看该作者
范例教程网址在哪啊?
回复

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
116
在线时间
20 小时
注册时间
2020-2-18
帖子
13
8
发表于 2020-3-12 20:06:42 | 只看该作者
为什么我注释了[light 1】用不出来呀,大佬求解
回复

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-19 14:15

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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