查看: 2283|回复: 5

[已经解决] 【脚本学习】求解读一段独立背包脚本

[复制链接]
梦石
24
星屑
8942
在线时间
248 小时
注册时间
2020-12-4
回帖
259

极短24获奖极短23获奖极短22获奖

发表于 2022-11-18 01:27:45 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 纯属小虫 于 2022-11-18 18:09 编辑

最近想给游戏新添一个肉鸽模式的小副本系统,需要一个副本内独立背包
于是找到了这个古老的多背包系统脚本
很牛,很精简,很强大......但也强大到解读不出来

想要把金币的数据也能够存到全局变量之中,但试着修改了一下,没有成功......所以想请教大佬们解读一下
原作者:@英顺的马甲
[fold=脚本][pre lang="ruby"]#===============================================================================
# ● 【简易坑爹系列】多背包脚本    by  英顺的马甲
#===============================================================================
module Xiao虫
  Bag_Variable_Id = 113
end

class GameBag
  # 背包判定条件
  def self.identifier
    # 若需要以别的条件来判定背包请更改下面的脚本
    #===========================================
    $game_variables[Xiao虫::Bag_Variable_Id]
    #===========================================
    # 若需要以别的条件来判定背包请更改上面的脚本
  end
  # 将当前背包复制到缓存背包
  def self.push
    ObjectSpace.each_object(GameBag) do |bag|
      bag.cache = (bag.data[GameBag.identifier]||{}).clone
    end
  end
  # 将缓存背包复制到当前背包
  def self.pull
    ObjectSpace.each_object(GameBag) do |bag|
      bag.data[GameBag.identifier] = bag.cache.clone
    end
  end
  # 将当前背包叠加到缓存背包
  def self.merge
    ObjectSpace.each_object(GameBag) do |bag|
      (bag.data[GameBag.identifier] || {}).each do |k, v|
        bag.cache[k] = [bag.cache[k] + v, 99].min
      end
    end
  end
  # 清空当前背包  以及金币
  def self.clear
    # 如果是默认背包,则无视此指令
    return if $game_variables[Xiao虫::Bag_Variable_Id] == 0
    ObjectSpace.each_object(GameBag) do |bag|
      bag.data.delete(GameBag.identifier)
    end
  end
  # 清空缓存背包
  def self.drop
    ObjectSpace.each_object(GameBag) do |bag|
      bag.cache.clear
    end
  end
  # 初始化
  def initialize
    @data = {}
    @cache = {}
  end
  # 不需要理会
  def method_missing(meth, *args)
    begin
      (@data[GameBag.identifier] ||= {}).__send__(meth, *args)
    rescue Exception
      raise $!, $!.message, caller
    end
  end
  attr_accessor :data
  attr_accessor :cache
end
$ORIG_MULTIBAG_PARTY = Game_Party.clone unless $ORIG_MULTIBAG_PARTY
class Game_Party < $ORIG_MULTIBAG_PARTY
  def initialize
    super
    @items = GameBag.new
    @armors = GameBag.new
    @weapons = GameBag.new
  end
end[/pre][/fold]

主要懵逼点在第10行的定义,以及57到68行
...>>>
  def self.identifier
    # 若需要以别的条件来判定背包请更改下面的脚本
    #===========================================
    $game_variables[Xiao虫::Bag_Variable_Id]
    #===========================================
    # 若需要以别的条件来判定背包请更改上面的脚本
  end
...>>>
  def method_missing(meth, *args)
    begin
      (@data[GameBag.identifier] ||= {}).__send__(meth, *args)
    rescue Exception
      raise $!, $!.message, caller
    end
  end
  attr_accessor :data
  attr_accessor :cache
end
$ORIG_MULTIBAG_PARTY = Game_Party.clone unless $ORIG_MULTIBAG_PARTY
class Game_Party < $ORIG_MULTIBAG_PARTY
>>>...

求教:
1.函数定义里面只放一个孤零零的变量是什么含义
2.method_missing 里的定义貌似是用来写入物品数据的...但跟天书一样0.0 啥也没看懂
3.克隆类然后套成父类,再在初始化定义中写super加附加内容————这一套天秀操作跟alias的区别在哪?
梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
回帖
205
发表于 2022-11-18 16:47:40 | 显示全部楼层
本帖最后由 RPGzh500223 于 2022-11-18 16:49 编辑

其实RUBY代码(元编程)很绕的,远不像RMXP的代码这么直白……别问我,我就学了些简单的

基本是对哈希表的操作,理解这个核心,自己写个简单易懂的也可以,看不懂这代码也就没多大关系了。

