未定义的方法` - '代表nil:NilClass(NoMethodError)

时间:2017-05-04 09:19:40

标签: ruby methods undefined libgosu

我无法解决如何修复它所以它需要十几个远离健康类变量,因为它说这是一个错误。

/home/will/Code/Rubygame/objects.rb:61:in `attacked': undefined method `-' for nil:NilClass (NoMethodError)
    from ./main.rb:140:in `update'
    from /var/lib/gems/2.3.0/gems/gosu-0.10.8/lib/gosu/patches.rb:140:in `tick'
    from /var/lib/gems/2.3.0/gems/gosu-0.10.8/lib/gosu/patches.rb:140:in `tick'
    from ./main.rb:197:in `<main>'

以下是main中的代码:

def update
    @player.left if Gosu::button_down? Gosu::KbA
    @player.right if Gosu::button_down? Gosu::KbD
    @player.up if Gosu::button_down? Gosu::KbW
    @player.down if Gosu::button_down? Gosu::KbS
    if Gosu::button_down? Gosu::KbK 
        @player.shot if @player_type == "Archer" or @player_type == "Mage"
        if @object.collision(@xshot, @yshot) == true
            x, y, health = YAML.load_file("Storage/info.yml")
            @object.attacked #LINE 140
        end
    end

end

这是@ object.attacked导致的地方:

 def attacked
    puts "attacked"
    @health -= 10 #LINE 61
    @xy.insert(@health)
    File.open("Storage/info.yml", "w") {|f| f.write(@xy.to_yaml) }
    @xy.delete_at(2)
    if @health == 0
        @dead = true
    end
end 

如果需要,可以使用yaml文件:

   ---
   - 219.0
   - 45.0
   - 100.0

我试图在@health之后添加.to_i,如下所示:

   @health.to_i -= 10

但它只是提出另一个错误说:

   undefined method `to_i=' for nil:NilClass (NoMethodError)

2 个答案:

答案 0 :(得分:2)

错误消息告诉您@health == nil方法中的attacked。你需要在某个地方初始化这个值!通常这将在您的类的恰当命名的initialize方法中。或者继续你目前为止提供的代码,如果有人第一次受到攻击你想将@health实例变量设置为默认值,你可以将其更改为:

def attacked
  @health ||= 100 # or whatever
  puts "attacked"
  @health -= 10 #LINE 61
  @xy.insert(@health)
  File.open("Storage/info.yml", "w") {|f| f.write(@xy.to_yaml) }
  @xy.delete_at(2)
  if @health == 0
    @dead = true
  end
end 

注意:||=语法是ruby的条件赋值运算符 - 它表示'将@health设置为100,除非已经定义了@health。

答案 1 :(得分:2)

如@omnikron所述,您的@health未初始化,因此-=在尝试从nil中减去时会引发异常。如果我们改为使用initialize方法,我想你的对象类看起来像:

Class Object
  attr_accessor :health

  def initialize
    @health = 100
  end
end

def attacked
  puts "attacked"
  @object.health -= 10 #LINE 61
  @xy.insert(@object.health)
  File.open("Storage/info.yml", "w") {|f| f.write(@xy.to_yaml) }
  @xy.delete_at(2)
  if @health == 0
    @dead = true
  end
end