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

Project1

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

[原创发布] 【教程】如何制作储物箱

[复制链接]

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

跳转到指定楼层
1
发表于 2021-7-27 20:48:35 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 guoxiaomi 于 2021-7-28 11:09 编辑

相关问题:
https://rpg.blue/thread-486363-1-1.html

示意图:


解决这个问题,通常的做法是创建一个Scene类,然后用事件call这个类,就跟使用商店一样。上面的示意图也就是我们所想要的效果:整个场景分为4部分,当左下或者右下窗口激活时,按下空格来交换队伍里的物品和储物箱里的物品。
接下来我会仔细的讲解该如何写这个脚本。对于RGSS的初学者来说,可以当作写Scene的教程。这个教程会逐步完善场景类所需的各种内容,并且每完成一小部分就会展示一下效果。

【第一节:场景类的基本结构】
首先创建一个模块,以避免跟其他的脚本同名,后续的所有类的定义都是在这个模块里进行。这里使用提问者的名字Taeckle作为模块名。
接下来创建场景的类Scene_Storage。这个场景的类需要包括:

1. main方法,在范例里,main方法被拆分成了3部分:create_windowsscene_loopdispose_windows
create_windows 用来创建4个窗口,使用几个比较基础的窗口类作为place holder,这里只是用来检查窗口位置是否正确,此方法会在后面的步骤里被新的定义覆盖:
RUBY 代码复制
  1. # ----------------------------------------- #
  2. # Help Window (640 x 64)                    #
  3. # ----------------------------------------- #
  4. # Menu Window (640 x 64)                    #
  5. # --------------------+-------------------- #
  6. # Item Window Party   | Item Window Storage #
  7. #    (320 x 352)      |    (320 x 352)      #
  8. # --------------------+-------------------- #
  9. def create_windows
  10.   # Help Window
  11.   @help_window = Window_Help.new
  12.   # Horizontal Command Window
  13.   @menu_window = Window_Selectable.new(0, 64, 640, 64)
  14.   # Item Window left: Party items
  15.   @item_window_party = Window_Selectable.new(0, 128, 320, 480 - 64 * 2)
  16.   # Item Window right: Storage items
  17.   @item_window_storage = Window_Selectable.new(320, 128, 320, 480 - 64 * 2)
  18. end


scene_loop 直接照抄RGSS的内容。dispose_windows使用RGSS3的风格,将属于Scene的所有Window类的实例对象关闭。

由于scene_loop里呼叫了update方法,所以还需要创建一个空的update方法。

2. 数据的处理,这个场景涉及到RGSS以外的数据。所以需要定义数据的类型Data,以及场景所需的实例变量@data
考虑到具体要解决的问题是储物箱,所以该场景要占用一个全局变量来存储数据,把这个变量的ID传给场景的initialize方法。顺便传递了储存箱最大能装的数量作为第2个参数。
RUBY 代码复制
  1. def initialize(data_vid, item_max_size = 99)
  2.   @scene_class = $scene.class
  3.   @item_max_size = [item_max_size, 99].min
  4.   if !$game_variables[data_vid].is_a?(Data)
  5.     $game_variables[data_vid] = Data.new
  6.   end
  7.   @data = $game_variables[data_vid]
  8. end

在initialize方法里,会检测传入的全局变量是否为Data类型,如果不是就初始化一下,然后绑定此全局变量。

储物箱应该要提供存入和取出两个方法。定义storefetch两个空方法,其参数是要存储的东西和数量(默认为1)

