搜索附件  
同能RPG制作大师 附件中心 同能RM技术讨论区 RPG Maker XP 讨论区 重写“半生烛光”: Light.zip

重写“半生烛光”: Light.zip

 

重写“半生烛光”:
整体还是很鸡肋,效果基本没变化,懒得做gif示意图了。
烛火可以自定义颜色,支持不透明度变化实现明暗变化,API效率提升,代码是关于灯光效果的实现,关于交互自行修改添加吧。
Light.dll  VS2017 C语言编写

RUBY 代码
  1. class Rect
  2.   def to_int
  3.     self.__id__
  4.   end
  5. end
  6. class Bitmap
  7.   def to_int
  8.     self.__id__
  9.   end
  10. end
  11. module LIGHT
  12.   # 并不严谨的标志,但是方便
  13.   Flag = "set_light"
  14.   Pic_Dir = "Graphics/Light_Textures"
  15.   # 透明通道图片,有效值为alpha,填充的颜色能看清图形就好,建议黑色
  16.   Light_Type_Pic_Name = {
  17.     0 => "round.png"
  18.   }
  19.   Light_Effect_Rect_Frame = 10
  20.   dll = "Light.dll"
  21.   # 源位图双线性插值缩放至目标位图(无混合)
  22.   # dst_bitmap_obj_id, src_bitmap_obj_id
  23.   Stretch = Win32API.new(dll, 'bitmap_stretch_move', 'LL', 'L')
  24.   # ————灯光专用方法————
  25.   # 以纹理的alpha值进行颜色填充,再与黑色(0xFF000000)进行混合(Bitmap#blt)
  26.   # alpha: 0       16
  27.     @min_alpha = (alpha_dinx & 0xFF00) >> 8
  28.     @max_alpha = alpha_dinx & 0xFF
  29.     if@min_alpha > @max_alpha
  30.       @min_alpha, @max_alpha = @max_alpha, @min_alpha
  31.     end
  32.   end
  33.   def display_at(target_bitmap)
  34.     self.alpha_update
  35.     returnif@alpha == 0
  36.     dx = (@event.real_x - $game_map.display_x + 3) / 4 + @off_x
  37.     returnif dx >= target_bitmap.width            #left
  38.     returnif dx + @src_rect.width - 1 = target_bitmap.height           #top
  39.     returnif dy + @src_rect.height - 1  @max_alpha
  40.         @alpha, @delta_alpha = @max_alpha, -@delta_alpha
  41.       end
  42.       if@alpha < @min_alpha
  43.         @alpha, @delta_alpha = @min_alpha, -@delta_alpha
  44.       end
  45.     end
  46.   end
  47.   def src_rect_update
  48.     if@rect_active == true
  49.       @src_rect.x += @src_rect.width
  50.       @src_rect.x = 0if@src_rect.x >= @bitmap.width
  51.     end
  52.   end
  53.   def bitmap_dispose
  54.     @bitmap.dispose
  55.   end
  56. end
  57. class LightRenderTarget
  58.   def initialize(viewport)
  59.     @alpha = -1
  60.     self.alpha = 128
  61.     returnif$game_map.light_switch == false
  62.     @rt = Sprite.new(viewport)
  63.     @target = Bitmap.new(viewport.rect.width, viewport.rect.height)
  64.     @rt.bitmap = @target
  65.     @rt.blend_type = 2
  66.     @rt.z = 1000
  67.   end
  68.   def alpha=(new_alpha)
  69.     returnif@alpha == new_alpha
  70.     @alpha = new_alpha < 0 ? 0 : (new_alpha > 255 ? 255 : new_alpha)
  71.   end
  72.   def update
  73.     returnif$game_map.light_switch == false
  74.     returnif@alpha == 0
  75.     if Graphics.frame_count % LIGHT::Light_Effect_Rect_Frame == 0
  76.       $game_map.light_data.each{|i| i.src_rect_update}  
  77.     end
  78.     LIGHT::Full.call(@target, @alpha)   
  79.     $game_map.light_data.each{|i| i.display_at(@target)}
  80.   end
  81.   def dispose
  82.     if@target != nil
  83.       @target.dispose
  84.       @rt.dispose
  85.       @target = nil
  86.     end
  87.     LIGHT.cache_clear
  88.   end
  89. end
  90. class Interpreter
  91.   includeLIGHT::Macro
  92. end
  93. class Game_Player
  94.   includeLIGHT::Interface
  95.   def light_on(*args)
  96.     @light_data ||= []
  97.     self.set_light(*args)
  98.   end
  99.   # 其实类似手电筒,根据方向调整 center_type, off_x, off_y, cell_idx就可以实现
  100. end
  101. #———以下代码有大部分RMXP原代码,建议直接添加至原代码———
  102. class Game_Map
  103.   attr_reader   :light_data
  104.   attr_reader   :light_switch
  105.   #--------------------------------------------------------------------------
  106.   # ● 初始化条件
  107.   #--------------------------------------------------------------------------
  108.   def initialize
  109.     @map_id = 0
  110.     @display_x = 0
  111.     @display_y = 0
  112.     @light_data = []
  113.     @light_switch = false
  114.   end
  115.   #--------------------------------------------------------------------------
  116.   # ● 设置
  117.   #     map_id : 地图 ID
  118.   #--------------------------------------------------------------------------
  119.   def setup(map_id)
  120.     # 地图 ID 记录到 @map_id
  121.     @map_id = map_id
  122.     # 地图文件装载后、设置到 @map
  123.     @map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
  124.     # 定义实例变量设置地图元件信息
  125.     tileset = $data_tilesets[@map.tileset_id]
  126.     @tileset_name = tileset.tileset_name
  127.     @autotile_names = tileset.autotile_names
  128.     @panorama_name = tileset.panorama_name
  129.     @panorama_hue = tileset.panorama_hue
  130.     @fog_name = tileset.fog_name
  131.     @fog_hue = tileset.fog_hue
  132.     @fog_opacity = tileset.fog_opacity
  133.     @fog_blend_type = tileset.fog_blend_type
  134.     @fog_zoom = tileset.fog_zoom
  135.     @fog_sx = tileset.fog_sx
  136.     @fog_sy = tileset.fog_sy
  137.     @battleback_name = tileset.battleback_name
  138.     @passages = tileset.passages
  139.     @priorities = tileset.priorities
  140.     @terrain_tags = tileset.terrain_tags
  141.     # 初始化显示坐标
  142.     @display_x = 0
  143.     @display_y = 0
  144.     # 清除刷新要求标志
  145.     @need_refresh = false
  146.     # 释放上一地图的灯光对象
  147.     @light_data.each{|i| i.bitmap_dispose}
  148.     @light_data.clear
  149.     # 设置地图事件数据
  150.     @events = {}
  151.     for i in@map.events.keys
  152.       @events[i] = Game_Event.new(@map_id, @map.events[i])
  153.     end
  154.     @light_switch = !@light_data.empty?
  155.     # 设置公共事件数据
  156.     @common_events = {}
  157.     for i in1...$data_common_events.size
  158.       @common_events[i] = Game_CommonEvent.new(i)
  159.     end
  160.     # 初始化雾的各种信息
  161.     @fog_ox = 0
  162.     @fog_oy = 0
  163.     @fog_tone = Tone.new(0, 0, 0, 0)
  164.     @fog_tone_target = Tone.new(0, 0, 0, 0)
  165.     @fog_tone_duration = 0
  166.     @fog_opacity_duration = 0
  167.     @fog_opacity_target = 0
  168.     # 初始化滚动信息
  169.     @scroll_direction = 2
  170.     @scroll_rest = 0
  171.     @scroll_speed = 4
  172.   end
  173. end
  174. class Game_Event
  175.   includeLIGHT::Macro
  176.   includeLIGHT::Interface
  177.   # !!注释即代码,不能乱写!!
  178.   # 只在“第一个指令块”有效。
  179.   # 标志:事件当前页的第一条指令set_light(...);
  180.   def refresh_light
  181.     if@list
  182.       if@list[0].code == 108
  183.         if(params = @list[0].parameters[0]).include?(LIGHT::Flag)
  184.           i, scripts = 1, params.dup
  185.           while(@list[i].code == 408)
  186.             scripts  XP) 脚本 tktk_bitmap.dll 替换成 Light.dll,原工程自行下载。
  187. RUBY 代码
  188. [code]=begin
  189.   HN_Light version 1.0.1.0 for VX Ace
  190.         by 半生
  191. [url]http://www.tktkgame.com[/url]
  192.   要HN_RG_BITMAP(ver 0.1.2.1以降)
  193. 2012/01/08 ver 1.0.1.2
  194.  队列歩行の仲间に対応
  195. 2015/04/25 Xp移植(ver 1.0)
  196.   By RyanBern
  197. 2015/12/20 ver 1.1
  198.   Z 坐标修正 && 战斗测试 BUG 修复
  199. 2018/02/11 ver 1.2
  200.   增加控制黑暗不透明度的变量
  201. =end
  202. # 注释掉的为原代码,替换代码都比原代码快
  203. class Bitmap; def to_int; self.__id__; end; end
  204. class Rect; def to_int; self.__id__; end; end
  205. # ----- 在这里设定-----
  206. module HN_Light
  207.   # 简略化0:(精细)~2:(粗暴,负荷轻)
  208.   SIMPLIFY = 2
  209.   # 表示黑暗处的不透明度的变量号码
  210.   # 变量的数值为0-255,越大则不可见度越高
  211.   DARK_OPACITY_VAR = 11
  212.   # 玩家的烛光类型使用的变量号码
  213.   PLAYER_LIGHT_TYPE = 12
  214.   # 黑暗判断上使用的开关
  215.   DARK_SWITCH = 11
  216.   # 烛光事件识别用的正规表达式
  217.   REGEX_LIGHT = /@LIGHT(\d+)/
  218.   # 烛光图像的目录
  219.   LIGHT_IMG_DIR = "Graphics/Pictures/"
  220.   # 烛光Bitmap设定
  221.   LIGHTS = [
  222.   # [文件名  ,单元数, 放大率,  Y偏移值, 色相]
  223.     ["light1",     1,    2.0,        0,    0],
  224.     ["light2",     1,    1.0,        0,    0],
  225.     ["light3",     1,    0.8,        0,    0],
  226.     ["light4",     1,    1.0,      -16,    0],
  227.     ["light5",     1,    2.0,        0,    0],
  228.     ["light6",     1,    1.0,        0,    0],
  229.     ["light7",     1,    3.0,      -16,    0],
  230.     ["light1",     1,    0.5,        0,    0],
  231.     ["light6",     1,    2.0,        0,    0],
  232.   ]
  233.   dll = "Light.dll"
  234.   Stretch = Win32API.new(dll, 'bitmap_stretch_move', 'LL', 'L')
  235.   Mul = Win32API.new(dll, 'bitmap_light_mul', 'LLLLLL', 'L')
  236.   Full = Win32API.new(dll, 'bitmap_full_white_alpha', 'LL', 'L')
  237. end
  238. #  ----- 在这里设定 -----
  239. module HN_Light
  240.   # 事件mix-in用
  241.   module LightEvent
  242.     attr_reader :light_type
  243.     def initialize
  244.       super()
  245.       @light_type = 0
  246.     end
  247.     def check_light
  248.       @light_type = 0
  249.       returnif@list.nil?
  250.       @list.eachdo |command|
  251.         breakif@light_type > 0
  252.         if command.code == 108or command.code == 408
  253.           command.parameters.eachdo |line|
  254.             if line =~ REGEX_LIGHT
  255.               @light_type = $1.to_i
  256.               break
  257.             end
  258.           end
  259.         end
  260.       end# END @list.each
  261.     end
  262.   end# END module LightEvent
  263.   class Light
  264.     attr_reader :bitmap
  265.     attr_reader :cells
  266.     attr_reader :width
  267.     attr_reader :height
  268.     attr_reader :ox
  269.     attr_reader :oy
  270.     def initialize(light_type, s_zoom = 1)
  271.       light = LIGHTS[light_type - 1]
  272.       if light.nil?
  273.         # 本来不应该来这里
  274.         @bitmap = Bitmap.new(32, 32)
  275.         @cells = 1
  276.         @zoom = 1.0
  277.         @oy = 16
  278.         @ox = 16
  279.         @width  = 32
  280.         @height = 32
  281.       else
  282.         @bitmap = Bitmap.new(LIGHT_IMG_DIR + light[0])
  283.         #@bitmap.invert()
  284.         @cells = light[1].to_i
  285.         @cells = 1if(@cells < 1or@cells > @bitmap.width)
  286.         @zoom = light[2].to_f
  287.         @zoom = 1.0if@zoom  0)
  288.         @light_events.push(event)
  289.       end
  290.     end
  291.   end
  292.   alias:_hn_light__setup_events:setupunless method_defined?(:_hn_light__setup_events)
  293.   def setup(map_id)
  294.     _hn_light__setup_events(map_id)
  295.     refresh_lights()if@map_id > 0
  296.   end
  297.   alias:_hn_light__refresh:refreshunless method_defined?(:_hn_light__refresh)
  298.   def refresh
  299.     _hn_light__refresh()
  300.     refresh_lights()if@map_id > 0
  301.   end
  302. end
  303. class Sprite_Dark < Sprite
  304.   @@base_color = Color.new(255,255,255,192)
  305.   def initialize(viewport = nil)
  306.     super(viewport)
  307.     @width = 640
  308.     @height = 480
  309.     caseHN_Light::SIMPLIFY
  310.     when1
  311.       @zoom = 2
  312.     when2
  313.       @zoom = 4
  314.     else
  315.       @zoom = 1
  316.     end
  317.     @width /= @zoom
  318.     @height /= @zoom
  319.     self.zoom_x = @zoom.to_f
  320.     self.zoom_y = @zoom.to_f
  321.     self.bitmap = Bitmap.new(@width, @height)
  322.     self.bitmap.fill_rect(self.bitmap.rect, @@base_color)
  323.     self.blend_type = 2# 混合型(减算)
  324.     self.z = 800
  325.     self.visible = false
  326.     @light_cache = {}
  327.   end
  328.   # 追加烛光
  329.   def add_light(charactor)
  330.     returnif charactor.nil?
  331.     light_type = charactor.light_type
  332.     returnif(light_type < 1or light_type > HN_Light::LIGHTS.size)
  333.     unless@light_cache.key?(light_type)
  334.       @light_cache[light_type] = HN_Light::Light.new(light_type, @zoom)
  335.     end
  336.     light = @light_cache[light_type]
  337.     # 画面外什麽都不做
  338.     if@zoom == 1
  339.       returnif(charactor.screen_x < 0  - light.width + light.ox)
  340.       returnif(charactor.screen_x > @width + light.ox)
  341.       returnif(charactor.screen_y < 0 - light.height + light.oy)
  342.       returnif(charactor.screen_y > @height + light.oy)
  343.     else
  344.       returnif(charactor.screen_x < 0  - (light.width + light.ox) * @zoom)
  345.       returnif(charactor.screen_x > (@width + light.ox)  * @zoom)
  346.       returnif(charactor.screen_y < 0 - (light.height + light.oy) * @zoom)
  347.       returnif(charactor.screen_y > (@height + light.oy) * @zoom)
  348.     end
  349.     # 动画判定
  350.     if light.cells > 1
  351.       index = (Graphics.frame_count / 4) % light.cells
  352.       rect = Rect.new(index * light.width , 0, light.width, light.height)
  353.     else
  354.       rect = light.bitmap.rect
  355.     end
  356.     if@zoom != 1
  357.       p_x = charactor.screen_x / @zoom - light.ox
  358.       p_y = (charactor.screen_y - 16) / @zoom - light.oy
  359.     else
  360.       p_x = charactor.screen_x - light.ox
  361.       p_y = charactor.screen_y - 16 - light.oy
  362.     end
  363.     # 乗算合成(3)
  364.     #self.bitmap.blend_blt(p_x, p_y, light.bitmap, rect, 3)
  365.     HN_Light::Mul.call(self.bitmap, p_x, p_y, light.bitmap, rect, 255)
  366.   end
  367.   def refresh
  368.     #self.bitmap.fill_rect(self.bitmap.rect, @@base_color)
  369.     HN_Light::Full.call(self.bitmap, @@base_color.alpha.to_i)
  370.     $game_map.light_events.eachdo |event|
  371.       nextifHN_Light::LIGHTS[event.light_type - 1].nil?
  372.       add_light(event)
  373.     end
  374.     add_light($game_player)
  375.   end
  376.   # 更新
  377.   def update
  378.     super
  379.     #@@base_color = Color.new(255, 255, 255, $game_variables[HN_Light::DARK_OPACITY_VAR])
  380.     @@base_color.alpha = $game_variables[HN_Light::DARK_OPACITY_VAR]
  381.     refresh()
  382.   end
  383.   #--------------------------------------------------------------------------
  384.   # ● 解放
  385.   #--------------------------------------------------------------------------
  386.   def dispose
  387.     self.bitmap.dispose
  388.     @light_cache.values.eachdo |light|
  389.       light.dispose
  390.     end
  391.     super
  392.   end
  393. end
  394. class Spriteset_Map  
  395.   # 动画判定
  396.   def create_dark
  397.     @dark_sprite = Sprite_Dark.new(@viewport1)
  398.   end
  399.   # 更新黑暗Sprite
  400.   def update_dark
  401.     if(@dark_sprite.visible = $game_switches[HN_Light::DARK_SWITCH])
  402.       @dark_sprite.update
  403.     end
  404.   end
  405.   # 破弃黑暗Sprite
  406.   def dispose_dark
  407.     @dark_sprite.dispose
  408.   end
  409.   # 初期化
  410.   alias:_dark__initialize:initializeunless private_method_defined?(:_dark__initialize)
  411.   def initialize
  412.     _dark__initialize()
  413.     create_dark()
  414.     update_dark()
  415.   end
  416.   # 更新
  417.   alias:_dark__update:updateunless method_defined?(:_dark__update)
  418.   def update
  419.     _dark__update()
  420.     update_dark()if !@dark_sprite.nil? and !@dark_sprite.disposed?
  421.   end
  422.   # 结束处理
  423.   alias:_dark__dispose:disposeunless method_defined?(:_dark__dispose)
  424.   def dispose
  425.     dispose_dark()
  426.     _dark__dispose()
  427.   end
  428. end
复制代码








             本帖来自P1论坛作者RPGzh500223,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=491685  若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
         同一主题附件:
    d1.png
    d2.png
    Light.zip (6.32 KB)
Loading...

QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

GMT+8, 2024-11-22 18:57 , Processed in 0.050839 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

返回顶部