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

Project1

 找回密码
 注册会员
搜索
楼主: guoxiaomi
打印 上一主题 下一主题

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

[复制链接]

Lv4.逐梦者

梦石
0
星屑
9163
在线时间
466 小时
注册时间
2015-5-8
帖子
866
21
发表于 2021-8-24 01:53:00 | 只看该作者
本帖最后由 taeckle 于 2021-8-24 01:54 编辑
taeckle 发表于 2021-8-23 15:48
@guoxiaomi

好的,大神我还有个问题:


大神这是你要的p出$game_variables[2]后的截图:




变量2.PNG (84.05 KB, 下载次数: 31)

变量2.PNG

点评

这个说起来就很复杂了……建议了解到“ruby里每个对象都有独一无二的ID”为止,更多的以后再说  发表于 2021-8-31 21:52
那在这里对象是那个Data, ID又是神马?0x3e708e0?  发表于 2021-8-31 20:18
对象的类和ID。你想p出具体的内容就要主动实现inspect方法  发表于 2021-8-31 18:14
大神那这到底是神马?  发表于 2021-8-31 16:11
这不是乱码又是啥啊?  发表于 2021-8-24 18:05
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9163
在线时间
466 小时
注册时间
2015-5-8
帖子
866
22
发表于 2021-8-24 05:15:24 | 只看该作者
本帖最后由 taeckle 于 2021-8-25 05:34 编辑

报告大神,您在本帖第14楼布置的家庭作业(新增箱子内部所有物品武器防具数量之和不超过2X$game_variables[1])做完了,请过目:

