2013-03-06 2 views
0

Итак, я написал несколько простых RPG ранее на других языках (а именно python), поэтому решил попробовать написать один в рубине. Итак, этим утром я сел и набрал основы боевой механики, сделал несколько созданий и начал рассказ. Однако, по какой-то причине, когда я пытаюсь запустить программу, которую я получаю эту ошибку:Ruby RPG: неопределенный метод для свойств существа

herosquest.rb:67: undefined method 'traits' for Creature::Hero:Class (NoMethodError)

Я посмотрел на код (который я буду предоставлять в полном объеме в конце) и нашел определение в линии от 26 до 55, где именно.

class Creature 
    # Creature attributes are used to determine the outcome of combat. 
    traits :life, :strength, :charisma, :weapon 
    attr_accessor :life, :strength, :charisma, :weapon 
    #New class methods for hp, str, char, wep 
    def self.life(val) 
    @traits ||= {} 
    @traits['life'] = val 
    end 

    def self.strength(val) 
    @traits ||= {} 
    @traits['strength'] = val 
    end 

    def self.charisma(val) 
    @traits ||= {} 
    @traits['charisma'] = val 
    end 

    def self.weapon(val) 
    @traits ||= {} 
    @traits['weapon'] = val 
    end 
    #initialize sets defaults for each attr 
    def initialize 
    self.class.traits.each do |k,v| 
     instance_variable_set("@#{k}", v) 
    end 
    end 
end 

Почему это не работает?

Вот и вся часть кода, если это помогает. Примечание: Когда я скопировал свой код, некоторые из отступов были испорчены. Это намного опрятно, чем кажется.

#CREATURE MECHANICS 
    #Create critters. Make them do stuff. 
class Creature 
    def self.metaclass; class << self; self; end; end 
    def self.traits(*arr) 
    return @traits if arr.empty? 
    attr_accessor(*arr) 
    arr.each do |a| 
     metaclass.instance_eval do 
     define_method(a) do |val| 
      @traits ||= {} 
      @traits[a] = val 
     end 
     end 
    end 
    class_eval do 
     define_method(:initialize) do 
     self.class.traits.each do |k,v| 
      instance_variable_set("@#{k}", v) 
     end 
     end 
    end 
    end 


class Creature 
    # Creature attributes are used to determine the outcome of combat. 
    traits :life, :strength, :charisma, :weapon 
    attr_accessor :life, :strength, :charisma, :weapon 
    #New class methods for hp, str, char, wep 
    def self.life(val) 
    @traits ||= {} 
    @traits['life'] = val 
    end 

    def self.strength(val) 
    @traits ||= {} 
    @traits['strength'] = val 
    end 

    def self.charisma(val) 
    @traits ||= {} 
    @traits['charisma'] = val 
    end 

    def self.weapon(val) 
    @traits ||= {} 
    @traits['weapon'] = val 
    end 
    #initialize sets defaults for each attr 
    def initialize 
    self.class.traits.each do |k,v| 
     instance_variable_set("@#{k}", v) 
    end 
    end 
end 




#CREATURE TYPES 
    #Hero 
    #Our brave Hero! Chosen by the gods! Mighty slayer 
    #of beasts! Also, broke. Which is why he's hunting 
    #a dragon. Poor, foolish mortal... 
class Hero < Creature 
    traits :bombs, :arrows, :money 

    life 10 
    strength 4 
    charisma 4 
    weapon 4 
    bombs rand(3..10) 
    arrows rand(15..100) 
    money rand(0..25)    #Should be used with Traders for buying stuff 

    #Bow. Needs arrows. Duh. Hero should start with, say, 50? 
    def ^(enemy) 
    if @arrows.zero? 
     puts "[Twang. Your imaginary arrow, alas, fails to slay the creature. Or have any effect at all. Moron.]" 
     return 
    end 
    @arrows -= 1 
    fight(enemy, rand(0+((charisma+(0..4))*2))) #Zero means you missed 
    end 
