扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 121|回复: 0

[转载发布] 重写“半生烛光”

[复制链接]
累计送礼:
0 个
累计收礼:
0 个
  • TA的每日心情
    开心
    2024-11-27 10:08
  • 签到天数: 108 天

    连续签到: 4 天

    [LV.6]常住居民II

    2229

    主题

    376

    回帖

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    6
    卡币
    9686
    OK点
    16
    推广点
    0
    同能卷
    0
    积分
    12319

    灌水之王

    发表于 2024-4-20 02:06:18 | 显示全部楼层 |阅读模式
    整体还是很鸡肋,效果基本没变化,懒得做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在线咨询功能删除,谢谢。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

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

    GMT+8, 2025-1-25 03:22 , Processed in 0.132758 second(s), 66 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

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