RUBY 代码复制
  1. # encoding: utf-8
  2. module Taeckle
  3.   @version = "0.5"  #先更新下版本号_家庭作业
  4.  
  5.   class Data
  6.     attr_reader :items
  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.     # ● 获取(箱子内或身上)所有物品的数量之和 (Version 0.5的更新_家庭作业)
  26.     def item_number_all
  27.        @item_number_in_all=0
  28.         for i in 0...@items.values.size
  29.           @item_number_in_all +=@items.values[i]
  30.         end  
  31.       return @item_number_in_all
  32.     end   
  33.  
  34.     #--------------------------------------------------------------------------
  35.     # ● 获取武器所持数
  36.     #     weapon_id : 武器 ID
  37.     #--------------------------------------------------------------------------
  38.     def weapon_number(weapon_id)
  39.       # 如果 hash 个数数值不存在就返回 0
  40.       return @weapons.include?(weapon_id) ? @weapons[weapon_id] : 0
  41.     end
  42.  
  43.     # ● 获取(箱子内或身上)所有武器的数量之和 (Version 0.5的更新_家庭作业)
  44.     def weapon_number_all
  45.        @weapon_number_in_all=0
  46.         for i in 0...@weapons.values.size
  47.           @weapon_number_in_all +=@weapons.values[i]
  48.         end  
  49.       return @weapon_number_in_all
  50.     end  
  51.     #--------------------------------------------------------------------------
  52.     # ● 获取防具所持数
  53.     #     armor_id : 防具 ID
  54.     #--------------------------------------------------------------------------
  55.     def armor_number(armor_id)
  56.       # 如果 hash 个数数值不存在就返回 0
  57.       return @armors.include?(armor_id) ? @armors[armor_id] : 0
  58.     end
  59.  
  60.     # ● 获取(箱子内或身上)所有防具的数量之和 (Version 0.5的更新_家庭作业)
  61.     def armor_number_all
  62.        @armor_number_in_all=0
  63.         for i in 0...@armors.values.size
  64.           @armor_number_in_all +=@armors.values[i]
  65.         end  
  66.       return @armor_number_in_all
  67.     end      
  68.     #--------------------------------------------------------------------------
  69.     # ● 增加物品 (减少)
  70.     #     item_id : 物品 ID
  71.     #     n       : 个数
  72.     #--------------------------------------------------------------------------
  73.     def gain_item(item_id, n)
  74.       # 更新 hash 的个数数据
  75.       if item_id > 0
  76.         @items[item_id] = [[item_number(item_id) + n, 0].max, 99].min
  77.       end
  78.     end
  79.  
  80.     #--------------------------------------------------------------------------
  81.     # ● 增加武器 (减少)
  82.     #     weapon_id : 武器 ID
  83.     #     n         : 个数
  84.     #--------------------------------------------------------------------------
  85.     def gain_weapon(weapon_id, n)
  86.       # 更新 hash 的个数数据
  87.       if weapon_id > 0
  88.         @weapons[weapon_id] = [[weapon_number(weapon_id) + n, 0].max, 99].min
  89.       end
  90.     end
  91.  
  92.     #--------------------------------------------------------------------------
  93.     # ● 增加防具 (减少)
  94.     #     armor_id : 防具 ID
  95.     #     n        : 个数
  96.     #--------------------------------------------------------------------------
  97.     def gain_armor(armor_id, n)
  98.       # 更新 hash 的个数数据
  99.       if armor_id > 0
  100.         @armors[armor_id] = [[armor_number(armor_id) + n, 0].max, 99].min
  101.       end
  102.     end   
  103.   end
  104.  
  105.   class Window_Help < ::Window_Help
  106.   end
  107.  
  108.   class Window_Menu < ::Window_Selectable
  109.     def initialize
  110.       super(0, 64, 640, 64)
  111.       @item_max = 3
  112.       @column_max = 3
  113.       @index = 0
  114.       @commands = ["存入", "取出", "离开"]
  115.       self.contents = Bitmap.new(width - 32, height - 32)
  116.       refresh
  117.     end
  118.  
  119.     #--------------------------------------------------------------------------
  120.     # ● 刷新
  121.     #--------------------------------------------------------------------------
  122.     def refresh
  123.       self.contents.clear
  124.       for i in 0...@item_max
  125.         draw_item(i)
  126.       end
  127.     end
  128.  
  129.     #--------------------------------------------------------------------------
  130.     # ● 描绘项目
  131.     #     index : 项目编号
  132.     #--------------------------------------------------------------------------
  133.     def draw_item(index)
  134.       self.contents.draw_text(index * 212 - 12, 0, 212, 32, @commands[index], 1)
  135.     end
  136.  
  137.     def update_help
  138.       case @index
  139.       when 0 then text = "存入物品"
  140.       when 1 then text = "取出物品"
  141.       when 2 then text = "离开场景"
  142.       end
  143.       @help_window.set_text(text, 1)
  144.     end
  145.   end
  146.  
  147.   class Window_Item< ::Window_Selectable
  148.  
  149.   attr_accessor :bind_data   
  150.     #--------------------------------------------------------------------------
  151.     # ● 获取物品
  152.     #--------------------------------------------------------------------------
  153.     def item
  154.       return @data[self.index]
  155.     end
  156.  
  157.     #--------------------------------------------------------------------------
  158.     # ● 刷新
  159.     #--------------------------------------------------------------------------
  160.     def refresh
  161.       if self.contents != nil
  162.         self.contents.dispose
  163.         self.contents = nil
  164.       end
  165.       @data = []
  166.       # 添加物品
  167.       for i in 1...$data_items.size
  168.         if @bind_data.item_number(i) > 0
  169.           @data.push($data_items[i])
  170.         end
  171.       end
  172.       # 在战斗中以外添加武器、防具
  173.       unless $game_temp.in_battle
  174.         for i in 1...$data_weapons.size
  175.           if @bind_data.weapon_number(i) > 0
  176.             @data.push($data_weapons[i])
  177.           end
  178.         end
  179.         for i in 1...$data_armors.size
  180.           if @bind_data.armor_number(i) > 0
  181.             @data.push($data_armors[i])
  182.           end
  183.         end
  184.       end
  185.       # Sort by description
  186.       if @data.first.respond_to?(:desc)
  187.         @data.sort! { |a, b| a.desc <=> b.desc }
  188.       end
  189.       # 如果项目数不是 0 就生成位图、重新描绘全部项目
  190.       @item_max = @data.size
  191.       if @item_max > 0
  192.         self.contents = Bitmap.new(width - 32, row_max * 32)
  193.         for i in 0...@item_max
  194.           draw_item(i)
  195.         end
  196.       end
  197.     end
  198.  
  199.     #--------------------------------------------------------------------------
  200.     # ● 描绘项目
  201.     #     index : 项目编号
  202.     #--------------------------------------------------------------------------
  203.     def draw_item(index)
  204.       item = @data[index]
  205.       case item
  206.       when RPG::Item
  207.         number = @bind_data.item_number(item.id)
  208.       when RPG::Weapon
  209.         number = @bind_data.weapon_number(item.id)
  210.       when RPG::Armor
  211.         number = @bind_data.armor_number(item.id)
  212.       end
  213.       if self.active
  214.         self.contents.font.color = normal_color
  215.       else
  216.         self.contents.font.color = disabled_color
  217.       end
  218.       x = 4
  219.       y = index * 32
  220.       rect = Rect.new(x, y, self.width / @column_max - 32, 32)
  221.       self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
  222.       bitmap = RPG::Cache.icon(item.icon_name)
  223.       opacity = self.contents.font.color == normal_color ? 255 : 128
  224.       self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
  225.       self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
  226.       self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
  227.       self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  228.     end
  229.  
  230.     #--------------------------------------------------------------------------
  231.     # ● 刷新帮助文本
  232.     #--------------------------------------------------------------------------
  233.     def update_help
  234.       @help_window.set_text(self.item == nil ? "" : self.item.description)
  235.     end
  236.   end  
  237.  
  238.   class Scene_Storage
  239.     attr_reader :data
  240.  
  241.     def initialize
  242.       @scene_class = $scene.class
  243.       if !$game_system.storage_data.is_a?(Data)
  244.         $game_system.storage_data = Data.new
  245.       end
  246.       @data = $game_system.storage_data
  247.     end
  248.  
  249.     def main
  250.       create_windows
  251.       scene_loop
  252.       dispose_windows
  253.     end
  254.  
  255.     # layout
  256.     # ----------------------------------------- #
  257.     # Help Window (640 x 64)                    #
  258.     # ----------------------------------------- #
  259.     # Menu Window (640 x 64)                    #
  260.     # --------------------+-------------------- #
  261.     # Item Window Party   | Item Window Storage #
  262.     #    (320 x 352)      |    (320 x 352)      #
  263.     # --------------------+-------------------- #
  264.     def create_windows
  265.       # Help Window
  266.       @help_window = Window_Help.new
  267.       # Horizontal Command Window
  268.       @menu_window = Window_Menu.new
  269.       @menu_window.active = true
  270.       # Item Window left: Party items
  271.       @item_window_party = Window_Item.new(0, 128, 320, 352)
  272.       @item_window_party.bind_data = $game_party
  273.       @item_window_party.active = false
  274.       @item_window_party.index = -1
  275.       @item_window_party.refresh
  276.       # Item Window right: Storage items
  277.       @item_window_storage = Window_Item.new(320, 128, 320, 352)
  278.       @item_window_storage.bind_data = @data
  279.       @item_window_storage.active = false
  280.       @item_window_storage.index = -1
  281.       @item_window_storage.refresh
  282.       # binding help windows
  283.       @menu_window.help_window = @help_window
  284.       @item_window_party.help_window = @help_window
  285.       @item_window_storage.help_window = @help_window
  286.     end
  287.  
  288.     def update
  289.       @help_window.update
  290.       # update active window
  291.       if @menu_window.active
  292.         @menu_window.update
  293.         if Input.trigger?(Input::C)
  294.           $game_system.se_play($data_system.decision_se)
  295.           case @menu_window.index
  296.           when 0
  297.             @item_window_party.active = true
  298.             @menu_window.active = false
  299.             if @item_window_party.index == -1
  300.               @item_window_party.index = 0
  301.             end
  302.           when 1
  303.             @item_window_storage.active = true
  304.             @menu_window.active = false
  305.             if @item_window_storage.index == -1
  306.               @item_window_storage.index = 0
  307.             end
  308.           when 2
  309.             $scene = @scene_class.new
  310.             return
  311.           end
  312.           @item_window_party.refresh
  313.           @item_window_storage.refresh
  314.         end
  315.         return
  316.       end
  317.  
  318.       if @item_window_party.active
  319.         @item_window_party.update
  320.         if Input.trigger?(Input::B)
  321.           $game_system.se_play($data_system.cancel_se)
  322.           @item_window_party.active = false
  323.           @menu_window.active = true
  324.           @item_window_party.index = -1
  325.           @item_window_storage.index = -1
  326.           @item_window_party.refresh
  327.           @item_window_storage.refresh
  328.         end
  329.         if Input.trigger?(Input::C)
  330.           ret = store(@item_window_party.item)
  331.           if ret
  332.             $game_system.se_play($data_system.decision_se)
  333.             @item_window_party.refresh
  334.             @item_window_storage.refresh
  335.           else
  336.             $game_system.se_play($data_system.buzzer_se)
  337.           end
  338.         end
  339.         return
  340.       end
  341.  
  342.       if @item_window_storage.active
  343.         @item_window_storage.update
  344.         if Input.trigger?(Input::B)
  345.           $game_system.se_play($data_system.cancel_se)
  346.           @item_window_storage.active = false
  347.           @menu_window.active = true
  348.           @item_window_party.index = -1
  349.           @item_window_storage.index = -1
  350.           @item_window_party.refresh
  351.           @item_window_storage.refresh
  352.         end
  353.         if Input.trigger?(Input::C)
  354.           ret = fetch(@item_window_storage.item)
  355.           if ret
  356.             $game_system.se_play($data_system.decision_se)
  357.             @item_window_party.refresh
  358.             @item_window_storage.refresh
  359.           else
  360.             $game_system.se_play($data_system.buzzer_se)
  361.           end
  362.         end
  363.         return
  364.       end
  365.     end
  366.  
  367.     def scene_loop
  368.       Graphics.transition
  369.       # 主循环
  370.       loop do
  371.         # 刷新游戏画面
  372.         Graphics.update
  373.         # 刷新输入信息
  374.         Input.update
  375.         # 刷新画面
  376.         update
  377.         # 如果画面切换就中断循环
  378.         if $scene != self
  379.           break
  380.         end
  381.       end
  382.       # 准备过渡
  383.       Graphics.freeze
  384.     end
  385.  
  386.     def dispose_windows
  387.       self.instance_variables.each do |name|
  388.         obj = self.instance_variable_get(name)
  389.         obj.dispose if obj.is_a?(Window)
  390.       end
  391.     end
  392.  
  393.     def store(item, number = 1)
  394.       # RPG::Item
  395.         num_storage_item = @data.item_number_all #version 0.5的更新_家庭作业
  396.         num_storage_weapon = @data.weapon_number_all #version 0.5的更新_家庭作业
  397.         num_storage_armor = @data.armor_number_all #version 0.5的更新_家庭作业   
  398.       if item.is_a?(RPG::Item)
  399.         num_party = $game_party.item_number(item.id)
  400.         num_storage = @data.item_number(item.id)        
  401.         if can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number) #version 0.5的更新_家庭作业
  402.           $game_party.lose_item(item.id, number)
  403.           @data.gain_item(item.id, number)
  404.           return true
  405.         else
  406.           box_limit= 2*$game_variables[1]
  407.           print "箱子内已经有#{box_limit}个东西了,已经存满了"
  408.         end
  409.       end
  410.       # RPG::Weapon
  411.       if item.is_a?(RPG::Weapon)
  412.         num_party = $game_party.weapon_number(item.id)
  413.         num_storage = @data.weapon_number(item.id)      
  414.         if can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number) #version 0.5的更新_家庭作业
  415.           $game_party.lose_weapon(item.id, number)
  416.           @data.gain_weapon(item.id, number)
  417.           return true
  418.         else
  419.           box_limit= 2*$game_variables[1]
  420.           print "箱子内已经有#{box_limit}个东西了,已经存满了"           
  421.         end
  422.       end
  423.       # RPG::Armor
  424.       if item.is_a?(RPG::Armor)
  425.         num_party = $game_party.armor_number(item.id)
  426.         num_storage = @data.armor_number(item.id)     
  427.         if can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number) #version 0.5的更新_家庭作业
  428.           $game_party.lose_armor(item.id, number)
  429.           @data.gain_armor(item.id, number)
  430.           return true
  431.         else
  432.           box_limit= 2*$game_variables[1]
  433.           print "箱子内已经有#{box_limit}个东西了,已经存满了"           
  434.         end
  435.       end
  436.       return false
  437.     end
  438.  
  439.     def fetch(item, number = 1)
  440.       if item.is_a?(RPG::Item)
  441.         num_party = $game_party.item_number(item.id)
  442.         num_storage = @data.item_number(item.id)        
  443.         $game_party.gain_item(item.id, number)
  444.         @data.gain_item(item.id, -number)
  445.         return true
  446.       end
  447.       # RPG::Weapon
  448.       if item.is_a?(RPG::Weapon)
  449.         num_party = $game_party.weapon_number(item.id)
  450.         num_storage = @data.weapon_number(item.id)      
  451.         $game_party.gain_weapon(item.id, number)
  452.         @data.gain_weapon(item.id, -number)
  453.         return true
  454.       end
  455.       # RPG::Armor
  456.       if item.is_a?(RPG::Armor)
  457.         num_party = $game_party.armor_number(item.id)
  458.         num_storage = @data.armor_number(item.id)     
  459.         $game_party.gain_armor(item.id, number)
  460.         @data.gain_armor(item.id, -number)
  461.         return true
  462.       end
  463.       return false
  464.     end
  465.  
  466.     def can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number=1) #version 0.5的更新_家庭作业
  467.       num_storage_item+num_storage_weapon+num_storage_armor+number <= 2*$game_variables[1] #箱子大小上限设置
  468.   end
  469.  
  470. end