最终脚本如下:
RUBY 代码复制下载
  1. # encoding: utf-8
  2. module Taeckle
  3.   @version = "0.1"
  4.  
  5.   class Data
  6.   end
  7.  
  8.   class Scene_Storage
  9.     attr_reader :data
  10.  
  11.     def initialize(data_vid, item_max_size = 99)
  12.       @scene_class = $scene.class
  13.       @item_max_size = [item_max_size, 99].min
  14.       if !$game_variables[data_vid].is_a?(Data)
  15.         $game_variables[data_vid] = Data.new
  16.       end
  17.       @data = $game_variables[data_vid]
  18.     end
  19.  
  20.     def main
  21.       create_windows
  22.       scene_loop
  23.       dispose_windows
  24.     end
  25.  
  26.     # layout
  27.     # ----------------------------------------- #
  28.     # Help Window (640 x 64)                    #
  29.     # ----------------------------------------- #
  30.     # Menu Window (640 x 64)                    #
  31.     # --------------------+-------------------- #
  32.     # Item Window Party   | Item Window Storage #
  33.     #    (320 x 352)      |    (320 x 352)      #
  34.     # --------------------+-------------------- #
  35.     def create_windows
  36.       # Help Window
  37.       @help_window = Window_Help.new
  38.       # Horizontal Command Window
  39.       @menu_window = Window_Selectable.new(0, 64, 640, 64)
  40.       # Item Window left: Party items
  41.       @item_window_party = Window_Selectable.new(0, 128, 320, 480 - 64 * 2)
  42.       # Item Window right: Storage items
  43.       @item_window_storage = Window_Selectable.new(320, 128, 320, 480 - 64 * 2)
  44.     end
  45.  
  46.     def update
  47.     end
  48.  
  49.     def scene_loop
  50.       Graphics.transition
  51.       # 主循环
  52.       loop do
  53.         # 刷新游戏画面
  54.         Graphics.update
  55.         # 刷新输入信息
  56.         Input.update
  57.         # 刷新画面
  58.         update
  59.         # 如果画面切换就中断循环
  60.         if $scene != self
  61.           break
  62.         end
  63.       end
  64.       # 准备过渡
  65.       Graphics.freeze
  66.     end
  67.  
  68.     def dispose_windows
  69.       self.instance_variables.each do |name|
  70.         obj = self.instance_variable_get(name)
  71.         obj.dispose if obj.is_a?(Window)
  72.       end
  73.     end
  74.  
  75.     def store(item, number = 1)
  76.     end
  77.  
  78.     def fetch(item, number = 1)
  79.     end
  80.   end
  81. end


【第二节:测试工程】
创建一个空白的工程,并且将写好的scene_storage_base.rb插入到脚本编辑器的main前。根据具体的需求,创建如下自动事件:

按F12执行,进入新游戏后,自动执行本事件,就会进入到Scene_Storage里了。这个时候场景里还是一片空白:


【第三节:数据结构】
接下来我们需要完善Data类,以及storefetch两个方法。ruby允许随时打开一个类添加新的内容,也允许覆盖原来的同名方法。

1. Data类是存储在箱子里的物品、武器等。所以Data类可以直接套用Game_Party的部分内容:
RUBY 代码复制
  1. class Data
  2.   attr_reader :item
  3.   attr_reader :weapons
  4.   attr_reader :armors
  5.  
  6.   def initialize
  7.     @items = {}
  8.     @weapons = {}
  9.     @armors = {}
  10.   end
  11.  
  12.   # ...
  13. end
复制粘贴Game_Party的item_number, weapon_number, armor_number, gain_item, gain_weapon, gain_armor这6个方法即可。
由于拥有完全相同的6个方法和对应的数据结构,Game_Party和Data的实例在某些地方可以互相替换。详见后面的@bind_data部分。

2. store方法,需要根据传入的变量的不同类型(item/weapon/armor),来选择调用指定的方法。此外,当箱子或者队伍的背包已经满了的时候,就不能继续放入物品,定义一个函数来判断这种情况:
RUBY 代码复制
  1. def can_store?(num_party, num_storage, number)
  2.   num_party - number >= 0 && num_party - number <= 99 && num_storage + number >= 0 && num_storage + number <= @item_max_size
  3. end
考虑到存储物品可能会失败,store方法的返回值是true或者false,以表示这次存储是成功还是失败。

