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

Project1

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

[有事请教] 请问P1P2的地方的变量

[复制链接]

Lv3.寻梦者

梦石
0
星屑
4541
在线时间
382 小时
注册时间
2012-11-8
帖子
275
1
发表于 2023-10-16 10:24:49 | 显示全部楼层
数组指针的问题。在Scene_Mercenaries里传入的mercenaries是个纯数字的数组,用dup复制没毛病
f Input.trigger?(Input::C)
        if @window_shopcommand.active
          case @window_shopcommand.index
          when 0  #雇佣窗口
            @window_mercenaries.set_mercenaries(@temp)
            @type = 0
            @window_shopcommand.active = false
            @window_mercenaries.active = true
            @window_mercenaries.index = 0
            return
在这里雇佣的时候把@temp传给了window_mercenaries的@mercenaries,由于set方法里使用的@mercenaries=mercenaries
这里实际是把@temp的指针赋值给@mercenaries,这意味着window里的@mercenaries和scene里的@temp指向的是同一个数组,也就是说改变window的@mercenaries也会影响scene里的@temp
因此window.mercenaries.delete也就等效于@temp.delete。
不同类的变量的名称相同与否都没关系。数组的赋值并不是复制。传入的参数为纯数字数组时,建议使用dup/clone,以避免此类情况发生,当然若是想要两者关联起来那直接=
另外如果数组中包含对象时,使用dup/clone也无法复制,建议使用Marshal::load(Marshal.dump(obj))来复制

点评

脚本是这样写的 a=[2,3,4,5,6,7,8] $scene=Mercenaries::Scene_Mercenaries.new(a) 能说详细点吗?  发表于 2023-10-16 16:57
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
4541
在线时间
382 小时
注册时间
2012-11-8
帖子
275
2
发表于 2023-10-16 22:29:41 | 显示全部楼层
这就是一个容易搞混的概念,数组是Array类的实例对象,虽然数组的一些运算和方法看起来与整形浮点等变量差不多,但两者是不一样的
数组可以理解成指针或者内存地址
就拿你的脚本来说:
a=[2,3,4,5,6,7,8],内存空间中[2,3,4,5,6,7,8],让a指向这块内存,方便起见把它称作A
$scene=Mercenaries::Scene_Mercenaries.new(a)初始化scene,传入a
初始化中,@mercenaries = mercenaries,这一步使得scene的@mercenaries同样也指向了A这块内存空间
@temp = @mercenaries.dup,这一步单独开辟一块B空间,里面内容是[2,3,4,5,6,7,8],@temp指向这块B空间
make_window初始化各种window,其中Window_Mercenaries中又使用了@mercenaries = mercenaries
于是window的@mercenaries也指向了A这块空间,在这个时候,scene和window各自的@mercenaries都指向了同一块内存地址A,而@temp是单独的B
在进行雇佣操作的时候,先执行了@window_mercenaries.set_mercenaries(@temp),在set_mercenaries方法中使用了@mercenaries = mercenaries
此时,window.mercenaries被修改成指向内存空间B,也就是和@temp是相同的地址
所以接下来雇佣时,从window.mercenaries删除元素时,p @temp时打印出的结果自然也没有,而此时scene.mercenaries并不会改变
总结来说,在方法中传入参数是数组的时候,传入的并不是该数组每个元素的值,而是数组所指向的内存地址的值
可以按一下方式来定义方法
def a(b)
  @c=b.dup  #数组中不含有对象,可以使用此语句
  @d=Marshal::load(Marshal.dump(b))   #数组中不论是否含有对象都可使用此语句
end
或者在调用方法的时候,使用a(b.dup)

点评

谢谢解答,大概了解了  发表于 2023-10-17 21:12
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
4541
在线时间
382 小时
注册时间
2012-11-8
帖子
275
3
发表于 2023-10-19 08:44:00 | 显示全部楼层
kvkv97 发表于 2023-10-18 21:30
我的意思是:
出现问题的地方是P1和P2的地方。P1的时候, @window_mercenaries.mercenaries的实际变量是@wi ...

RUBY 代码复制
  1. when 0  #雇佣
  2.           if $game_party.gold >= $game_actors[@window_mercenaries.id].price
  3.             if $game_party.actors.size < 4
  4.               $game_party.lose_gold($game_actors[@window_mercenaries.id].price)
  5.               $game_party.add_actor(@window_mercenaries.id)
  6.               #@temp=[2,3,4,5,6,7,8,9]
  7. p  @temp
  8.               @window_mercenaries.mercenaries.delete(@window_mercenaries.id)
  9.              #@temp=[3,4,5,6,7,8,9]
  10. p  @window_mercenaries.id
  11.               @window_mercenaries.refresh
  12.               if @window_mercenaries.index > @window_mercenaries.mercenaries.size-1
  13.                 @window_mercenaries.index = @window_mercenaries.mercenaries.size-1
  14.               end
  15.             end
  16.           end


delete之后再p @window_mercenaries.id,结果是3,这没问题啊
雇佣2以后@mercenaries=[3,4,5,6,7,8],雇佣的时候window的index=0
雇佣操作并没有改变index,所以雇佣后,id返回的就是此时数组中的第一个元素3
delete删除的方法是匹配并删除元素,再将后面的元素往前移位
这时候再去调用id返回的就是3

def id
      return @mercenaries[self.index]
end

点评

昨天夜里,去P了一下,结果像你说的一样,答案是3,谢谢你热心的解答,谢谢了  发表于 2023-10-19 21:15
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-5-18 00:46

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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