接下来还有地图上存储箱事件的脚本需改成$scene = Taeckle::Scene_Storage.new (以前是: size = [$game_variables[1] * 3, 99].min $scene = Taeckle::Scene_Storage.new(2, size))

最后在Game_System 内的"定义实例变量下面"加一句"attr_accessor :storage_data #箱子存储",然后在def initialize内加一行"@storage_data = []" , 写完收工!

点评

明白了,我换了个格式,现在没有显示问题了  发表于 2021-8-24 16:55
我去,那为啥你的脚本里可以把[i]显示出来?  发表于 2021-8-24 16:39
看上去没啥大问题  发表于 2021-8-24 15:44
OK,我知道了,代码里的[i]无法在论坛上显示  发表于 2021-8-24 15:43
我觉得代码问题很大,但是你说正常那就正常吧……  发表于 2021-8-24 15:41
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
24004
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

23
 楼主| 发表于 2021-8-24 19:08:10 | 只看该作者
本帖最后由 guoxiaomi 于 2021-8-24 21:43 编辑

整体上没有大问题,已经是很大的进步了。
一个算法上的小问题:
一定要这样统计总数吗?我之前的建议是,Data类维护一个整数@num,初始为0,每次成功放入、取出物品时,增加或者减少这个数。这样就不需要每次循环加一遍了。