fetch方法就是store方法,只不过第二个参数是负的。
最终脚本如下:
RUBY 代码复制下载
  1. # encoding: utf-8
  2. module Taeckle
  3.   @version = "0.2"
  4.  
  5.   class Data
  6.     attr_reader :item
  7.     attr_reader :weapons
  8.     attr_reader :armors
  9.  
  10.     def initialize
  11.       @items = {}
  12.       @weapons = {}
  13.       @armors = {}
  14.     end
  15.  
  16.     #--------------------------------------------------------------------------
  17.     # ● 获取物品的所持数
  18.     #     item_id : 物品 ID
  19.     #--------------------------------------------------------------------------
  20.     def item_number(item_id)
  21.       # 如果 hash 个数数值不存在就返回 0
  22.       return @items.include?(item_id) ? @items[item_id] : 0
  23.     end
  24.  
  25.     #--------------------------------------------------------------------------
  26.     # ● 获取武器所持数
  27.     #     weapon_id : 武器 ID
  28.     #--------------------------------------------------------------------------
  29.     def weapon_number(weapon_id)
  30.       # 如果 hash 个数数值不存在就返回 0
  31.       return @weapons.include?(weapon_id) ? @weapons[weapon_id] : 0
  32.     end
  33.  
  34.     #--------------------------------------------------------------------------
  35.     # ● 获取防具所持数
  36.     #     armor_id : 防具 ID
  37.     #--------------------------------------------------------------------------
  38.     def armor_number(armor_id)
  39.       # 如果 hash 个数数值不存在就返回 0
  40.       return @armors.include?(armor_id) ? @armors[armor_id] : 0
  41.     end
  42.  
  43.     #--------------------------------------------------------------------------
  44.     # ● 增加物品 (减少)
  45.     #     item_id : 物品 ID
  46.     #     n       : 个数
  47.     #--------------------------------------------------------------------------
  48.     def gain_item(item_id, n)
  49.       # 更新 hash 的个数数据
  50.       if item_id > 0
  51.         @items[item_id] = [[item_number(item_id) + n, 0].max, 99].min
  52.       end
  53.     end
  54.  
  55.     #--------------------------------------------------------------------------
  56.     # ● 增加武器 (减少)
  57.     #     weapon_id : 武器 ID
  58.     #     n         : 个数
  59.     #--------------------------------------------------------------------------
  60.     def gain_weapon(weapon_id, n)
  61.       # 更新 hash 的个数数据
  62.       if weapon_id > 0
  63.         @weapons[weapon_id] = [[weapon_number(weapon_id) + n, 0].max, 99].min
  64.       end
  65.     end
  66.  
  67.     #--------------------------------------------------------------------------
  68.     # ● 增加防具 (减少)
  69.     #     armor_id : 防具 ID
  70.     #     n        : 个数
  71.     #--------------------------------------------------------------------------
  72.     def gain_armor(armor_id, n)
  73.       # 更新 hash 的个数数据
  74.       if armor_id > 0
  75.         @armors[armor_id] = [[armor_number(armor_id) + n, 0].max, 99].min
  76.       end
  77.     end
  78.   end
  79.  
  80.   class Scene_Storage
  81.     def store(item, number = 1)
  82.       # RPG::Item
  83.       if item.is_a?(RPG::Item)
  84.         num_party = $game_party.item_number(item.id)
  85.         num_storage = @data.item_number(item.id)
  86.         if can_store?(num_party, num_storage, number)
  87.           $game_party.lose_item(item.id, number)
  88.           @data.gain_item(item.id, number)
  89.           return true
  90.         end
  91.       end
  92.       # RPG::Weapon
  93.       if item.is_a?(RPG::Weapon)
  94.         num_party = $game_party.weapon_number(item.id)
  95.         num_storage = @data.weapon_number(item.id)
  96.         if can_store?(num_party, num_storage, number)
  97.           $game_party.lose_weapon(item.id, number)
  98.           @data.gain_weapon(item.id, number)
  99.           return true
  100.         end
  101.       end
  102.       # RPG::Armor
  103.       if item.is_a?(RPG::Armor)
  104.         num_party = $game_party.armor_number(item.id)
  105.         num_storage = @data.armor_number(item.id)
  106.         if can_store?(num_party, num_storage, number)
  107.           $game_party.lose_armor(item.id, number)
  108.           @data.gain_armor(item.id, number)
  109.           return true
  110.         end
  111.       end
  112.       return false
  113.     end
  114.  
  115.     def fetch(item, number = 1)
  116.       store(item, -number)
  117.     end
  118.  
  119.     def can_store?(num_party, num_storage, number)
  120.       num_party - number >= 0 && num_party - number <= 99 && num_storage + number >= 0 && num_storage + number <= @item_max_size
  121.     end
  122.   end
  123. end
将这个脚本加入到编辑器里,再次测试,应该得到跟第二节一样的效果。因为我们还没有写具体的窗口绘制。

