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

Project1

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

[有事请教] 语法错误

[复制链接]

Lv3.寻梦者

梦石
0
星屑
4647
在线时间
281 小时
注册时间
2013-10-13
帖子
852
跳转到指定楼层
1
发表于 2026-2-10 23:35:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
在class Game_Enemy < Game_Battler中
  #--------------------------------------------------------------------------
  # ● 初始化对像
  #     troop_id     : 循环 ID
  #     member_index : 循环成员的索引
  #--------------------------------------------------------------------------
  def initialize(troop_id, member_index)
    super()
    @troop_id = troop_id
    @member_index = member_index
    troop = $data_troops[@troop_id]
    @enemy_id = troop.members[@member_index].enemy_id
    enemy = $data_enemies[@enemy_id]
    @battler_name = enemy.battler_name
    @battler_hue = enemy.battler_hue
    @hp = self.maxhp
    @sp = maxsp
    @Hidden = troop.members[@member_index].hidden
    @immortal = troop.members[@member_index].immortal
  end
@hp = maxhp 可以加上self变@hp = self.maxhp ,为什么在class Sprite_Character < RPG::Sprite中
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
          @tile_id, @character.character_hue)
不能变成
bitmap = RPG::Cache.tile($game_map.tileset_name,
          @tile_id, @character.character_hue)
显示syntax error
?????????????????????????? 为什么?????????????????????????

Lv4.逐梦者

梦石
0
星屑
7286
在线时间
1243 小时
注册时间
2015-8-15
帖子
712
2
发表于 2026-2-23 11:01:29 | 只看该作者
本帖最后由 金芒芒 于 2026-2-23 11:07 编辑

你想弄明白为什么在 Game_Enemy 类里给 @hp 赋值时加不加 self. 都可以,但在 Sprite_Character 类里给 bitmap 赋值时必须加 self.,这是 Ruby 中实例变量和属性方法的核心区别问题。
核心原因拆解
首先要明确两个关键概念:
实例变量:以 @ 开头的变量(如 @hp、@bitmap),是对象内部直接存储数据的容器。
属性方法:通过 attr_accessor/attr_reader/attr_writer 定义的 xxx= 赋值方法(如 bitmap=),本质是方法调用,不是直接操作变量。
1. 先看 Game_Enemy 中的 self.maxhp
ruby
@hp = self.maxhp  # 可以写成 @hp = maxhp
maxhp 是 Game_Battler 类中定义的读取方法(attr_reader :maxhp 或自定义的 def maxhp)。
在 Ruby 中,调用无参数的实例方法时,self. 是可以省略的(这是语法糖)。
这里 maxhp 等价于 self.maxhp,因为 Ruby 会默认把当前对象(self)作为方法的调用者。
2. 再看 Sprite_Character 中的 self.bitmap = ...
ruby
self.bitmap = xxx  # 不能省略 self.
bitmap= 是 Sprite 类中定义的赋值方法(attr_writer :bitmap 或自定义的 def bitmap=(value))。
Ruby 语法规定:调用赋值方法(以 = 结尾的方法)时,必须显式写 self.。
如果省略 self.,Ruby 会把 bitmap = xxx 解析为「定义一个局部变量 bitmap 并赋值」,而不是「调用 bitmap= 方法」—— 这是最关键的区别!
代码示例验证
我们用极简的代码模拟这个场景,你就能直观理解:
ruby
# 模拟 Sprite 类(包含 bitmap= 赋值方法)
class MySprite
  # 定义 bitmap 的读取和赋值方法(等价于 attr_accessor :bitmap)
  def bitmap
    @bitmap
  end

  def bitmap=(value)
    @bitmap = value
    puts "调用了 bitmap= 方法,赋值为:#{value}"
  end

  def set_bitmap_with_self(value)
    # 正确:调用赋值方法
    self.bitmap = value
  end

  def set_bitmap_without_self(value)
    # 错误:定义局部变量,不会调用 bitmap= 方法
    bitmap = value
    puts "局部变量 bitmap 的值:#{bitmap},但 @bitmap 还是:#{@bitmap}"
  end
end

# 测试
sprite = MySprite.new
sprite.set_bitmap_with_self("正确赋值")  # 输出:调用了 bitmap= 方法,赋值为:正确赋值
sprite.set_bitmap_without_self("错误赋值") # 输出:局部变量 bitmap 的值:错误赋值,但 @bitmap 还是:正确赋值
补充:为什么 @hp = maxhp 不用 self.?
Game_Battler 中的 maxhp 是读取方法(无参数、无 =),Ruby 解析规则是:
当遇到 maxhp 时,先检查是否是局部变量 → 不是 → 再检查是否是当前对象的实例方法 → 是 → 自动调用 self.maxhp。
而 bitmap = xxx 中,Ruby 会优先把 bitmap 解析为局部变量(即使存在同名的赋值方法),除非显式加 self. 指明是调用方法。
总结
无参数读取方法(如 maxhp):self. 可省略,Ruby 会默认调用当前对象的方法。
赋值方法(如 bitmap=):必须加 self.,否则 Ruby 会把左边的标识符解析为局部变量,而非调用赋值方法。
本质区别:xxx(无 =)是「方法调用」,xxx = ...(有 =)默认是「局部变量赋值」,只有 self.xxx = ... 才是「赋值方法调用」。
这是 Ruby 语法的核心规则,也是 RPG Maker 脚本中这类写法差异的根本原因。

点评

明白了  发表于 2026-2-24 18:14
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2026-6-4 13:11

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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