RUBY 代码
- #==============================================================================
- # ★ Item_Transmute
- #------------------------------------------------------------------------------
- # 配方不公开的物品合成
- # By Summoner
- #==============================================================================
- #
- # 本脚本以 知识共享署名-非商业性使用 3.0 Unported 许可协议进行许可。
- # 详见 [url]http://creativecommons.org/licenses/by-nc/3.0/[/url]
- #
- #==============================================================================
- #
- # 这是一个配方不公开的物品合成,也就是说什么材料可以合成什么物品玩家在
- # 游戏中的合成界面是不能直接看到的。由于物品的合成配方不是公开的,所以
- # 玩家需要通过自己探索或从NPC处得到合成配方(当然看攻略也是一种可能)
- #
- # 例如M&M中的配药水,Diablo II的盒子,NWV中的铁匠铺、Wizard Lab……
- #
- # 冲突可能性:基本上是添加新的内容,冲突可能性较小
- #
- # 可扩展性:可以加强、扩展的东西应该很多。
- # 例如:合成需要花费GP、SP甚至XP,合成需要特定器具,合成失败受到伤害,
- # 某些物品的几率合成、物品图鉴等等。
- #
- # 有的东西已经注释清楚了,搞懂原理的话,根据自己需要改起来也不会很麻烦。
- #
- # 个人一下子没时间实现这些,欢迎大家多多修改分享。
- #
- # 使用方法:在事件中使用脚本$scene = Scene_Compose.new,然后等待2帧
- #
- #
- #==============================================================================
- # 若合成失败(无匹配的配方)物品是否失去
- $Ingredient_Lost_When_Fail = false
- # 合成成功/失败SE
- # 若不使用SE请设置为“""”(不含外引号)
- $SE_Compose_Successful = "Audio/SE/109-Heal05"
- $SE_Compose_Failed = "Audio/SE/117-Fire01"
- #=============================================================================
- # ■ 配方及补充的定义
- #-----------------------------------------------------------------------------
- # Game_System
- #=============================================================================
- class Game_System
- attr_accessor :formulas
- attr_accessor :products
- alias formulas_initialize initialize
- def initialize
- formulas_initialize
- @formulas = []
- @products = []
- #############################################################################
- #
- #===========================配方表===========================================
- #
- # 配方格式
- #
- # @formulas[i] = [[材料种类,材料编号,数量],[材料种类,材料编号,数量]……]
- # @products[i] = [[成品种类,成品编号,数量],[成品种类,成品编号,数量]……]
- #
- # 种类:物品 0 武器 1 防具 2
- #
- # 1.如果有两个配方材料相同,理论上会按编号较小的处理
- # 2.配方材料的顺序与合成是无关的(当然如果你想改成有关肯定也不会太麻烦)
- # 3.允许某个材料拆成多件成品(可能就不叫物品合成,应该叫物品分解了)
- # 4.暂时不支持多步合并为一步的合成
- # 例如 A + B = C,C + D = E,如果不存在A + B + D = E的配方
- # A + B + D无法合成 E
- #
- #############################################################################
- @formulas[0] = []
- @products[0] = []
- # 样例1: 回复剂x3 = 超回复剂x1
- @formulas[1] = [[0,1,3]]
- @products[1] = [[0,2,1]]
- @formulas[2] = [[0,2,3]]
- @products[2] = [[0,3,1]]
- @formulas[3] = [[0,4,3]]
- @products[3] = [[0,5,1]]
- @formulas[4] = [[0,5,3]]
- @products[4] = [[0,6,1]]
- # 样例2: 完全恢复剂x1 + 超级香水x1 = 圣灵药x1
- @formulas[5] = [[0,3,1],[0,6,1]]
- @products[5] = [[0,7,1]]
- # 样例3: 完全恢复剂x1 + 超级香水x1 = 完全圣灵药x1
- # 被样例2 被覆盖
- @formulas[6] = [[0,3,1],[0,6,1]]
- @products[6] = [[0,8,1]]
- # 圣灵药x1 = 完全恢复剂x1 + 超级香水x1 (Item_Decompose...)
- @formulas[7] = [[0,7,1]]
- @products[7] = [[0,3,1],[0,6,1]]
- # 样例5: 铜剑x1 + 回复剂x1 + 铜铠x1 = 密斯利尔剑x1
- @formulas[8] = [[1,1,1],[0,1,1],[2,1,1]]
- @products[8] = [[1,4,1]]
- end
- end
- class Game_Temp
- attr_accessor :forge
- alias forge_item_initialize initialize
- def initialize
- forge_item_initialize
- # 定义合成窗口中的物品储存区
- @forge = []
- end
- end
- #==============================================================================
- # ■ Window_ForgeCommand
- #------------------------------------------------------------------------------
- # 合成画面、选择要做的事的窗口
- #==============================================================================
- class Window_ComposeCommand < Window_Selectable
- #--------------------------------------------------------------------------
- # ● 初始化对像
- #--------------------------------------------------------------------------
- def initialize
- super(0, 64, 640, 64)
- self.contents = Bitmap.new(width - 32, height - 32)
- @item_max = 4
- @column_max = 4
- @commands = ["更改材料", "合成", "放弃合成", "离开"]
- refresh
- self.index = 0
- end
- #--------------------------------------------------------------------------
- # ● 刷新
- #--------------------------------------------------------------------------
- def refresh
- self.contents.clear
- for i in0...@item_max
- draw_item(i)
- end
- end
- #--------------------------------------------------------------------------
- # ● 描绘项目
- # index : 项目编号
- #--------------------------------------------------------------------------
- def draw_item(index)
- x = 4 + index * 160
- self.contents.draw_text(x, 0, 128, 32, @commands[index])
- end
- end
- #==============================================================================
- # ■ Window_ForgeLeft
- #------------------------------------------------------------------------------
- # 合成画面中显示拥有的物品的窗口
- #==============================================================================
- class Window_ComposeLeft < Window_Selectable
- #--------------------------------------------------------------------------
- # ● 初始化对像
- #--------------------------------------------------------------------------
- def initialize
- super(0, 128, 320, 352)
- @column_max = 1
- refresh
- self.index = 0
- end
- #--------------------------------------------------------------------------
- # ● 获取物品
- #--------------------------------------------------------------------------
- def item
- return@data[self.index]
- end
- #--------------------------------------------------------------------------
- # ● 刷新
- #--------------------------------------------------------------------------
- def refresh
- ifself.contents != nil
- self.contents.dispose
- self.contents = nil
- end
- self.update_cursor_rect
- @data = []
- for i in1...$data_items.size
- if$game_party.item_number(i) > 0
- @data.push($data_items[i])
- end
- end
- for i in1...$data_weapons.size
- if$game_party.weapon_number(i) > 0
- @data.push($data_weapons[i])
- end
- end
- for i in1...$data_armors.size
- if$game_party.armor_number(i) > 0
- @data.push($data_armors[i])
- end
- end
- # 如果项目数不是 0 就生成位图、描绘全部项目
- @item_max = @data.size
- if@item_max > 0
- self.contents = Bitmap.new(width - 32, row_max * 32)
- for i in0...@item_max
- draw_item(i)
- end
- end
- end
- #--------------------------------------------------------------------------
- # ● 描绘项目
- # index : 项目标号
- #--------------------------------------------------------------------------
- def draw_item(index)
- item = @data[index]
- case item
- whenRPG::Item
- number = $game_party.item_number(item.id)
- whenRPG::Weapon
- number = $game_party.weapon_number(item.id)
- whenRPG::Armor
- number = $game_party.armor_number(item.id)
- end
- self.contents.font.color = normal_color
- x = 4
- y = index * 32
- rect = Rect.new(x, y, self.width / @column_max - 32, 32)
- self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
- bitmap = RPG::Cache.icon(item.icon_name)
- opacity = self.contents.font.color == normal_color ? 255 : 128
- self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
- self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
- self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
- self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
- end
- #--------------------------------------------------------------------------
- # ● 刷新帮助文本
- #--------------------------------------------------------------------------
- def update_help
- @help_window.set_text(self.item == nil ? "" : self.item.description)
- end
- end
- #==============================================================================
- # ■ Window_ForgeRight
- #------------------------------------------------------------------------------
- # 合成画面中的合成区窗口
- #==============================================================================
- class Window_ComposeRight < Window_Selectable
- attr_accessor :forge_item
- #--------------------------------------------------------------------------
- # ● 初始化对像
- #--------------------------------------------------------------------------
- def initialize(forge_item)
- super(320, 128, 320, 352)
- @column_max = 1
- @forge_item = []
- refresh
- self.index = 0
- end
- #--------------------------------------------------------------------------
- # ● 获取物品
- #--------------------------------------------------------------------------
- def item
- return@data[self.index]
- end
- #--------------------------------------------------------------------------
- # ● 获取物品
- #--------------------------------------------------------------------------
- def item_number
- return@data_number[self.index]
- end
- #--------------------------------------------------------------------------
- # ● 刷新
- #--------------------------------------------------------------------------
- def refresh
- ifself.contents != nil
- self.contents.dispose
- self.contents = nil
- end
- @data = []
- @data_number = []
- @forge_item = $game_temp.forge
- for item_forge in@forge_item
- case item_forge[0]
- when0
- item = $data_items[item_forge[1]]
- when1
- item = $data_weapons[item_forge[1]]
- when2
- item = $data_armors[item_forge[1]]
- end
- if(item != nil)and(item_forge[2] != 0)
- @data.push(item)
- @data_number.push(item_forge[2])
- else
- @data.delete(item)
- end
- end
- # 如果项目数不是 0 就生成位图、描绘全部项目
- @item_max = @data.size
- if@item_max > 0
- self.contents = Bitmap.new(width - 32, row_max * 32)
- for i in0...@item_max
- draw_item(i)
- end
- end
- end
- #--------------------------------------------------------------------------
- # ● 描绘项目
- # index : 项目标号
- #--------------------------------------------------------------------------
- def draw_item(index)
- item = @data[index]
- case item
- whenRPG::Item
- number = $game_temp.forge[index][2]
- whenRPG::Weapon
- number = $game_temp.forge[index][2]
- whenRPG::Armor
- number = $game_temp.forge[index][2]
- end
- self.contents.font.color = normal_color
- x = 4
- y = index * 32
- rect = Rect.new(x, y, self.width / @column_max - 32, 32)
- self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
- bitmap = RPG::Cache.icon(item.icon_name)
- opacity = self.contents.font.color == normal_color ? 255 : 128
- self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
- self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
- self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
- self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
- end
- #--------------------------------------------------------------------------
- # ● 刷新帮助文本
- #--------------------------------------------------------------------------
- def update_help
- @help_window.set_text(self.item == nil ? "" : self.item.description)
- end
- end
- #==============================================================================
- # ■ Scene_Compose
- #------------------------------------------------------------------------------
- # 处理物品合成画面的类
- #==============================================================================
- class Scene_Compose
- #--------------------------------------------------------------------------
- # ● 初始化
- #--------------------------------------------------------------------------
- def initialize
- # 生成帮助窗口
- @help_window = Window_Help.new
- # 生成命令窗口
- @command_window = Window_ComposeCommand.new
- @command_window.active = false
- # 生成左方窗口
- @item_window = Window_ComposeLeft.new
- @item_window.active = true
- @item_window.help_window = @help_window
- # 生成右方窗口
- @forge_window = Window_ComposeRight.new([])
- @forge_window.active = false
- @forge_window.help_window = @help_window
- # 初始化配方与合成区
- @formulas = $game_system.formulas
- @products = $game_system.products
- @forge = []
- @products_temp = []
- end
- #--------------------------------------------------------------------------
- # ● 主处理
- #--------------------------------------------------------------------------
- def main
- # 执行过渡
- Graphics.transition
- # 主循环
- loopdo
- # 刷新游戏画面
- Graphics.update
- # 刷新输入情报
- Input.update
- # 刷新画面
- update
- # 如果画面被切换的话就中断循环
- if$scene != self
- break
- end
- end
- # 准备过渡
- Graphics.freeze
- # 释放窗口
- @help_window.dispose
- @command_window.dispose
- @item_window.dispose
- @forge_window.dispose
- end
- #--------------------------------------------------------------------------
- # ● 刷新画面
- #--------------------------------------------------------------------------
- def update
- @help_window.update
- @command_window.update
- @item_window.update
- @forge_window.update
- if@command_window.active
- update_command
- return
- end
- if@item_window.active
- update_item
- return
- end
- if@forge_window.active
- update_forge
- return
- end
- return
- end
- #--------------------------------------------------------------------------
- # ● 刷新画面(指令窗口激活的情况下)
- #--------------------------------------------------------------------------
- def update_command
- # 按下 B 键的情况下
- if Input.trigger?(Input::B)
- # 演奏取消 SE
- $game_system.se_play($data_system.cancel_se)
- abort
- # 切换到地图画面
- $scene = Scene_Map.new
- return
- end
- # 按下 C 键的情况下
- if Input.trigger?(Input::C)
- # 命令窗口光标位置分支
- case@command_window.index
- when0 # 更改材料
- # 演奏确定 SE
- $game_system.se_play($data_system.decision_se)
- # 窗口状态转向物品窗口
- @command_window.active = false
- @item_window.active = true
- @forge_window.active = false
- when1 # 合成
- # 演奏确定 SE
- $game_system.se_play($data_system.decision_se)
- # 执行合成命令
- if$game_temp.forge != []
- compose
- end
- when2 # 放弃合成
- # 演奏确定 SE
- $game_system.se_play($data_system.decision_se)
- # 放弃合成
- abort
- when3 # 离开
- # 演奏确定 SE
- $game_system.se_play($data_system.decision_se)
- # 放弃合成
- abort
- # 切换到地图画面
- $scene = Scene_Map.new
- end
- return
- end
- end
- #--------------------------------------------------------------------------
- # ● 刷新画面(物品窗口激活的情况下)
- #--------------------------------------------------------------------------
- def update_item
- # 按下 B 键的情况下
- if Input.trigger?(Input::B)
- # 演奏取消 SE
- $game_system.se_play($data_system.cancel_se)
- # 切换到指令窗口
- @item_window.active = false
- @command_window.active = true
- @help_window.set_text("")
- return
- end
- # 按下 C 键的情况
- if Input.trigger?(Input::C)
- # 演奏确定 SE
- $game_system.se_play($data_system.decision_se)
- # 获取物品
- @item = @item_window.item
- # 获取物品的所持数
- case@item
- whenRPG::Item
- number = $game_party.item_number(@item.id)
- typetemp = 0
- whenRPG::Weapon
- number = $game_party.weapon_number(@item.id)
- typetemp = 1
- whenRPG::Armor
- number = $game_party.armor_number(@item.id)
- typetemp = 2
- end
- if number != nil
- # 更改合成窗口的物品
- case@item
- whenRPG::Item
- $game_party.lose_item(@item.id, 1)
- whenRPG::Weapon
- $game_party.lose_weapon(@item.id, 1)
- whenRPG::Armor
- $game_party.lose_armor(@item.id, 1)
- end
- forge_change(typetemp, @item.id, 1)
- # 刷新各窗口
- @item_window.update
- @help_window.update
- @forge_window.update
- @item_window.refresh
- @forge_window.refresh
- end
- end
- # 按下 右方向键 的情况
- if Input.trigger?(Input::RIGHT)
- # 切换到合成窗口
- @item_window.active = false
- @forge_window.active = true
- end
- end
- #--------------------------------------------------------------------------
- # ● 刷新画面(合成窗口激活的情况下)
- #--------------------------------------------------------------------------
- def update_forge
- # 按下 B 键的情况下
- if Input.trigger?(Input::B)
- # 演奏取消 SE
- $game_system.se_play($data_system.cancel_se)
- # 切换到指令窗口
- @forge_window.active = false
- @command_window.active = true
- @help_window.set_text("")
- return
- end
- # 按下 C 键的情况
- if Input.trigger?(Input::C)
- # 演奏确定 SE
- $game_system.se_play($data_system.decision_se)
- # 获取物品
- @item = @forge_window.item
- # 获取物品的所持数
- case@item
- whenRPG::Item
- number = @forge_window.item_number
- typetemp = 0
- whenRPG::Weapon
- number = @forge_window.item_number
- typetemp = 1
- whenRPG::Armor
- number = @forge_window.item_number
- typetemp = 2
- end
- if number != nil
- # 更改合成窗口的物品
- case@item
- whenRPG::Item
- $game_party.gain_item(@item.id, 1)
- whenRPG::Weapon
- $game_party.gain_weapon(@item.id, 1)
- whenRPG::Armor
- $game_party.gain_armor(@item.id, 1)
- end
- #p number
- forge_change(typetemp, @item.id, -1)
- # 刷新各窗口
- @item_window.refresh
- @forge_window.refresh
- @help_window.update
- @item_window.update
- @forge_window.update
- end
- end
- # 按下 左方向键 的情况下
- if Input.trigger?(Input::LEFT)
- # 切换到合成窗口
- @forge_window.active = false
- @item_window.active = true
- end
- end
- #--------------------------------------------------------------------------
- # ● 更改合成窗口物品
- #--------------------------------------------------------------------------
- def forge_change(type,id,number)
- quantity = number
- for item in$game_temp.forge
- if(item[0]==type)and(item[1]==id)
- item[2] = [item[2] += quantity,99].min
- if item[2] == 0
- $game_temp.forge.delete(item)
- end
- return
- end
- end
- $game_temp.forge.push([type,id,number])
- end
- #--------------------------------------------------------------------------
- # ● 放弃合成
- #--------------------------------------------------------------------------
- def abort
- # 将合成窗口中的物品转移至物品窗口中
- for item in$game_temp.forge
- # 判断物品类型并归还
- case item[0]
- when0
- $game_party.gain_item(item[1], item[2])
- when1
- $game_party.gain_weapon(item[1], item[2])
- when2
- $game_party.gain_armor(item[1], item[2])
- end
- end
- $game_temp.forge = []
- # 刷新各窗口
- @item_window.refresh
- @forge_window.refresh
- end
- #--------------------------------------------------------------------------
- # ● 检测是否有符合的配方
- #--------------------------------------------------------------------------
- def match
- match_one = false
- match_this = false
- # 检测每一个配方
- for i in[email]0...@formulas.size[/email]
- # 将合成窗口中的物品复制到合成缓存区
- # 注意: 直接使用"="将传引用 导致检测配方是否匹配时合成窗口中物品被删除
- @forge = $game_temp.forge.dup
- # 检测这个配方中每一项材料
- for ingredient in@formulas[i]
- match_this = true
- # 合成区中没有此项材料的情况
- unless@forge.include?(ingredient)
- match_this = false
- break
- end
- # 从合成区中暂时删除这项材料
- @forge.delete(ingredient)
- end
- if match_this == false
- next
- end
- # 检测合成区中是否还有配方外的材料剩余
- unless@forge == []
- match_this = false
- end
- # 满足这一个配方的情况
- if match_this == true
- match_one = true
- # 获取配方的成品
- @products_temp = @products[i]
- break
- end
- end
- return match_one
- end
- #--------------------------------------------------------------------------
- # ● 合成
- #--------------------------------------------------------------------------
- def compose
- # 如果有符合的配方
- if match
- # 将合成窗口中的材料改变为成品
- $game_temp.forge = []
- for i in[email]0...@products_temp.size[/email]
- forge_change(@products_temp[i][0], @products_temp[i][1], @products_temp[i][2])
- end
- if$SE_Compose_Successful != ""
- Audio.se_play($SE_Compose_Successful)
- end
- # 合成失败的情况
- else
- if$SE_Compose_Failed != ""
- Audio.se_play($SE_Compose_Failed)
- end
- if$Ingredient_Lost_When_Fail
- $game_temp.forge = []
- end
- end
- # 刷新各窗口
- @item_window.refresh
- @forge_window.refresh
- end
- end
复制代码
详细介绍已经在代码注释上了,是一个朋友叫我代发的,他可能不能上6R,作者:Summoner
我试用过了,上面也注释的很清楚。
调用语句为:$scene = Scene_Compose.new
过后等待2帧
上图
像这样 回复剂放入3个后按合成即可,也可以放入一个圣灵药,再按合成,就分解出物品来,详细代码上注释的很清楚。
好吧,还是附上范例,其实也没什么可说的。
本帖来自P1论坛作者纳尔德,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:
https://rpg.blue/forum.php?mod=viewthread&tid=245186 若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。