【第四节:场景的update】
接下来我们要实现留空的update方法。在这个具体的任务里,有3个窗口,我们绘制一张简图来描述场景里各个窗口之间的切换:

这部分比较考验对RGSS的熟悉程度,总之按照RGSS的写法:
首先更新@help_window,然后依次判断是否有窗口处于active的状态,如果是就执行这个窗口的更新,主要是处理各个按键触发时要执行的内容。记得加上SE,以及各窗口refresh的时机和修改index = -1以隐藏光标。这些细节可以仔细阅读RGSS默认的各个Scene的update的实现。
注意在选择“退出”的写法,@scene_class记录了上一个场景的类(在initialize方法里),退出时利用这个值恢复了上一个场景。不定义这个变量,在此处直接写$scene = Scene_Map.new也是一样的。

然后我们需要定义各个窗口类,并设置好窗口创建时的初始状态。
1. Window_Help,直接就是RGSS默认的Window_Help:
RUBY 代码复制
  1. class Window_Help < ::Window_Help
  2. end

2. Window_Menu,有可以移动的光标,所以继承自Window_Selectable。这里要参考RGSS默认的Window_ShopCommand的写法。由于绑定了@help_window,所以需要定义update_help方法:
RUBY 代码复制
  1. def update_help
  2.   case @index
  3.   when 0 then text = "存入物品"
  4.   when 1 then text = "取出物品"
  5.   when 2 then text = "离开场景"
  6.   end
  7.   @help_window.set_text(text, 1)
  8. end

3. Window_Item,左下和右下两个窗口,都是展示携带的物品,所以可以用同一种窗口类来实现。这两个窗口除了位置不同外,唯一的区别就是展示的数据不同,所以定义@bind_data这个实例变量表示要展示的数据来源。对于左下窗口,@bind_data = $game_party;对于右下窗口@bind_data = $scene.data。同样有可以移动的光标,所以也继承自Window_Selectable。

定义三个空方法待后续完善:item,refresh和update_help。item需要返回此窗口当前被选中的item,供场景类的store和fetch调用。
RUBY 代码复制
  1. class Window_Item < ::Window_Selectable
  2.   attr_accessor :bind_data
  3.  
  4.   def item
  5.   end
  6.  
  7.   def refresh
  8.   end
  9.  
  10.   def update_help
  11.   end
  12. end