end 

    #The hero's sword, given to him by the gods. 
    #Unlimited uses. Also, shiny. 
    def /(enemy) 
    fight(enemy, rand(4+weapon+(strength*2))) 
    end 

    #Trading. Ah, commerce! Doesn't quite work yet. 
    #Need a way to make sure money stays positive, 
    #and some sort of way to make sure you can't 
    #cheat the poor trader out of his goods. 
    def trade(enemy) 
     if @money.zero? 
      puts "[ The trader ignores you. You need money.]" 
      return 
     else puts "[What do you want to buy?\n Arrows = 10 for 2 coins\n Bombs = 5 for 5 coins]"  #Should add new weapons someday 
      purchase = gets.chomp 
      if purchase == "Arrows" 
       puts "[You buy 10 arrows for 2 coins]" 
       @arrows += 10 
       @money -= 2 
      elsif purchase == "Bombs" 
       puts "[You buy 5 bombs for 5 coins]" 
       @bombs += 5 
       @money -= 5 
    end 
end  

    #Mmm, tasty lembas. Elvish waybread. One small 
    #bite is enough to fill the stomach of a grown man. 
    def %(enemy) 
    lembas = rand(charisma) 
    puts "[Tasty lembas gives you #{ lembas } life.]" 
    @life += lembas 
    fight(enemy, 0) 
    end 

    #Bombs. They explode. Hopefully, far away from you. 
    def *(enemy) 
    if @bombs.zero? 
     puts "[You light your finger on fire instead of the fuze. Then, you realize you're out of bombs.]" 
      @life -= 1 
     return 
    end 
    @bombs -= 1 
    fight(enemy, rand(weapon+(2..25))) 
    end 
end 


#Man 
    #Doesn't do much. Stands around and says boring things. Well, someday, anyway... 
class Man < Creature 
    traits :chat  #Will eventually say random stuff about the weather or whatever. 

    life 4 
    strength 2 
    charisma 4 
    weapon 1   
end 


#Woman 
    #Like Man. Except she smells nicer. 
    #Oh, and she's got a frying pan... 
    #Looks fierce. 
class Woman < Creature 
    life 4 
    strength 2 
    charisma 8 
    weapon 4   
end 


#Trader 
    #Hangs around taverns and pushes 
    #useless stuff on passers-by. 
class Trader < Creature 
    traits :bombs, :arrows, :money 

    life 4 
    strength 4 
    charisma 16 
    weapon 10   #Armed and dangerous. Sort of... 
    bombs rand(0..100) 
    arrows rand(0..500) 
    money rand(100..2500) 
end 


#Monkey 
    #Pain in the butt. Travels in packs. Makes 
    #faces and throws bananas. 
class Monkey < Creature 
    life 8 
    strength 5 
    charisma 11 
    weapon 2   #Beats you with its cute little fists. 
end 


#Cow 
    #Cows won't attack you unless you hit them, or try to ride them, 
    #or make fun of them for chewing cud. 
    #Also, they don't like it when people stare 
    #at their udders. It makes them uncomfortable. 
class Cow < Creature 
    life 18 
    strength 15 
    charisma 2  #It's a cow, not a rocket scientist 
    weapon 3 
end 


#Deer 
    #The deer is not as timid as it appears. Serves you right 
    #for picking on a poor, "helpless" creature. Jerk. 
class Deer < Creature 
    life 30 
    strength 22 
    charisma 5 
    weapon 15 
end 


#Biker 
    #Found on paths. Rides a bike. 
    #Not *super* tough, but should be 
    #strong enough to make you fear 
    #for your life. 
class Biker < Creature 
    life 34 
    strength 10 
    charisma 4  #They aren't very bright... 
    weapon 8 
end 


#Angel 
    #Heavenly host. "Information: Kill" 
    #Seriously, don't screw around with these guys. 
class Angel < Creature 
    life 85 
    strength 8 
    charisma 60  #Seriously smart, since it's 
    weapon 25     #secretly a robot. 
end 


#Tentacle 
    #Found in lakes by throwing things ala Merry and Pippin. 
    #NOTE: Should include this in the first scene with a lake: 
     #"I am afraid of the pool. Don't disturb it!" 
    #Should preferably be said by a smallish man, muttering about 
    #"My precious," Mordor, and someone called Sam. 
class Tentacle < Creature 
    life 9 
    strength 3  #Not strong, but there's a lot of them. 
    charisma 4 
    weapon 8 
end 


