Reputation: 23
I can't work out how to fix it so it takes ten away from the health class variable, as it says that it is an error.
/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>'
Here is the code 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
And here is where the @object.attacked leads to:
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
And the yaml file if needed:
---
- 219.0
- 45.0
- 100.0
I tried to put .to_i after the @health like this:
@health.to_i -= 10
But it just brings up another error saying:
undefined method `to_i=' for nil:NilClass (NoMethodError)
Upvotes: 2
Views: 5299
Reputation: 1357
As mentioned by @omnikron, your @health
is uninitialized, hence -=
throws an exception when trying to subtract from nil
. If we go with initialize method instead, I imagine your object class looking like:
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
Upvotes: 2
Reputation: 2321
The error message is telling you that @health == nil
in your attacked
method. You need to initialize this value somewhere! Usually this would be in the aptly-named initialize
method of your class. Alternatively going on the code that you have provided so far, if when somebody is attacked for the first time you want to set the @health
instance variable to a default value you could change it to:
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
Note: the ||=
syntax is ruby's conditional assignment operator – it means 'set @health
to 100 unless @health is already defined.
Upvotes: 2