那最好这样写:
  1. def item_number_all
  2.   sum = 0
  3.   @items.values.each do |number|
  4.     sum += number
  5.   end
  6.   sum
  7. end
复制代码
RGSS的ruby版本太低没有Array#sum方法,但是似乎有Array#inject,如果有的话可以这样写:
  1. def item_number_all
  2.   @items.values.inject(0, :+)
  3. end
复制代码

点评

大神我上面的家庭作业主要是想学习下把一个哈希表全部的值(value)转换成一个数组的方法, 你的这个存储箱脚本已经让我在上班摸鱼时学到不少东西啦  发表于 2021-8-24 20:53
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9163
在线时间
466 小时
注册时间
2015-5-8
帖子
866
24
发表于 2021-8-25 06:55:14 | 只看该作者
本帖最后由 taeckle 于 2021-8-25 06:59 编辑

大神我还有个问题:

我把你的这个存储箱脚本里的第一行"module Taeckle" 以及脚本里的最后一行"end"都删掉了,
然后再把地图上存储箱事件的脚本需改成$scene = Scene_Storage.new后为啥就出错了

这是截图:





这里非得用个module...end才行吗?

点评

最前面加上::就表示跳出这个module,直接从顶层寻找,就会锁定到默认的Window_Help,不加就是module里的  发表于 2021-8-26 01:55
对,你可以再仔细看看代码,尤其是类似class Window_Help < ::Window_Help  发表于 2021-8-26 01:54
那在module里面实例化new一个在module内部的class是不是就不需要带上module名称了啊?  发表于 2021-8-25 21:42
带上模块名就可以区分了,你直接调用是外面的  发表于 2021-8-25 19:36
是啊,你看看我不是重复定义了Window_Help和Window_Item吗  发表于 2021-8-25 19:36
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9163
在线时间
466 小时
注册时间
2015-5-8
帖子
866
25
发表于 2021-8-27 02:50:21 | 只看该作者
本帖最后由 taeckle 于 2021-8-27 02:56 编辑

大神我突然又有个地方想不明白了:
在你的这个存储箱脚本version_0.3里的第50行"if store(@item_window_party.item)"为啥可以调用下面做的def store里面的内容呢?if不是仅用来判断真假的嘛?怎么这里也可以用来表示执行了呢?
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9163
在线时间
466 小时
注册时间
2015-5-8
帖子
866
26
发表于 2021-8-27 02:55:32 | 只看该作者
还有大神我在本帖第22楼发的version_0.5里的第407, 420, 433行的print怎么才能换成一个好看一点的提示框啊?稍微好看点就行了,
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9163
在线时间
466 小时
注册时间
2015-5-8
帖子
866
27
发表于 2021-9-3 05:14:42 | 只看该作者
本帖最后由 taeckle 于 2021-9-3 15:36 编辑

大神我还想设置第22号防具禁止存入这个存储箱子里(当玩家试图存放第22号道具时会有提示信息"此物品无法存储"出现,再按下enter键这个提示信息会消失),

