2017-05-04 7 views
2

문제를 해결하는 방법을 고칠 수 없으므로 상태 클래스 변수에서 10을 벗어나므로 오류라고합니다. 여기 정의되지 않은 메소드`- '에 대해 nil : 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 

@he 뒤에 .to_i를 넣으려고했습니다. 이 같은 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

오류 메시지가 당신을 말하고를 당신의 attacked 방법 @health == nil. 이 값을 어딘가에 초기화해야합니다! 일반적으로이 클래스의 클래스 이름은 initialize입니다.

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 

참고 : 누군가가 처음으로 공격을 할 때 당신은 당신이 그것을 변경할 수있는 기본 값으로 @health 인스턴스 변수를 설정하려는 경우, 지금까지 제공 한 코드 진행 또는 : ||= 구문은 루비의 조건부 할당 연산자입니다. @health가 이미 정의되어 있지 않으면 '@health을 100으로 설정합니다.

2

@omnikron에서 언급했듯이 @health은 초기화되지 않기 때문에 에서 뺄셈을 시도하면 -=이 예외를 throw합니다. 우리가 대신 초기화 방법으로 갈 경우, 당신의 객체 클래스처럼 보이는 상상 : 나는 당신의 문제가 실제로 생각

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'를 클래스 이름으로 사용하면 모든 단일 루비 객체가'Object' 클래스에서 상속 받기 때문에 흥미로운 문제가 발생할 것입니다! 그래서 이것은 _ 하나의 루비 객체 _에 대한 초기화 메소드를 덮어 씁니다. 당신은 irb에서 이것을 시도 할 수 있습니다. 위의 코드는 경고를 출력합니다 : 초기화하는 객체 # 초기화는 무한 루프를 야기 할 수 있습니다. " – omnikron

+0

좋은 점 @omnikron, 나는 그것을 언급해야합니다. –