#Watcher in the Water 
    #Found after killing a bunch of tentacles. 
    #Should be tough enough to scare you off, 
    #but weak enough that you won't die 
    #instantly. 
class Watcher_in_the_Water < Creature 
    life 250 
    strength 10 
    charisma 35 
    weapon 4   #I don't want him to be too powerfull 
end 


#Dragon 
    #Will totally kill you to death. A lot. 
    #Final boss type thing. Surrounded 
    #by his hoard of glittering treasure. 
     #Oooh, shiny... 
class Dragon < Creature 
    life 500  # tough scales 
    strength 95 # bristling veins 
    charisma 65 # toothy smile 
    weapon 157 # fire breath 
end 




#COMBAT MECHANICS 
    #Hitting in combat 
    def hit(damage) 
    p_up = rand(charisma) 
    if p_up % 9 == 7 
     @life += p_up/4 
     puts "[#{ self.class } magic powers up #{ p_up }!]" 
    end 
    @life -= damage 
    puts "[#{ self.class } has died.]" if @life <= 0 
    end 

    #Turn in combat 
    def fight(enemy, weapon) 
    if life <= 0 
     puts "[#{ self.class } is dead, Jim. You can't fight!]" 
     return 
    end 

    #You attack 
    your_hit = rand(strength + weapon) 
    puts "[Your #{weapon} hit the #{enemy} for #{ your_hit } points of damage!]" 
    enemy.hit(your_hit) 

    #Enemy fights back 
    p enemy 
    if enemy.life > 0 
     enemy_hit = rand(enemy.strength + enemy.weapon) 
     puts "[The #{enemy} hit with #{ enemy_hit } points of damage!]" 
     self.hit(enemy_hit) 
    end 
    end 
end 



#PLACES, EVENTS, & STORY 
    #First, generate the Player 
h = Hero.new 
    #Determine player name and gender 
    print "What is your name, adventurer?\n" 
     name=gets.chomp.to_s 
    print "#{name}, are you male or female?\n" 
     gender=gets 
    print "\n" 


    #player chooses his/her class 
until heroclass = (1..3) 
print"What class do you want?\n(1 for Scout, 2 for Fighter, or 3 for Ranger)\n" 
heroclass = gets.to_i 
     if heroclass == 1 
      heroclass = "Scout" 
      Hero.charisma = charisma + 3 
      Hero.strength = strength - 1 
      Hero.weapon = weapon + 1 
      Hero.arrows = arrows + 50 
      print"Scouts are quick and intelligent, but they are a bit weak.\nTheir prefered weapon is the bow.\n" 
    break 
     elsif heroclass == 2 
      heroclass = "Fighter" 
      Hero.strength = strength + 3 
      Hero.charisma = charisma - 3 
      Hero.weapon = weapon + 3 
      Hero.life = life + 5 
      print"Fighters are skilled at close combat, and their endurance is unmached by lesser mortals.\n(They aren't very bright though...)\nTheir prefered weapon is the sword\n" 
    break 
     elsif heroclass == 3 
      heroclass = "Ranger" 
      Hero.strength = strength - 1 
      Hero.charisma = charisma + 2 
      Hero.life = life + 2 
      Hero.bombs = bombs + 5 
      Hero.weapon = weapon + 2 
      print"Rangers are highly skilled, but not as strong as fighters or as agile as scouts.\nThey fight well with all weapons, but they particularly enjoy blowing stuff up.\n" 
    break 
     else print "Please enter a valid class number." 
end 
print "Welcome, #{name}, the #{gender} #{heroclass}, Chosen Hero of the gods!\n" 
print "The disembodied voice you are now hearing is your Spirit Guide" 
end 
+0

Простите множество саркастических и/или ненужных комментариев. Помогите мне организовать мои мысли. –

+0

Спасибо @ Андрю Гримм, который позаботился об этом. –

ответ

1

Когда я попытался запустить свой код, я получил ошибку

so_question.rb:28:in `<class:Creature>': undefined method `traits' for Creature::Creature:Class (NoMethodError) 
    from so_question.rb:26:in `<class:Creature>' 
    from so_question.rb:3:in `<main>' 

, потому что у вас есть класс с именем Creature в классе Creature и traits является методом класса на Creature, а не на Creature::Creature.

Смежные вопросы