定义好了所有的窗口后,覆写create_windows方法,将这些窗口添加到类里,并且设置正确的位置和初始条件。尤其要注意bind_data的设置。最终脚本如下:
RUBY 代码复制下载
  1. # encoding: utf-8
  2.  
  3. module Taeckle
  4.   @version = "0.3"
  5.  
  6.   class Scene_Storage
  7.     def update
  8.       @help_window.update
  9.       # update active window
  10.       if @menu_window.active
  11.         @menu_window.update
  12.         if Input.trigger?(Input::C)
  13.           $game_system.se_play($data_system.decision_se)
  14.           case @menu_window.index
  15.           when 0
  16.             @item_window_party.active = true
  17.             @menu_window.active = false
  18.             if @item_window_party.index == -1
  19.               @item_window_party.index = 0
  20.             end
  21.           when 1
  22.             @item_window_storage.active = true
  23.             @menu_window.active = false
  24.             if @item_window_storage.index == -1
  25.               @item_window_storage.index = 0
  26.             end
  27.           when 2
  28.             $scene = @scene_class.new
  29.             return
  30.           end
  31.           @item_window_party.refresh
  32.           @item_window_storage.refresh
  33.         end
  34.         return
  35.       end
  36.  
  37.       if @item_window_party.active
  38.         @item_window_party.update
  39.         if Input.trigger?(Input::B)
  40.           $game_system.se_play($data_system.cancel_se)
  41.           @item_window_party.active = false
  42.           @menu_window.active = true
  43.           @item_window_party.index = -1
  44.           @item_window_storage.index = -1
  45.           @item_window_party.refresh
  46.           @item_window_storage.refresh
  47.         end
  48.         if Input.trigger?(Input::C)
  49.           ret = store(@item_window_party.item)
  50.           if ret
  51.             $game_system.se_play($data_system.decision_se)
  52.             @item_window_party.refresh
  53.             @item_window_storage.refresh
  54.           else
  55.             $game_system.se_play($data_system.buzzer_se)
  56.           end
  57.         end
  58.         return
  59.       end
  60.  
  61.       if @item_window_storage.active
  62.         @item_window_storage.update
  63.         if Input.trigger?(Input::B)
  64.           $game_system.se_play($data_system.cancel_se)
  65.           @item_window_storage.active = false
  66.           @menu_window.active = true
  67.           @item_window_party.index = -1
  68.           @item_window_storage.index = -1
  69.           @item_window_party.refresh
  70.           @item_window_storage.refresh
  71.         end
  72.         if Input.trigger?(Input::C)
  73.           ret = fetch(@item_window_storage.item)
  74.           if ret
  75.             $game_system.se_play($data_system.decision_se)
  76.             @item_window_party.refresh
  77.             @item_window_storage.refresh
  78.           else
  79.             $game_system.se_play($data_system.buzzer_se)
  80.           end
  81.         end
  82.         return
  83.       end
  84.     end
  85.  
  86.     def create_windows
  87.       # Help Window
  88.       @help_window = Window_Help.new
  89.       # Horizontal Command Window
  90.       @menu_window = Window_Menu.new
  91.       @menu_window.active = true
  92.       # Item Window left: Party items
  93.       @item_window_party = Window_Item.new(0, 128, 320, 352)
  94.       @item_window_party.bind_data = $game_party
  95.       @item_window_party.active = false
  96.       @item_window_party.index = -1
  97.       @item_window_party.refresh
  98.       # Item Window right: Storage items
  99.       @item_window_storage = Window_Item.new(320, 128, 320, 352)
  100.       @item_window_storage.bind_data = @data
  101.       @item_window_storage.active = false
  102.       @item_window_storage.index = -1
  103.       @item_window_storage.refresh
  104.       # binding help windows
  105.       @menu_window.help_window = @help_window
  106.       @item_window_party.help_window = @help_window
  107.       @item_window_storage.help_window = @help_window
  108.     end
  109.   end
  110.  
  111.   class Window_Help < ::Window_Help
  112.   end
  113.  
  114.   class Window_Menu < ::Window_Selectable
  115.     def initialize
  116.       super(0, 64, 640, 64)
  117.       @item_max = 3
  118.       @column_max = 3
  119.       @index = 0
  120.       @commands = ["存入", "取出", "离开"]
  121.       self.contents = Bitmap.new(width - 32, height - 32)
  122.       refresh
  123.     end
  124.  
  125.     #--------------------------------------------------------------------------
  126.     # ● 刷新
  127.     #--------------------------------------------------------------------------
  128.     def refresh
  129.       self.contents.clear
  130.       for i in 0...@item_max
  131.         draw_item(i)
  132.       end
  133.     end
  134.  
  135.     #--------------------------------------------------------------------------
  136.     # ● 描绘项目
  137.     #     index : 项目编号
  138.     #--------------------------------------------------------------------------
  139.     def draw_item(index)
  140.       self.contents.draw_text(index * 212 - 12, 0, 212, 32, @commands[index], 1)
  141.     end
  142.  
  143.     def update_help
  144.       case @index
  145.       when 0 then text = "存入物品"
  146.       when 1 then text = "取出物品"
  147.       when 2 then text = "离开场景"
  148.       end
  149.       @help_window.set_text(text, 1)
  150.     end
  151.   end
  152.  
  153.   class Window_Item < ::Window_Selectable
  154.     attr_accessor :bind_data
  155.  
  156.     def item
  157.     end
  158.  
  159.     def refresh
  160.     end
  161.  
  162.     def update_help
  163.     end
  164.   end
  165. end
将这个脚本加入到F11脚本编辑器,执行可以看到如下效果:

可以看到场景里各项window的切换已经做好了,只是现在还没有做好队伍携带的物品的显示。有对齐强迫症的,可以仔细修改Window_Menu的draw_item方法里面的212和-12这两个参数。

【第五节:显示物品的窗口】
刚才给Window_Item留下了3个空的方法:item,refresh和update_help。这里item和update_help照抄RGSS默认的Window_Item。refresh和被refresh调用的draw_item也是基本照抄,但是需要做几点修改:
1. 将所有的$game_party替换成@bind_data
2. 默认的Window_Item是两列,而这个脚本里是一列,修改draw_item里的x和y的设置
3. 默认draw_item会让无法使用的物品显示灰色,改成当前窗口未激活则所有物品显示灰色
4. (可选)额外的需求要求物品按照其desc属性来排序,在refresh方法里添加按照desc排序的内容:
RUBY 代码复制
  1. # Sort by description
  2. if @data.first.respond_to?(:desc)
  3.   @data.sort! { |a, b| a.desc <=> b.desc }
  4. end