请问为了实现这个目的又该怎么搞呢?
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9163
在线时间
466 小时
注册时间
2015-5-8
帖子
866
28
发表于 2021-9-9 05:55:22 | 只看该作者
本帖最后由 taeckle 于 2021-9-10 06:34 编辑

大神这是我在本帖第22楼Version_0.5的基础上做的更新,主要是想在存储时让一些物品无法存储以及提示信息, 你帮我看看还有啥问题没,多谢了 :

  1. # encoding: utf-8
  2. module Taeckle
  3.   @version = "0.6" #新增无法存储一些物品以及提示信息

  4.   class Data
  5.     attr_reader :items
  6.     attr_reader :weapons
  7.     attr_reader :armors

  8.     def initialize
  9.       @items = {}
  10.       @weapons = {}
  11.       @armors = {}
  12.     end

  13.     #--------------------------------------------------------------------------
  14.     # ● 获取物品的所持数
  15.     #     item_id : 物品 ID
  16.     #--------------------------------------------------------------------------
  17.     def item_number(item_id)
  18.       # 如果 hash 个数数值不存在就返回 0
  19.       return @items.include?(item_id) ? @items[item_id] : 0
  20.     end

  21.     # ● 获取(箱子内或身上)所有物品的数量之和
  22.     def item_number_all
  23.        @item_number_in_all=0
  24.         for i in [email protected]
  25.           @item_number_in_all [email protected][i]
  26.         end  
  27.       return @item_number_in_all
  28.     end   
  29.    
  30.     #--------------------------------------------------------------------------
  31.     # ● 获取武器所持数
  32.     #     weapon_id : 武器 ID
  33.     #--------------------------------------------------------------------------
  34.     def weapon_number(weapon_id)
  35.       # 如果 hash 个数数值不存在就返回 0
  36.       return @weapons.include?(weapon_id) ? @weapons[weapon_id] : 0
  37.     end
  38.    
  39.     # ● 获取(箱子内或身上)所有武器的数量之和
  40.     def weapon_number_all
  41.        @weapon_number_in_all=0
  42.         for i in [email protected]
  43.           @weapon_number_in_all [email protected][i]
  44.         end  
  45.       return @weapon_number_in_all
  46.     end  
  47.     #--------------------------------------------------------------------------
  48.     # ● 获取防具所持数
  49.     #     armor_id : 防具 ID
  50.     #--------------------------------------------------------------------------
  51.     def armor_number(armor_id)
  52.       # 如果 hash 个数数值不存在就返回 0
  53.       return @armors.include?(armor_id) ? @armors[armor_id] : 0
  54.     end

  55.     # ● 获取(箱子内或身上)所有防具的数量之和
  56.     def armor_number_all
  57.        @armor_number_in_all=0
  58.         for i in [email protected]
  59.           @armor_number_in_all [email protected][i]
  60.         end  
  61.       return @armor_number_in_all
  62.     end      
  63.     #--------------------------------------------------------------------------
  64.     # ● 增加物品 (减少)
  65.     #     item_id : 物品 ID
  66.     #     n       : 个数
  67.     #--------------------------------------------------------------------------
  68.     def gain_item(item_id, n)
  69.       # 更新 hash 的个数数据
  70.       if item_id > 0
  71.         @items[item_id] = [[item_number(item_id) + n, 0].max, 99].min
  72.       end
  73.     end

  74.     #--------------------------------------------------------------------------
  75.     # ● 增加武器 (减少)
  76.     #     weapon_id : 武器 ID
  77.     #     n         : 个数
  78.     #--------------------------------------------------------------------------
  79.     def gain_weapon(weapon_id, n)
  80.       # 更新 hash 的个数数据
  81.       if weapon_id > 0
  82.         @weapons[weapon_id] = [[weapon_number(weapon_id) + n, 0].max, 99].min
  83.       end
  84.     end

  85.     #--------------------------------------------------------------------------
  86.     # ● 增加防具 (减少)
  87.     #     armor_id : 防具 ID
  88.     #     n        : 个数
  89.     #--------------------------------------------------------------------------
  90.     def gain_armor(armor_id, n)
  91.       # 更新 hash 的个数数据
  92.       if armor_id > 0
  93.         @armors[armor_id] = [[armor_number(armor_id) + n, 0].max, 99].min
  94.       end
  95.     end   
  96.   end
  97.   
  98.   class Window_Help < ::Window_Help
  99.   end
  100.   
  101.   class Window_Menu < ::Window_Selectable
  102.     def initialize
  103.       super(0, 64, 640, 64)
  104.       @item_max = 3
  105.       @column_max = 3
  106.       @index = 0
  107.       @commands = ["存入", "取出", "离开"]
  108.       self.contents = Bitmap.new(width - 32, height - 32)
  109.       refresh
  110.     end

  111.     #--------------------------------------------------------------------------
  112.     # ● 刷新
  113.     #--------------------------------------------------------------------------
  114.     def refresh
  115.       self.contents.clear
  116.       for i in 0...@item_max
  117.         draw_item(i)
  118.       end
  119.     end

  120.     #--------------------------------------------------------------------------
  121.     # ● 描绘项目
  122.     #     index : 项目编号
  123.     #--------------------------------------------------------------------------
  124.     def draw_item(index)
  125.       self.contents.draw_text(index * 212 - 12, 0, 212, 32, @commands[index], 1)
  126.     end

  127.     def update_help
  128.       case @index
  129.       when 0 then text = "存入物品"
  130.       when 1 then text = "取出物品"
  131.       when 2 then text = "离开场景"
  132.       end
  133.       @help_window.set_text(text, 1)
  134.     end
  135.   end
  136.   
  137.   class Window_Item< ::Window_Selectable
  138.    
  139.   attr_accessor :bind_data   
  140.     #--------------------------------------------------------------------------
  141.     # ● 获取物品
  142.     #--------------------------------------------------------------------------
  143.     def item
  144.       return @data[self.index]
  145.     end

  146.     #--------------------------------------------------------------------------
  147.     # ● 刷新
  148.     #--------------------------------------------------------------------------
  149.     def refresh
  150.       if self.contents != nil
  151.         self.contents.dispose
  152.         self.contents = nil
  153.       end
  154.       @data = []
  155.       # 添加物品
  156.       for i in 1...$data_items.size
  157.         if @bind_data.item_number(i) > 0
  158.           @data.push($data_items[i])
  159.         end
  160.       end
  161.       # 在战斗中以外添加武器、防具
  162.       unless $game_temp.in_battle
  163.         for i in 1...$data_weapons.size
  164.           if @bind_data.weapon_number(i) > 0
  165.             @data.push($data_weapons[i])
  166.           end
  167.         end
  168.         for i in 1...$data_armors.size
  169.           if @bind_data.armor_number(i) > 0
  170.             @data.push($data_armors[i])
  171.           end
  172.         end
  173.       end
  174.       # Sort by description
  175.       if @data.first.respond_to?(:desc)
  176.         @data.sort! { |a, b| a.desc <=> b.desc }
  177.       end
  178.       # 如果项目数不是 0 就生成位图、重新描绘全部项目
  179.       @item_max = @data.size
  180.       if @item_max > 0
  181.         self.contents = Bitmap.new(width - 32, row_max * 32)
  182.         for i in 0...@item_max
  183.           draw_item(i)
  184.         end
  185.       end
  186.     end

  187.     #--------------------------------------------------------------------------
  188.     # ● 描绘项目
  189.     #     index : 项目编号
  190.     #--------------------------------------------------------------------------
  191.     def draw_item(index)
  192.       item = @data[index]
  193.       case item
  194.       when RPG::Item
  195.         number = @bind_data.item_number(item.id)
  196.       when RPG::Weapon
  197.         number = @bind_data.weapon_number(item.id)
  198.       when RPG::Armor
  199.         number = @bind_data.armor_number(item.id)
  200.       end
  201.       if self.active
  202.         self.contents.font.color = normal_color
  203.       else
  204.         self.contents.font.color = disabled_color
  205.       end
  206.       x = 4
  207.       y = index * 32
  208.       rect = Rect.new(x, y, self.width / @column_max - 32, 32)
  209.       self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
  210.       bitmap = RPG::Cache.icon(item.icon_name)
  211.       opacity = self.contents.font.color == normal_color ? 255 : 128
  212.       self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
  213.       self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
  214.       self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
  215.       self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  216.     end

  217.     #--------------------------------------------------------------------------
  218.     # ● 刷新帮助文本
  219.     #--------------------------------------------------------------------------
  220.     def update_help
  221.       @help_window.set_text(self.item == nil ? "" : self.item.description)
  222.     end
  223.   end  

  224. # ■ Storage_Prompt_Window
  225. #------------------------------------------------------------------------------
  226. #  提示仓库已满窗口或禁止存储某个物品。
  227. #==============================================================================
  228. class Storage_Prompt_Window < Window_Base
  229.   #--------------------------------------------------------------------------
  230.   # ● 初始化对像
  231.   #--------------------------------------------------------------------------
  232.   def initialize
  233.     super(140, 60, 370,100)
  234.     self.contents = Bitmap.new(width - 32, height - 32)
  235.   end  

  236.   def draw_text_2
  237.     self.contents.clear
  238.     self.contents.font.size = 25
  239.     self.contents.font.color = Color.new(255, 255, 128, 255)
  240.     self.contents.draw_text(5, 0, self.width - 32, 32, "这个道具无法存储!")
  241.   end   
  242. end   
  243.   
  244.   class Scene_Storage
  245.     attr_reader :data

  246.     def initialize     
  247.       @scene_class = $scene.class
  248.       if !$game_system.storage_data.is_a?(Data)
  249.       $game_system.storage_data = Data.new  #记得在class Game_System里建个@storage_data
  250.       end
  251.       @data = $game_system.storage_data

  252.     end
  253.                  
  254.     def main
  255.       create_windows
  256.       scene_loop
  257.       dispose_windows
  258.     end

  259.     # layout
  260.     # ----------------------------------------- #
  261.     # Help Window (640 x 64)                    #
  262.     # ----------------------------------------- #
  263.     # Menu Window (640 x 64)                    #
  264.     # --------------------+-------------------- #
  265.     # Item Window Party   | Item Window Storage #
  266.     #    (320 x 352)      |    (320 x 352)      #
  267.     # --------------------+-------------------- #
  268.     def create_windows
  269.       # Help Window
  270.       @help_window = Window_Help.new
  271.       # Horizontal Command Window
  272.       @menu_window = Window_Menu.new
  273.       @menu_window.active = true
  274.       # Item Window left: Party items
  275.       @item_window_party = Window_Item.new(0, 128, 320, 352)
  276.       @item_window_party.bind_data = $game_party
  277.       @item_window_party.active = false        
  278.       @item_window_party.index = -1
  279.       @item_window_party.refresh
  280.       # 生成提示仓库已满提示窗口
  281.       @storage_noplace_window = Storage_Prompt_Window.new
  282.       @storage_noplace_window.draw_text_1
  283.       @storage_noplace_window.x = 210
  284.       @storage_noplace_window.y = 180
  285.       @storage_noplace_window.active = false   
  286.       @storage_noplace_window.visible = false     
  287.       @storage_noplace_window.opacity = 255
  288.       # 生成道具禁止存储提示窗口
  289.       @storage_prohibition_window = Storage_Prompt_Window.new
  290.       @storage_prohibition_window.draw_text_2
  291.       @storage_prohibition_window.x = 210
  292.       @storage_prohibition_window.y = 180
  293.       @storage_prohibition_window.active = false   
  294.       @storage_prohibition_window.visible = false     
  295.       @storage_prohibition_window.opacity = 255         
  296.       # Item Window right: Storage items
  297.       @item_window_storage = Window_Item.new(320, 128, 320, 352)
  298.       @item_window_storage.bind_data = @data
  299.       @item_window_storage.active = false
  300.       @item_window_storage.index = -1
  301.       @item_window_storage.refresh
  302.       # binding help windows
  303.       @menu_window.help_window = @help_window
  304.       @item_window_party.help_window = @help_window
  305.       @item_window_storage.help_window = @help_window
  306.     end

  307.     def update
  308.       @help_window.update
  309.       # update active window
  310.       if @menu_window.active
  311.         @menu_window.update
  312.         if Input.trigger?(Input::C)
  313.           $game_system.se_play($data_system.decision_se)
  314.           case @menu_window.index
  315.           when 0
  316.             @item_window_party.active = true
  317.             @menu_window.active = false
  318.             if @item_window_party.index == -1
  319.               @item_window_party.index = 0
  320.             end
  321.           when 1
  322.             @item_window_storage.active = true
  323.             @menu_window.active = false
  324.             if @item_window_storage.index == -1
  325.               @item_window_storage.index = 0
  326.             end
  327.           when 2
  328.             $scene = @scene_class.new
  329.             return
  330.           end
  331.           @item_window_party.refresh
  332.           @item_window_storage.refresh
  333.         end
  334.         return
  335.       end

  336.       if @item_window_party.active
  337.         @item_window_party.update
  338.        if Input.trigger?(Input::B)
  339.           $game_system.se_play($data_system.cancel_se)
  340.           @item_window_party.active = false
  341.           @menu_window.active = true
  342.           @item_window_party.index = -1
  343.           @item_window_storage.index = -1
  344.           @item_window_party.refresh
  345.           @item_window_storage.refresh
  346.        end
  347.         
  348.        if Input.trigger?(Input::C)
  349.         if @item_window_party.item.is_a?(RPG::Item) && [1].include?(@item_window_party.item.id)  #1号物品无法存储
  350.           $game_system.se_play($data_system.buzzer_se)      
  351.           @item_window_party.active = false     
  352.           @storage_prohibition_window.active = true
  353.           @storage_prohibition_window.visible = true
  354.         elsif @item_window_party.item.is_a?(RPG::Weapon) && [1].include?(@item_window_party.item.id) #1号武器无法存储
  355.           $game_system.se_play($data_system.buzzer_se)     
  356.           @item_window_party.active = false     
  357.           @storage_prohibition_window.active = true
  358.           @storage_prohibition_window.visible = true
  359.         elsif @item_window_party.item.is_a?(RPG::Armor) && [1].include?(@item_window_party.item.id) #1号防具无法存储
  360.           $game_system.se_play($data_system.buzzer_se)     
  361.           @item_window_party.active = false     
  362.           @storage_prohibition_window.active = true
  363.           @storage_prohibition_window.visible = true      
  364.         else         
  365.          if store(@item_window_party.item)
  366.           $game_system.se_play($data_system.decision_se)
  367.           @item_window_party.refresh
  368.           @item_window_storage.refresh
  369.          else
  370.           $game_system.se_play($data_system.buzzer_se)
  371.          end        
  372.         end
  373.         return
  374.        end
  375.       end

  376.       if @item_window_storage.active
  377.         @item_window_storage.update
  378.         if Input.trigger?(Input::B)
  379.           $game_system.se_play($data_system.cancel_se)
  380.           @item_window_storage.active = false
  381.           @menu_window.active = true
  382.           @item_window_party.index = -1
  383.           @item_window_storage.index = -1
  384.           @item_window_party.refresh
  385.           @item_window_storage.refresh
  386.         end
  387.         if Input.trigger?(Input::C)
  388.           ret = fetch(@item_window_storage.item)
  389.           if ret
  390.             $game_system.se_play($data_system.decision_se)
  391.             @item_window_party.refresh
  392.             @item_window_storage.refresh
  393.           else
  394.             $game_system.se_play($data_system.buzzer_se)
  395.           end
  396.         end
  397.         return
  398.       end
  399.       
  400.       #更新仓库已满提示窗口
  401.       if @storage_noplace_window.active
  402.        update_noplace_window
  403.        return
  404.       end  
  405.       #更新禁止存储提示窗口
  406.       if @storage_prohibition_window.active
  407.        update_prohibition_window
  408.        return
  409.       end      
  410.       
  411.     end

  412.     def scene_loop
  413.       Graphics.transition
  414.       # 主循环
  415.       loop do
  416.         # 刷新游戏画面
  417.         Graphics.update
  418.         # 刷新输入信息
  419.         Input.update
  420.         # 刷新画面
  421.         update
  422.         # 如果画面切换就中断循环
  423.         if $scene != self
  424.           break
  425.         end
  426.       end
  427.       # 准备过渡
  428.       Graphics.freeze
  429.     end

  430.     def dispose_windows
  431.       self.instance_variables.each do |name|
  432.         obj = self.instance_variable_get(name)
  433.         obj.dispose if obj.is_a?(Window)
  434.       end
  435.     @storage_noplace_window.dispose
  436.     @storage_prohibition_window.dispose         
  437.     end

  438.     def update_noplace_window
  439.      if Input.trigger?(Input::B)
  440.      # 演奏取消 SE
  441.      $game_system.se_play($data_system.cancel_se)
  442.      @storage_noplace_window.active = false
  443.      @storage_noplace_window.visible = false
  444.      @item_window_party.active = true      
  445.      return
  446.      end
  447.      if Input.trigger?(Input::C)
  448.      # 演奏取消 SE
  449.      $game_system.se_play($data_system.cancel_se)      
  450.      @storage_noplace_window.active = false
  451.      @storage_noplace_window.visible = false
  452.      @item_window_party.active = true      
  453.      return         
  454.      end  
  455.     end   

  456.     def update_prohibition_window
  457.      if Input.trigger?(Input::B)
  458.      # 演奏取消 SE
  459.      $game_system.se_play($data_system.cancel_se)
  460.      @storage_prohibition_window.active = false
  461.      @storage_prohibition_window.visible = false
  462.      @item_window_party.active = true      
  463.      return
  464.      end
  465.      if Input.trigger?(Input::C)
  466.      # 演奏取消 SE
  467.      $game_system.se_play($data_system.cancel_se)      
  468.      @storage_prohibition_window.active = false
  469.      @storage_prohibition_window.visible = false
  470.      @item_window_party.active = true      
  471.      return         
  472.      end  
  473.     end     
  474.    
  475.     def store(item, number = 1)
  476.       # RPG::Item
  477.         num_storage_item = @data.item_number_all
  478.         num_storage_weapon = @data.weapon_number_all
  479.         num_storage_armor = @data.armor_number_all           
  480.       if item.is_a?(RPG::Item)
  481.         num_party = $game_party.item_number(item.id)
  482.         num_storage = @data.item_number(item.id)        
  483.         if can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number)      
  484.           $game_party.lose_item(item.id, number)
  485.           @data.gain_item(item.id, number)
  486.           return true
  487.         else
  488.           box_limit= 3*$game_variables[1]
  489.           print "箱子内已经有#{box_limit}个东西了,已经存满了"           
  490.         end
  491.       end
  492.       # RPG::Weapon
  493.       if item.is_a?(RPG::Weapon)
  494.         num_party = $game_party.weapon_number(item.id)
  495.         num_storage = @data.weapon_number(item.id)      
  496.         if can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number)
  497.           $game_party.lose_weapon(item.id, number)
  498.           @data.gain_weapon(item.id, number)
  499.           return true
  500.         else
  501.           box_limit= 3*$game_variables[1]
  502.           print "箱子内已经有#{box_limit}个东西了,已经存满了"           
  503.         end
  504.       end
  505.       # RPG::Armor
  506.       if item.is_a?(RPG::Armor)
  507.         num_party = $game_party.armor_number(item.id)
  508.         num_storage = @data.armor_number(item.id)     
  509.         if can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number)
  510.           $game_party.lose_armor(item.id, number)
  511.           @data.gain_armor(item.id, number)
  512.           return true
  513.         else
  514.           box_limit= 3*$game_variables[1]
  515.           print "箱子内已经有#{box_limit}个东西了,已经存满了"           
  516.         end
  517.       end
  518.       return false
  519.     end

  520.     def fetch(item, number = 1)
  521.       if item.is_a?(RPG::Item)
  522.         num_party = $game_party.item_number(item.id)
  523.         num_storage = @data.item_number(item.id)        
  524.         $game_party.gain_item(item.id, number)
  525.         @data.gain_item(item.id, -number)
  526.         return true
  527.       end
  528.       # RPG::Weapon
  529.       if item.is_a?(RPG::Weapon)
  530.         num_party = $game_party.weapon_number(item.id)
  531.         num_storage = @data.weapon_number(item.id)      
  532.         $game_party.gain_weapon(item.id, number)
  533.         @data.gain_weapon(item.id, -number)
  534.         return true
  535.       end
  536.       # RPG::Armor
  537.       if item.is_a?(RPG::Armor)
  538.         num_party = $game_party.armor_number(item.id)
  539.         num_storage = @data.armor_number(item.id)     
  540.         $game_party.gain_armor(item.id, number)
  541.         @data.gain_armor(item.id, -number)
  542.         return true
  543.       end
  544.       return false
  545.     end
  546.    
  547.     def can_store?(num_storage_item, num_storage_weapon, num_storage_armor,number=1)
  548.       num_storage_item+num_storage_weapon+num_storage_armor+number <= 3*$game_variables[1] #@item_max_size
  549.     end   
  550.   end
  551. end
复制代码


回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
24004
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

29
 楼主| 发表于 2021-9-9 11:31:06 | 只看该作者
本帖最后由 guoxiaomi 于 2021-9-9 11:54 编辑

你scene_storage为什么会有contents和visible……必须继承了Window类才有contents、visible这些

你其实就是想创建一个sprite显示图片对吧?直接在create_windows方法里:
@sprite = ::Sprite.new
@sprite.bitmap = RPG::Cache.picture("storage")
在dispose_windows方法里:
@sprite.dispose

然后在其他地方主动改变@sprite.visible就行了

评分

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

查看全部评分

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

使用道具 举报

Lv2.观梦者

梦石
0
星屑
853
在线时间
85 小时
注册时间
2005-11-21
帖子
86
30
发表于 2021-9-19 15:21:19 | 只看该作者
太棒了,希望能多有一些这样的脚本教程以供学习参考。

评分

参与人数 1+1 收起 理由
taeckle + 1 我很赞同

查看全部评分

回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-12-4 01:05

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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