2017-05-04 271 views
2

我無法弄清楚如何解決這個問題,因此它需要遠離健康類變量,因爲它表示它是一個錯誤。未定義的方法' - '爲零:NilClass(NoMethodError)

/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>' 

下面是主要代碼:

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 

我試着把@to_i放在@he ALTH這樣的:

@health.to_i -= 10 

,但它只是帶來了另一個錯誤說:

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

我覺得你的問題其實是'X,Y,健康= YAML.load_file(「存儲/ info.yml」)'我假設這應該是'@x,@y,@health = YAML.load_file(「Storage/info.yml」)'實例變量而不是局部變量。 – engineersmnky

回答

2

該錯誤消息告訴你,@health == nilattacked方法。你需要在某個地方初始化這個值!通常這將在您的班級恰當地命名爲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。

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 
+1

在另一個主題上,使用'Object'作爲類名將會引發一些有趣的問題,因爲每個ruby對象都是從'Object'類繼承的!所以這會覆蓋_every單個ruby object_的初始化方法。你可以在irb中試試這個,在這裏你會看到上面的代碼打印'「警告:重新定義Object#初始化可能會導致無限循環」' – omnikron

+0

好點@omnikron,我也應該提到它。 –

相關問題