最终脚本如下:
RUBY 代码复制下载
  1. # encoding: utf-8
  2. module Taeckle
  3.   @version = "0.4"
  4.  
  5.   class Window_Item
  6.     #--------------------------------------------------------------------------
  7.     # ● 获取物品
  8.     #--------------------------------------------------------------------------
  9.     def item
  10.       return @data[self.index]
  11.     end
  12.  
  13.     #--------------------------------------------------------------------------
  14.     # ● 刷新
  15.     #--------------------------------------------------------------------------
  16.     def refresh
  17.       if self.contents != nil
  18.         self.contents.dispose
  19.         self.contents = nil
  20.       end
  21.       @data = []
  22.       # 添加物品
  23.       for i in 1...$data_items.size
  24.         if @bind_data.item_number(i) > 0
  25.           @data.push($data_items[i])
  26.         end
  27.       end
  28.       # 在战斗中以外添加武器、防具
  29.       unless $game_temp.in_battle
  30.         for i in 1...$data_weapons.size
  31.           if @bind_data.weapon_number(i) > 0
  32.             @data.push($data_weapons[i])
  33.           end
  34.         end
  35.         for i in 1...$data_armors.size
  36.           if @bind_data.armor_number(i) > 0
  37.             @data.push($data_armors[i])
  38.           end
  39.         end
  40.       end
  41.       # Sort by description
  42.       if @data.first.respond_to?(:desc)
  43.         @data.sort! { |a, b| a.desc <=> b.desc }
  44.       end
  45.       # 如果项目数不是 0 就生成位图、重新描绘全部项目
  46.       @item_max = @data.size
  47.       if @item_max > 0
  48.         self.contents = Bitmap.new(width - 32, row_max * 32)
  49.         for i in 0...@item_max
  50.           draw_item(i)
  51.         end
  52.       end
  53.     end
  54.  
  55.     #--------------------------------------------------------------------------
  56.     # ● 描绘项目
  57.     #     index : 项目编号
  58.     #--------------------------------------------------------------------------
  59.     def draw_item(index)
  60.       item = @data[index]
  61.       case item
  62.       when RPG::Item
  63.         number = @bind_data.item_number(item.id)
  64.       when RPG::Weapon
  65.         number = @bind_data.weapon_number(item.id)
  66.       when RPG::Armor
  67.         number = @bind_data.armor_number(item.id)
  68.       end
  69.       if self.active
  70.         self.contents.font.color = normal_color
  71.       else
  72.         self.contents.font.color = disabled_color
  73.       end
  74.       x = 4
  75.       y = index * 32
  76.       rect = Rect.new(x, y, self.width / @column_max - 32, 32)
  77.       self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
  78.       bitmap = RPG::Cache.icon(item.icon_name)
  79.       opacity = self.contents.font.color == normal_color ? 255 : 128
  80.       self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
  81.       self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
  82.       self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
  83.       self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  84.     end
  85.  
  86.     #--------------------------------------------------------------------------
  87.     # ● 刷新帮助文本
  88.     #--------------------------------------------------------------------------
  89.     def update_help
  90.       @help_window.set_text(self.item == nil ? "" : self.item.description)
  91.     end
  92.   end
  93. end

将这段脚本添加到F11脚本编辑器里,效果如图:

范例如下:
20210727-storage.zip (208.06 KB, 下载次数: 78)

使用的小技巧:
1. 由于数据存储在全局变量里,会跟随存档一起存下来。
2. 场景绑定不同的变量就会对应不同的储物箱。
3. 如果预先设置好变量的内容,就可以做到储物箱在第一次打开时就有东西了。
  1. $game_variables[2] = Taeckle::Data.new
  2. $game_variables[2].gain_item(1, 1)
复制代码

4. 设置可以存储的物品上限为0,并且在箱子里的每件物品数量恰好为1,此时箱子里的物品只能取出不能放回。
5. 可以在条件分歧里使用脚本里检查箱子里的内容:
  1. $game_variables[2].item_number(1) > 0
