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

Project1

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

[原创发布] 装备变更行走图 Ace 版 附属脚本—— 染色与涂装

[复制链接]

Lv3.寻梦者

梦石
1
星屑
1174
在线时间
58 小时
注册时间
2023-9-8
帖子
35
跳转到指定楼层
1
发表于 2026-4-9 02:16:58 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
RUBY 代码复制
  1. #==============================================================================#
  2. #  ** 染色与涂装系统 —— 装备变更行走图 Ace 版 附属脚本
  3. #------------------------------------------------------------------------------#
  4. #  作者:MrRuigi
  5. #  功能:
  6. #    · 在物品备注中定义染料和涂装,通过菜单对已装备的武器/防具进行染色/涂装
  7. #    · 染色采用色相旋转(hue_change),仅改变非透明像素的色调,保持透明背景
  8. #    · 涂装采用正片叠底(Multiply)混合,平铺小图案,仅作用于装备非透明区域
  9. #    · 装备外观变化会实时反映在玩家行走图中
  10. #    · 无可用物品时自动返回上一级,避免卡操作感
  11. #==============================================================================#
  12.  
  13. #==============================================================================#
  14. # ■ 配置模块
  15. #==============================================================================#
  16. module FalDyePaint
  17.   # 菜单中显示的选项名称
  18.   COMMAND_NAME = "染色/涂装"
  19.  
  20.   # 操作音效
  21.   DYE_SE      = "Heal6"      # 染色成功
  22.   PAINT_SE    = "Item3"      # 涂装成功
  23.   CANCEL_SE   = "Cancel2"    # 取消操作
  24.   ERROR_SE    = "Buzzer1"    # 错误提示
  25.  
  26.   # 默认颜色(无染色时视为白色,不影响色调)
  27.   DEFAULT_COLOR = Color.new(255, 255, 255)
  28.  
  29.   # 预览窗口尺寸
  30.   PREVIEW_WIDTH  = 100
  31.   PREVIEW_HEIGHT = 100
  32.  
  33.   # 染色模式:true = 色相旋转(推荐),false = 像素颜色混合(旧版效果)
  34.   USE_HUE_CHANGE = true
  35.  
  36.   # 像素混合模式下的染色强度 (0-255),仅在 USE_HUE_CHANGE = false 时生效
  37.   DYE_OPACITY = 160
  38.  
  39.   # 涂装图片存放文件夹(相对于 Graphics 目录)
  40.   PAINTING_DIR = "Painting"
  41. end
  42.  
  43. #==============================================================================#
  44. # ■ 装备变更行走图相关配置
  45. #==============================================================================#
  46. module EquipDisplay
  47.   # 各个朝向对应的显示优先级,靠后的显示在最前
  48.   Priority = {
  49.     0 => [:body, :armor, :helmet, :weapon, :shield], # 下
  50.     1 => [:weapon, :body, :armor, :helmet, :shield], # 左
  51.     2 => [:shield, :body, :armor, :helmet, :weapon], # 右
  52.     3 => [:body, :weapon, :shield, :armor, :helmet]  # 上
  53.   }
  54. end
  55.  
  56. #==============================================================================#
  57. # ■ RPG::EquipItem (扩展)
  58. #==============================================================================#
  59. class RPG::EquipItem < RPG::BaseItem
  60.   # 获取此装备当前的染色颜色(从系统数据中读取)
  61.   def dye_color
  62.     $game_system.dye_data(self) rescue nil
  63.   end
  64.  
  65.   # 获取此装备当前的涂装图案文件名
  66.   def paint_pattern
  67.     $game_system.paint_data(self) rescue nil
  68.   end
  69.  
  70.   # 获取行走图装备备注中的图片名
  71.   def display_equip_part
  72.     @note =~ /<display.(\S+)>/
  73.     return $1
  74.   end
  75. end
  76.  
  77. #==============================================================================#
  78. # ■ RPG::Item (扩展)
  79. #==============================================================================#
  80. class RPG::Item < RPG::UsableItem
  81.   # 判断是否为染料物品,并返回解析出的颜色(Color 对象)
  82.   def dye_color
  83.     @note =~ /<染料:\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*>/i
  84.     return nil unless $1 && $2 && $3
  85.     Color.new($1.to_i, $2.to_i, $3.to_i)
  86.   end
  87.  
  88.   # 判断是否为涂装物品,并返回图案文件名
  89.   def paint_pattern
  90.     @note =~ /<涂装:\s*(.+?)\s*>/i
  91.     return $1
  92.   end
  93.  
  94.   # 是否为可用的外观物品(染料或涂装)
  95.   def appearance_item?
  96.     dye_color || paint_pattern
  97.   end
  98. end
  99.  
  100. #==============================================================================#
  101. # ■ Game_System (扩展)
  102. #==============================================================================#
  103. class Game_System
  104.   # 初始化染色/涂装数据容器
  105.   alias dye_paint_initialize initialize
  106.   def initialize
  107.     dye_paint_initialize
  108.     @dye_data   = {}   # 格式: { equip_id => Color }
  109.     @paint_data = {}   # 格式: { equip_id => "pattern_name" }
  110.   end
  111.  
  112.   # 获取装备的染色颜色
  113.   def dye_data(equip)
  114.     @dye_data[equip_id(equip)] || FalDyePaint::DEFAULT_COLOR
  115.   end
  116.  
  117.   # 设置装备的染色颜色
  118.   def set_dye_data(equip, color)
  119.     @dye_data[equip_id(equip)] = color
  120.   end
  121.  
  122.   # 获取装备的涂装图案
  123.   def paint_data(equip)
  124.     @paint_data[equip_id(equip)]
  125.   end
  126.  
  127.   # 设置装备的涂装图案
  128.   def set_paint_data(equip, pattern)
  129.     @paint_data[equip_id(equip)] = pattern
  130.   end
  131.  
  132.   # 清除装备的染色数据
  133.   def clear_dye_data(equip)
  134.     @dye_data.delete(equip_id(equip))
  135.   end
  136.  
  137.   # 清除装备的涂装数据
  138.   def clear_paint_data(equip)
  139.     @paint_data.delete(equip_id(equip))
  140.   end
  141.  
  142.   private
  143.  
  144.   # 生成装备的唯一标识符(类别 + ID)
  145.   def equip_id(equip)
  146.     "#{equip.class.name}_#{equip.id}"
  147.   end
  148. end
  149.  
  150. #==============================================================================#
  151. # ■ Game_Actor (扩展)
  152. #==============================================================================#
  153. class Game_Actor
  154.   attr_accessor :equip_changed
  155.  
  156.   alias dye_paint_change_equip change_equip
  157.   def change_equip(slot_id, item)
  158.     dye_paint_change_equip(slot_id, item)
  159.     @equip_changed = true
  160.   end
  161. end
  162.  
  163. #==============================================================================#
  164. # ■ Window_DyePaintHelp (自定义帮助窗口)
  165. #==============================================================================#
  166. class Window_DyePaintHelp < Window_Help
  167.   def initialize(line_number = 2)
  168.     super(line_number)
  169.   end
  170.  
  171.   def set_actor(actor)
  172.     set_text(actor ? "#{actor.name} 的装备" : "")
  173.   end
  174.  
  175.   def set_equip(equip)
  176.     text = equip ? equip.name : ""
  177.     if equip
  178.       dye = $game_system.dye_data(equip)
  179.       pattern = $game_system.paint_data(equip)
  180.       extra = []
  181.       extra << "染色" if dye != FalDyePaint::DEFAULT_COLOR
  182.       extra << "涂装" if pattern
  183.       text += "  (#{extra.join('、')})" unless extra.empty?
  184.     end
  185.     set_text(text)
  186.   end
  187.  
  188.   def set_item(item)
  189.     text = item ? item.name : ""
  190.     if item
  191.       if item.dye_color
  192.         c = item.dye_color
  193.         text += sprintf("  RGB(%d,%d,%d)", c.red, c.green, c.blue)
  194.       elsif item.paint_pattern
  195.         text += "  图案: #{item.paint_pattern}"
  196.       end
  197.     end
  198.     set_text(text)
  199.   end
  200. end
  201.  
  202. #==============================================================================#
  203. # ■ Window_DyePaintCommand (命令窗口)
  204. #==============================================================================#
  205. class Window_DyePaintCommand < Window_HorzCommand
  206.   def initialize
  207.     super(0, 0)
  208.     deactivate
  209.   end
  210.  
  211.   def window_width
  212.     Graphics.width
  213.   end
  214.  
  215.   def col_max
  216.     2
  217.   end
  218.  
  219.   def make_command_list
  220.     add_command("染色", :dye)
  221.     add_command("涂装", :paint)
  222.   end
  223. end
  224.  
  225. #==============================================================================#
  226. # ■ Window_DyePaintActor (角色选择窗口)
  227. #==============================================================================#
  228. class Window_DyePaintActor < Window_Selectable
  229.   attr_reader :actor
  230.  
  231.   def initialize(x, y)
  232.     super(x, y, 160, Graphics.height - y)
  233.     refresh
  234.     activate
  235.     select(0)
  236.   end
  237.  
  238.   def item_max
  239.     $game_party.members.size
  240.   end
  241.  
  242.   def actor
  243.     $game_party.members[@index]
  244.   end
  245.  
  246.   def refresh
  247.     contents.clear
  248.     $game_party.members.each_with_index do |actor, i|
  249.       draw_actor_name(actor, 4, i * line_height)
  250.     end
  251.   end
  252.  
  253.   def draw_actor_name(actor, x, y)
  254.     change_color(normal_color)
  255.     draw_text(x, y, contents_width, line_height, actor.name)
  256.   end
  257.  
  258.   def update_help
  259.     @help_window.set_actor(actor) if @help_window
  260.   end
  261. end
  262.  
  263. #==============================================================================#
  264. # ■ Window_DyePaintEquip (装备选择窗口)
  265. #==============================================================================#
  266. class Window_DyePaintEquip < Window_Selectable
  267.   attr_reader :equip
  268.  
  269.   def initialize(x, y)
  270.     super(x, y, 200, Graphics.height - y)
  271.     @actor = nil
  272.     deactivate
  273.   end
  274.  
  275.   def actor=(actor)
  276.     return if @actor == actor
  277.     @actor = actor
  278.     refresh
  279.     select(0) if item_max > 0
  280.   end
  281.  
  282.   def item_max
  283.     @actor ? @actor.equips.compact.size : 0
  284.   end
  285.  
  286.   def equip
  287.     @actor ? @actor.equips.compact[@index] : nil
  288.   end
  289.  
  290.   def refresh
  291.     contents.clear
  292.     return unless @actor
  293.     @actor.equips.compact.each_with_index do |equip, i|
  294.       draw_item_name(equip, 4, i * line_height, true, contents_width - 8)
  295.     end
  296.   end
  297.  
  298.   def update_help
  299.     @help_window.set_equip(equip) if @help_window
  300.   end
  301. end
  302.  
  303. #==============================================================================#
  304. # ■ Window_DyePaintItem (染料/涂装物品窗口)
  305. #==============================================================================#
  306. class Window_DyePaintItem < Window_ItemList
  307.   def initialize(x, y, width, height)
  308.     super(x, y, width, height)
  309.     @mode = :dye
  310.     deactivate
  311.   end
  312.  
  313.   def mode=(mode)
  314.     return if @mode == mode
  315.     @mode = mode
  316.     refresh
  317.     select(0) if item_max > 0
  318.   end
  319.  
  320.   def include?(item)
  321.     case @mode
  322.     when :dye
  323.       item.is_a?(RPG::Item) && item.dye_color != nil
  324.     when :paint
  325.       item.is_a?(RPG::Item) && item.paint_pattern != nil
  326.     else
  327.       false
  328.     end
  329.   end
  330.  
  331.   def enable?(item)
  332.     $game_party.item_number(item) > 0
  333.   end
  334.  
  335.   def update_help
  336.     @help_window.set_item(item) if @help_window
  337.   end
  338. end
  339.  
  340. #==============================================================================#
  341. # ■ Window_DyePaintPreview (预览窗口)
  342. #==============================================================================#
  343. class Window_DyePaintPreview < Window_Base
  344.   def initialize(x, y)
  345.     super(x, y, FalDyePaint::PREVIEW_WIDTH + 32, FalDyePaint::PREVIEW_HEIGHT + 32)
  346.     @equip = nil
  347.     @dye_color = nil
  348.     @paint_pattern = nil
  349.     refresh
  350.   end
  351.  
  352.   def set_preview(equip, dye_color = nil, paint_pattern = nil)
  353.     return if @equip == equip && @dye_color == dye_color && @paint_pattern == paint_pattern
  354.     @equip = equip
  355.     @dye_color = dye_color
  356.     @paint_pattern = paint_pattern
  357.     refresh
  358.   end
  359.  
  360.   def clear
  361.     @equip = nil
  362.     @dye_color = nil
  363.     @paint_pattern = nil
  364.     refresh
  365.   end
  366.  
  367.   def refresh
  368.     contents.clear
  369.     return unless @equip
  370.  
  371.     draw_icon(@equip.icon_index, 0, 0)
  372.  
  373.     if @dye_color
  374.       rect = Rect.new(24, 0, 24, 24)
  375.       contents.fill_rect(rect, @dye_color)
  376.     end
  377.  
  378.     if @paint_pattern
  379.       contents.font.size = 16
  380.       contents.draw_text(48, 0, contents_width - 48, 24, @paint_pattern)
  381.     end
  382.  
  383.     contents.font.size = Font.default_size
  384.     contents.draw_text(0, 30, contents_width, 24, "当前效果", 1)
  385.   end
  386. end
  387.  
  388. #==============================================================================#
  389. # ■ Scene_DyePaint (染色/涂装主场景)
  390. #==============================================================================#
  391. class Scene_DyePaint < Scene_MenuBase
  392.   def start
  393.     super
  394.     create_help_window
  395.     create_command_window
  396.     create_actor_window
  397.     create_equip_window
  398.     create_item_window
  399.     create_preview_window
  400.  
  401.     @help_window.height = 72
  402.     @command_window.activate
  403.     @mode = :dye
  404.   end
  405.  
  406.   def create_help_window
  407.     @help_window = Window_DyePaintHelp.new
  408.     @help_window.viewport = @viewport
  409.   end
  410.  
  411.   def create_command_window
  412.     @command_window = Window_DyePaintCommand.new
  413.     @command_window.viewport = @viewport
  414.     @command_window.y = @help_window.height
  415.     @command_window.set_handler(:dye,   method(:command_dye))
  416.     @command_window.set_handler(:paint, method(:command_paint))
  417.     @command_window.set_handler(:cancel, method(:return_scene))
  418.   end
  419.  
  420.   def create_actor_window
  421.     y = @command_window.y + @command_window.height
  422.     @actor_window = Window_DyePaintActor.new(0, y)
  423.     @actor_window.viewport = @viewport
  424.     @actor_window.help_window = @help_window
  425.     @actor_window.set_handler(:ok,     method(:on_actor_ok))
  426.     @actor_window.set_handler(:cancel, method(:on_actor_cancel))
  427.     @actor_window.deactivate
  428.   end
  429.  
  430.   def create_equip_window
  431.     x = @actor_window.width
  432.     y = @actor_window.y
  433.     @equip_window = Window_DyePaintEquip.new(x, y)
  434.     @equip_window.viewport = @viewport
  435.     @equip_window.help_window = @help_window
  436.     @equip_window.set_handler(:ok,     method(:on_equip_ok))
  437.     @equip_window.set_handler(:cancel, method(:on_equip_cancel))
  438.   end
  439.  
  440.   def create_item_window
  441.     x = @actor_window.width + @equip_window.width
  442.     y = @actor_window.y
  443.     w = Graphics.width - x
  444.     h = Graphics.height - y
  445.     @item_window = Window_DyePaintItem.new(x, y, w, h)
  446.     @item_window.viewport = @viewport
  447.     @item_window.help_window = @help_window
  448.     @item_window.set_handler(:ok,     method(:on_item_ok))
  449.     @item_window.set_handler(:cancel, method(:on_item_cancel))
  450.     @item_window.mode = :dye
  451.   end
  452.  
  453.   def create_preview_window
  454.     x = Graphics.width - FalDyePaint::PREVIEW_WIDTH - 32
  455.     y = @command_window.y
  456.     @preview_window = Window_DyePaintPreview.new(x, y)
  457.     @preview_window.viewport = @viewport
  458.   end
  459.  
  460.   #--------------------------------------------------------------------------
  461.   # * 命令处理
  462.   #--------------------------------------------------------------------------
  463.   def command_dye
  464.     @mode = :dye
  465.     @command_window.deactivate
  466.     @actor_window.activate
  467.     @item_window.mode = :dye
  468.     @item_window.refresh
  469.     update_preview
  470.   end
  471.  
  472.   def command_paint
  473.     @mode = :paint
  474.     @command_window.deactivate
  475.     @actor_window.activate
  476.     @item_window.mode = :paint
  477.     @item_window.refresh
  478.     update_preview
  479.   end
  480.  
  481.   #--------------------------------------------------------------------------
  482.   # * 角色窗口处理
  483.   #--------------------------------------------------------------------------
  484.   def on_actor_ok
  485.     @equip_window.actor = @actor_window.actor
  486.     @actor_window.deactivate
  487.     if @equip_window.item_max > 0
  488.       @equip_window.activate
  489.     else
  490.       Sound.play_buzzer
  491.       @actor_window.activate
  492.     end
  493.     update_preview
  494.   end
  495.  
  496.   def on_actor_cancel
  497.     @actor_window.deactivate
  498.     @command_window.activate
  499.     @preview_window.clear
  500.   end
  501.  
  502.   #--------------------------------------------------------------------------
  503.   # * 装备窗口处理
  504.   #--------------------------------------------------------------------------
  505.   def on_equip_ok
  506.     @item_window.refresh
  507.     if @item_window.item_max == 0
  508.       Sound.play_buzzer
  509.       @help_window.set_text("没有可用的#{@mode == :dye ? '染料' : '涂装'}物品")
  510.       @equip_window.deactivate
  511.       @actor_window.activate
  512.       @preview_window.clear
  513.       return
  514.     end
  515.     @equip_window.deactivate
  516.     @item_window.activate
  517.     update_preview
  518.   end
  519.  
  520.   def on_equip_cancel
  521.     @equip_window.deactivate
  522.     @actor_window.activate
  523.     @preview_window.clear
  524.     @item_window.unselect
  525.   end
  526.  
  527.   #--------------------------------------------------------------------------
  528.   # * 物品窗口处理
  529.   #--------------------------------------------------------------------------
  530.   def on_item_ok
  531.     item = @item_window.item
  532.     equip = @equip_window.equip
  533.     if item.nil?
  534.       on_item_cancel
  535.       return
  536.     end
  537.  
  538.     if (@mode == :dye && item.dye_color) || (@mode == :paint && item.paint_pattern)
  539.       apply_appearance(equip, item)
  540.     else
  541.       Sound.play_buzzer
  542.     end
  543.   end
  544.  
  545.   def on_item_cancel
  546.     @item_window.deactivate
  547.     @equip_window.activate
  548.     @preview_window.set_preview(@equip_window.equip,
  549.                                 $game_system.dye_data(@equip_window.equip),
  550.                                 $game_system.paint_data(@equip_window.equip))
  551.   end
  552.  
  553.   #--------------------------------------------------------------------------
  554.   # * 应用染色/涂装
  555.   #--------------------------------------------------------------------------
  556.   def apply_appearance(equip, item)
  557.     if @mode == :dye
  558.       color = item.dye_color
  559.       $game_system.set_dye_data(equip, color)
  560.       RPG::SE.new(FalDyePaint::DYE_SE, 80).play
  561.     else
  562.       pattern = item.paint_pattern
  563.       $game_system.set_paint_data(equip, pattern)
  564.       RPG::SE.new(FalDyePaint::PAINT_SE, 80).play
  565.     end
  566.  
  567.     $game_party.lose_item(item, 1)
  568.  
  569.     @item_window.refresh
  570.     @equip_window.refresh
  571.     update_preview
  572.  
  573.     @item_window.deactivate
  574.     @equip_window.activate
  575.     @equip_window.select(@equip_window.index)
  576.  
  577.     $game_player.refresh
  578.   end
  579.  
  580.   #--------------------------------------------------------------------------
  581.   # * 更新预览窗口
  582.   #--------------------------------------------------------------------------
  583.   def update_preview
  584.     equip = @equip_window.equip
  585.     if equip
  586.       dye = $game_system.dye_data(equip)
  587.       paint = $game_system.paint_data(equip)
  588.       @preview_window.set_preview(equip, dye, paint)
  589.     else
  590.       @preview_window.clear
  591.     end
  592.   end
  593.  
  594.   #--------------------------------------------------------------------------
  595.   # * 帧更新
  596.   #--------------------------------------------------------------------------
  597.   def update
  598.     super
  599.     if @item_window.active && @item_window.item
  600.       item = @item_window.item
  601.       equip = @equip_window.equip
  602.       if equip
  603.         if @mode == :dye && item.dye_color
  604.           @preview_window.set_preview(equip, item.dye_color,
  605.                                       $game_system.paint_data(equip))
  606.         elsif @mode == :paint && item.paint_pattern
  607.           @preview_window.set_preview(equip,
  608.                                       $game_system.dye_data(equip),
  609.                                       item.paint_pattern)
  610.         else
  611.           @preview_window.set_preview(equip,
  612.                                       $game_system.dye_data(equip),
  613.                                       $game_system.paint_data(equip))
  614.         end
  615.       end
  616.     end
  617.   end
  618. end
  619.  
  620. #==============================================================================#
  621. # ■ Window_MenuCommand (在菜单中添加命令)
  622. #==============================================================================#
  623. class Window_MenuCommand < Window_Command
  624.   alias dye_paint_add_original_commands add_original_commands
  625.   def add_original_commands
  626.     dye_paint_add_original_commands
  627.     add_command(FalDyePaint::COMMAND_NAME, :dyepaint, true)
  628.   end
  629. end
  630.  
  631. #==============================================================================#
  632. # ■ Scene_Menu (增加菜单选项)
  633. #==============================================================================#
  634. class Scene_Menu < Scene_MenuBase
  635.   alias dye_paint_create_command_window create_command_window
  636.   def create_command_window
  637.     dye_paint_create_command_window
  638.     @command_window.set_handler(:dyepaint, method(:command_dyepaint))
  639.   end
  640.  
  641.   def command_dyepaint
  642.     SceneManager.call(Scene_DyePaint)
  643.   end
  644. end
  645.  
  646. #==============================================================================#
  647. # ■ Sprite_Player (装备变更行走图 + 染色/涂装叠加)
  648. #==============================================================================#
  649. class Sprite_Player < Sprite_Character
  650.   EquipDisplayPriority = EquipDisplay::Priority
  651.  
  652.   def graphic_changed?
  653.     super || equip_changed?
  654.   end
  655.  
  656.   def equip_changed?
  657.     @character.actor && @character.actor.equip_changed
  658.   end
  659.  
  660.   def set_character_bitmap
  661.     super
  662.     setup_bitmap_display_equips
  663.   end
  664.  
  665.   def setup_bitmap_display_equips
  666.     w = @cw * 3
  667.     h = @ch * 4
  668.     i = @character.character_index
  669.     orig_bitmap = Bitmap.new(w, h)
  670.     orig_bitmap.blt(0, 0, self.bitmap, Rect.new(i%4*w, i/4*h, w, h))
  671.     self.bitmap = Bitmap.new(w, h)
  672.     bitmap_draw_equips(orig_bitmap) if @character.actor
  673.     orig_bitmap.dispose
  674.   end
  675.  
  676.   def bitmap_draw_equips(orig_bitmap)
  677.     @character.actor.equip_changed = false
  678.     temp_equip_bitmaps = []
  679.     @character.actor.equips.each_with_index do |equip, index|
  680.       img_name = equip ? equip.display_equip_part : nil
  681.       if img_name
  682.         base_bmp = equip_bitmap(img_name, index == 1 && equip.is_a?(RPG::Weapon))
  683.         if base_bmp
  684.           colored_bmp = apply_dye_and_paint(base_bmp, equip)
  685.           temp_equip_bitmaps.push(colored_bmp)
  686.         else
  687.           temp_equip_bitmaps.push(nil)
  688.         end
  689.       else
  690.         temp_equip_bitmaps.push(nil)
  691.       end
  692.     end
  693.  
  694.     btmp_rect = Rect.new(0, 0, @cw*3, @ch)
  695.     4.times do |i|
  696.       btmp_rect.y = @ch * i
  697.       EquipDisplayPriority[i].each do |part|
  698.         btmp = equip_part_bitmap(part, temp_equip_bitmaps, orig_bitmap)
  699.         self.bitmap.blt(0, btmp_rect.y, btmp, btmp_rect) if btmp
  700.       end
  701.     end
  702.  
  703.     temp_equip_bitmaps.each {|b| b.dispose if b}
  704.   end
  705.  
  706.   #--------------------------------------------------------------------------
  707.   # * 应用染色和涂装(染色:色相旋转;涂装:正片叠底 + 平铺)
  708.   #--------------------------------------------------------------------------
  709.   def apply_dye_and_paint(src_bitmap, equip)
  710.     return src_bitmap unless equip
  711.     new_bmp = Bitmap.new(src_bitmap.width, src_bitmap.height)
  712.  
  713.     # ----- 染色处理(色相旋转)-----
  714.     dye_color = equip.dye_color
  715.     if dye_color && dye_color != FalDyePaint::DEFAULT_COLOR
  716.       if FalDyePaint::USE_HUE_CHANGE
  717.         hue = rgb_to_hue(dye_color.red, dye_color.green, dye_color.blue)
  718.         new_bmp.blt(0, 0, src_bitmap, src_bitmap.rect)
  719.         new_bmp.hue_change(hue)
  720.       else
  721.         new_bmp.blt(0, 0, src_bitmap, src_bitmap.rect)
  722.         (0...new_bmp.width).each do |x|
  723.           (0...new_bmp.height).each do |y|
  724.             color = new_bmp.get_pixel(x, y)
  725.             next if color.alpha == 0
  726.             r = (color.red   * (255 - FalDyePaint::DYE_OPACITY) + dye_color.red   * FalDyePaint::DYE_OPACITY) / 255
  727.             g = (color.green * (255 - FalDyePaint::DYE_OPACITY) + dye_color.green * FalDyePaint::DYE_OPACITY) / 255
  728.             b = (color.blue  * (255 - FalDyePaint::DYE_OPACITY) + dye_color.blue  * FalDyePaint::DYE_OPACITY) / 255
  729.             new_bmp.set_pixel(x, y, Color.new(r, g, b, color.alpha))
  730.           end
  731.         end
  732.       end
  733.     else
  734.       new_bmp.blt(0, 0, src_bitmap, src_bitmap.rect)
  735.     end
  736.  
  737.     # ----- 涂装处理(正片叠底 + 平铺,仅作用于非透明区域)-----
  738.     paint_pattern = equip.paint_pattern
  739.     if paint_pattern
  740.       paint_file = "Graphics/#{FalDyePaint::PAINTING_DIR}/#{paint_pattern}.png"
  741.       if File.exist?(paint_file)
  742.         paint_bmp = Bitmap.new(paint_file)
  743.  
  744.         # 创建平铺图层
  745.         tile_bmp = Bitmap.new(new_bmp.width, new_bmp.height)
  746.         tile_x = (new_bmp.width.to_f / paint_bmp.width).ceil
  747.         tile_y = (new_bmp.height.to_f / paint_bmp.height).ceil
  748.         tile_y.times do |y|
  749.           tile_x.times do |x|
  750.             tile_bmp.blt(x * paint_bmp.width, y * paint_bmp.height,
  751.                          paint_bmp, paint_bmp.rect)
  752.           end
  753.         end
  754.  
  755.         # 逐像素正片叠底
  756.         (0...new_bmp.width).each do |x|
  757.           (0...new_bmp.height).each do |y|
  758.             src_color = src_bitmap.get_pixel(x, y)
  759.             next if src_color.alpha == 0          # 透明区域不处理
  760.  
  761.             paint_color = tile_bmp.get_pixel(x, y)
  762.             next if paint_color.alpha == 0        # 涂装透明像素跳过
  763.  
  764.             base_color = new_bmp.get_pixel(x, y)
  765.  
  766.             # 正片叠底公式: Result = (Base * Overlay) / 255
  767.             r = (base_color.red * paint_color.red) / 255
  768.             g = (base_color.green * paint_color.green) / 255
  769.             b = (base_color.blue * paint_color.blue) / 255
  770.  
  771.             # 处理涂装的透明度(Alpha 混合)
  772.             if paint_color.alpha < 255
  773.               alpha_factor = paint_color.alpha / 255.0
  774.               r = (base_color.red * (1 - alpha_factor) + r * alpha_factor).to_i
  775.               g = (base_color.green * (1 - alpha_factor) + g * alpha_factor).to_i
  776.               b = (base_color.blue * (1 - alpha_factor) + b * alpha_factor).to_i
  777.             end
  778.  
  779.             new_bmp.set_pixel(x, y, Color.new(r, g, b, base_color.alpha))
  780.           end
  781.         end
  782.  
  783.         tile_bmp.dispose
  784.         paint_bmp.dispose
  785.       end
  786.     end
  787.  
  788.     new_bmp
  789.   end
  790.  
  791.   #--------------------------------------------------------------------------
  792.   # * RGB 转色相 (0~360)
  793.   #--------------------------------------------------------------------------
  794.   def rgb_to_hue(r, g, b)
  795.     r /= 255.0
  796.     g /= 255.0
  797.     b /= 255.0
  798.     max = [r, g, b].max
  799.     min = [r, g, b].min
  800.     delta = max - min
  801.  
  802.     hue = 0.0
  803.     if delta != 0
  804.       case max
  805.       when r
  806.         hue = 60.0 * ((g - b) / delta % 6)
  807.       when g
  808.         hue = 60.0 * ((b - r) / delta + 2)
  809.       when b
  810.         hue = 60.0 * ((r - g) / delta + 4)
  811.       end
  812.     end
  813.     hue = 0 if hue < 0
  814.     hue.to_i
  815.   end
  816.  
  817.   def equip_part_bitmap(part, temp_equip_bitmaps, orig_bitmap)
  818.     case part
  819.     when :body;     orig_bitmap
  820.     when :weapon;   temp_equip_bitmaps[0]
  821.     when :shield;   temp_equip_bitmaps[1]
  822.     when :armor;    temp_equip_bitmaps[2]
  823.     when :helmet;   temp_equip_bitmaps[3]
  824.     end
  825.   end
  826.  
  827.   def equip_bitmap(img_name, dual_weapon)
  828.     if img_name
  829.       img_file = "Graphics/DisplayEquips/#{img_name}"
  830.       if dual_weapon
  831.         img_dual = img_file + "_dual.png"
  832.         File.exist?(img_dual) ? Bitmap.new(img_dual) : nil
  833.       else
  834.         Bitmap.new(img_file + ".png") rescue nil
  835.       end
  836.     else
  837.       nil
  838.     end
  839.   end
  840.  
  841.   def update_src_rect
  842.     pattern = @character.pattern < 3 ? @character.pattern : 1
  843.     sx = pattern * @cw
  844.     sy = (@character.direction - 2) / 2 * @ch
  845.     self.src_rect.set(sx, sy, @cw, @ch)
  846.   end
  847.  
  848.   def dispose
  849.     bitmap.dispose if bitmap
  850.     super
  851.   end
  852. end
  853.  
  854. #==============================================================================#
  855. # ■ Spriteset_Map (覆盖角色精灵创建)
  856. #==============================================================================#
  857. class Spriteset_Map
  858.   def create_characters
  859.     @character_sprites = []
  860.     $game_map.events.values.each do |event|
  861.       @character_sprites.push(Sprite_Character.new(@viewport1, event))
  862.     end
  863.     $game_map.vehicles.each do |vehicle|
  864.       @character_sprites.push(Sprite_Character.new(@viewport1, vehicle))
  865.     end
  866.     $game_player.followers.reverse_each do |follower|
  867.       @character_sprites.push(Sprite_Player.new(@viewport1, follower))
  868.     end
  869.     @character_sprites.push(Sprite_Player.new(@viewport1, $game_player))
  870.     @map_id = $game_map.map_id
  871.   end
  872. end






注意:由于未知问题,不适用URGE,会导致无报错闪退

W{IA1W9[IP}40H3%X@7{HC3.png (198.55 KB, 下载次数: 18)

W{IA1W9[IP}40H3%X@7{HC3.png

`XIQE4(FNF8L`YOA72_88[2.png (137.63 KB, 下载次数: 18)

`XIQE4(FNF8L`YOA72_88[2.png

DEYTSI$GR%}I5C`41RV1B{8.png (16.67 KB, 下载次数: 19)

DEYTSI$GR%}I5C`41RV1B{8.png

{)R{$MHEM9(V}0IGTPON%VV.png (8.52 KB, 下载次数: 20)

{)R{$MHEM9(V}0IGTPON%VV.png

染色涂装.7z

264.18 KB, 下载次数: 3

售价: 50 星屑  [记录]

示例

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

本版积分规则

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

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

GMT+8, 2026-6-4 16:11

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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