ObjectSpace.each_object 是操作不了 立即值对象的,所以金钱(Fixnum)没效果,详细定义ruby1.8.6 ObjectSpace

问题
1. 不清楚,好像ruby2.x才有Hash#compare_by_identifier。反正 这里的 identifier 函数对应的是 键,只要确保 键 的 “唯一性” 就好了。
2. "ruby method_missing"定义可以直接百度,这里主要是不用把 哈希表的方法 定义成GameBag的实例方法,少写代码。
    其余就是报错,F1也有关于报错的部分,至于 "caller" 百度吧……
3.不清楚,论坛好像有帖子提到过这种操作。或许你可以两种写法测试一下有什么不同。


简单的写个背包
1. 沿用RMXP的习惯,方便存档,写在Game_Party里面。
2. 创建个 {},设计 具有唯一性 的键值,以对应不同的背包,可以是每个人的,也可以是每个副本、城市什么的。
3. 哈希表的值——单独的背包,可以是 数组、哈希表、Struct结构、自定义类……的对象。
    背包根据自己的需求保存 物品、武器、金钱等等(像不像又是个小背包),实际放入取出等操作的就是这些对象了。

评分

参与人数 1星屑 +50 赞 +1 收起 理由
RyanBern + 50 + 1 认可答案

查看全部评分

回复

使用道具 举报

梦石
24
星屑
8942
在线时间
248 小时
注册时间
2020-12-4
回帖
259

极短24获奖极短23获奖极短22获奖

 楼主| 发表于 2022-11-18 18:08:10 | 显示全部楼层
RPGzh500223 发表于 2022-11-18 16:47
其实RUBY代码(元编程)很绕的,远不像RMXP的代码这么直白……别问我,我就学了些简单的

基本是 ...


hhhh.....确实,用一个全局变量作哈希表,存独立的物品金币啥的就好了
听你这么一说,似乎重写一个要比理解这段代码要容易一些【捂脸】

不过,这个哈希表的数据结构好像还是要推敲一下
比如我就用一个$game_variable[X] 来设定当前的背包编号,Bag 是Game_Party里的背包集合的哈希表
Bag[0]  即为默认背包
Bag[1] 为1号独立背包 Bag[2] 为2号独立背包.....
那么,我要怎么安排这个哈希表,才能够便于写入和读取 【物品】【武器】【防具】【金钱】甚至是Game_Party里的其他数据呢

试写
Bag[背包编号] = [金币值,[物品类型,物品ID,持有物品数量].................]
Bag[0] = [100,[0,5,10],[0,10,5],[1,5,10].........]
背包0中存有  100金币  10个5号物品  5个10号物品  10个5号武器................


那么,第0项永远就是表示金币数,从第一项开始才是记录物品的数组

...不知这是不是最佳的数据结构格式
回复

使用道具 举报

梦石
0
星屑
8003
在线时间
1184 小时
注册时间
2007-7-29
回帖
2014
发表于 2022-11-18 18:33:04 | 显示全部楼层
1. 孤零零的变量代表返回该变量,这是节省的写法,return 非必须。
  1. def a
  2.     1
  3. end

  4. print a #=> 1
复制代码


2. mssing method是因为懒惰重定义所有的函数,遇到没定义的函数就交由@data去执行,无效函数则报错。

3. alias 只是重定义某个函数,重套不会撞名,也是一种省事的手法。

评分

参与人数 2星屑 +50 赞 +2 收起 理由
RyanBern + 50 + 1 认可答案
纯属小虫 + 1 膜拜

查看全部评分

回复

使用道具 举报

梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
回帖
205
发表于 2022-11-18 19:41:58 | 显示全部楼层
一开始没想那么多,前面所述方法,对Game_Party的改动很大,更适合确定游戏内容后定制的脚本,不像主楼的脚本更适合作为插件。

结构大致如下。你的写法,比如查找某个武器需要遍历所有物件,游戏后期物品多的话,可能就没那么快了
[pre lang=""]伪代码
ITEM, WEAPON, ARMOR, GOLD = 0, 1, 2, 3

@bags = {}
            item/weap/arm/gold           
@bags[key] = [{}, {}, {}, 0]

@bags[key][ITEM][item_id] => item_nums[/pre]
后面的相关交互几乎都是重写


主楼的脚本,可以把Game_Party的 @items/@weapons/@armors(任选其一)的[0] 作为 金币变量(初始化为0)

点评

感恩,结构一目了然了~~~另外,[0]那个方法的思路好棒,回头去试试 或许也可以直接将 item[a] item 设置成金币、步数之类的,以存储在独立背包里  发表于 2022-11-19 18:36
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部