复制代码

Screenshot 2021-07-27 182754.png (76.86 KB, 下载次数: 13)

Screenshot 2021-07-27 182754.png

评分

参与人数 8星屑 +500 +8 收起 理由
cm123 + 1 我很赞同
猫过敏 + 1
plain666 + 1 塞糖
黑夜守望者 + 1 精品文章
taeckle + 1 神的指引!
y967 + 1 优秀
RyanBern + 500 + 1 精品文章
enghao_lim + 1 塞糖

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

2
 楼主| 发表于 2021-7-27 20:55:21 | 只看该作者
@taeckle 你可以照着这个来学习

点评

多谢啦!  发表于 2021-7-30 15:52

评分

参与人数 1+1 收起 理由
taeckle + 1 多谢大神指点!

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
2125
在线时间
234 小时
注册时间
2018-3-23
帖子
100
3
发表于 2021-7-27 22:03:01 | 只看该作者
好顶赞醋虾
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1223
在线时间
149 小时
注册时间
2021-6-19
帖子
20
4
发表于 2021-7-28 00:59:39 | 只看该作者
有大佬快拜!!感謝教學~
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

梦石
0
星屑
9497
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

5
发表于 2021-7-28 09:05:34 | 只看该作者
太强了,已经加入图书馆豪华套餐。
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
692
在线时间
42 小时
注册时间
2021-1-26
帖子
40
6
发表于 2021-7-28 09:28:13 | 只看该作者
哦,懂了(小白一个,完全没有看懂)。
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9128
在线时间
463 小时
注册时间
2015-5-8
帖子
865
7
发表于 2021-7-30 15:51:58 | 只看该作者
我要好好学习下!
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9128
在线时间
463 小时
注册时间
2015-5-8
帖子
865
8
发表于 2021-7-31 01:08:40 | 只看该作者
大神我还有一个问题,

你上传脚本里的vscode, main.rb, rpg_desc.rb, scene_storage_base.rb,scene_storage_core.rb, scene_storage_data.rb, scene_storage_item.rb 要怎么打开啊?能直接复制粘贴到RPG Maker XP自带的脚本里吗?

点评

好,我去试试  发表于 2021-7-31 08:30
建议下载vscode:https://code.visualstudio.com/,记事本打开也可以。而且全部脚本在这个帖子里也能找到。  发表于 2021-7-31 01:35
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9128
在线时间
463 小时
注册时间
2015-5-8
帖子
865
9
发表于 2021-8-5 01:51:23 | 只看该作者
本帖最后由 taeckle 于 2021-8-5 01:54 编辑
guoxiaomi 发表于 2021-7-27 20:55
@taeckle 你可以照着这个来学习


还有大神请问下我要是想在上面这个脚本的基础上增加个放置在picture文件下的一个背景图片(比如背景图片就叫做"储物箱.png"),是不是直接就在def main里面添加上:

@menu_com.bitmap = RPG::Cache.picture("储物箱.png") 这句就行啦?

此外还需要多写一个释放这个背景图片的dispose吗?



点评

对啊  发表于 2021-8-5 11:11
是RPG Maker XP 默认脚本内的Scene_Battle设置战斗背景部分吗?  发表于 2021-8-5 03:54
参考Scene_Battle设置战斗背景的部分  发表于 2021-8-5 02:06
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9128
在线时间
463 小时
注册时间
2015-5-8
帖子
865
10
发表于 2021-8-9 00:25:53 | 只看该作者
本帖最后由 taeckle 于 2021-8-9 00:37 编辑

大神可以把这个脚本所有的相关代码整合到一个版本号里吗? 多谢了

比如你的最终版本(version 0.4)缺少了Scene_Storage类还有Data类,看得有点晕


还有你的0.3版本定义Window_Item的时候都是:

class Window_Item < ::Window_Selectable
    attr_accessor :bind_data

为何到了0.4版本也没继承了,直接一个  class Window_Item。。

看到这里咱又直接晕菜....


点评

已经在前面写过继承关系,后面就可以不写了  发表于 2021-8-9 01:03
把这4个版本按照顺序都拷贝进去就可以了  发表于 2021-8-9 00:54
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-26 09:00

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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