类Enemy具有函数combat_roll()但似乎无法访问它Python 2.7

时间:2017-08-20 19:41:19

标签: python class

我真的从不费心去学习Python中的课程,因为我找到的所有文档对我来说都太技术化了。所以,我再次坐下来试图征服他们。我希望能够为我制作的基于文本的游戏使用类,所以这就是我每次都尝试的方式。

我的班级代码(现在因为我一直在尝试我能想到的一切而弄得很乱)是

class enemy:
    def __init__(self, name, weapon, hp, attack, defense, xp):
        self.self = self
        self.name = name
        self.hp = hp
        self.attack = attack
        self.defense = defense
        self.xp = xp

        #self.attack_text1 = attack_text1
        self.attack_text1 = name, " attacks you with ", weapon, "."
        #self.attack_damage = attack_damage
        self.attack_damage = random.randint(0,2) + attack
        #self.total_damage = total_damage
        self.total_damage = self.attack_damage - player.defense
        if self.total_damage < 1:
            self.total_damage = 0

        #self.attack_text2 = attack_text2
        self.attack_text2 = name, " deals ", self.total_damage, " to you." 

        @staticmethod #tried this from a solution found on stack overflow
        def combat_roll(self):
            self.roll = random.randrange(0,20) + attack

        combat_roll(self)

我有一个名为combat()的函数,可以让玩家对抗敌人类的实例。

在该函数中调用该实例:

def combat():
    goblin_weapon = weapon("goblin dagger", 1, 5)
    goblin = enemy("ugly goblin", goblin_weapon, 3,2,1,150)

    goblin_damage = goblin.attack - player.defense
    print "a ", goblin.name, " attacks you with ", goblin_weapon, "."
    print goblin.combat_roll
    if goblin.roll > player.defense:
        print goblin.name, "does ", goblin_damage, " damage."
    else:
        print goblin.name, "misses."

我的目标基本上是对战斗的d20感觉。攻击加成+ d20对抗护甲等级。我希望敌人可以拥有自己的功能,可以处理自己的骰子。

我已经丢失了我的代码的原始状态。我已经检查了谷歌并在这里搜索了解决方案,但没有一个有效。我确信这是因为我没有以适合我大脑的方式看到解决方案,因为这不会那么复杂。为什么我不能像调用类变量那样调用函数?

enemy.combat_roll()
你知道吗?

无论如何,谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

您只在__init__内宣布该方法,而不是在敌人内部。根据我的理解,只有在enemy类本身内声明它才会可用。

class enemy:
    def __init__(self, name, weapon, hp, attack, defense, xp):
        self.self = self
        self.name = name
        self.hp = hp
        self.attack = attack
        self.defense = defense
        self.xp = xp

        #self.attack_text1 = attack_text1
        self.attack_text1 = name, " attacks you with ", weapon, "."
        #self.attack_damage = attack_damage
        self.attack_damage = random.randint(0,2) + attack
        #self.total_damage = total_damage
        self.total_damage = self.attack_damage - player.defense
        if self.total_damage < 1:
            self.total_damage = 0

        #self.attack_text2 = attack_text2
        self.attack_text2 = name, " deals ", self.total_damage, " to you." 
        combat_roll(self)

    def combat_roll(self):
        self.roll = random.randrange(0,20) + attack

答案 1 :(得分:0)

正如你所说,你的代码遍布整个地方,并不是完整的。我试着改写并按照我认为你想要的精神填写它:

import random

#dice roll for dealing damage as a global function
def get_damage(dice_size, bonus_damage):
    return random.randrange(dice_size) + bonus_damage

#class for a player
class Player:
    #initialises the player's name, defense value and hp
    def __init__(self, name, defense, hp):
        self.name = name
        self.defense = defense
        self.hp = hp

    #when something wants a string representation of a player (like format()
    #might) it just uses the player's name
    def __str__(self):
        return self.name

    #a method where a player takes damage from some enemy (if it quacks like an
    #enemy..). This is where your attack_text2 has gone.
    def take_damage(self, enemy, dmg):
        self.hp -= dmg
        print("{} deals {} damage to {}".format(enemy, dmg, self))

#class for a weapon
class Weapon:
    #__init__ taking 4 arguments, like in your code, except it wasn't clear what
    #the last two arguments were.
    def __init__(self, name, foo, bar):
        self.name = name
        self.foo = foo
        self.bar = bar

    #as with Player
    def __str__(self):
        return self.name

#class for an enemy
class Enemy:
    #this has changed: init only needs to *init*ialise the object not do any
    #more, so all it does is stored relevant info as a field.
    def __init__(self, name, weapon, hp, attack, defense, xp):
        self.self = self
        self.name = name
        self.weapon = weapon
        self.hp = hp
        self.attack = attack
        self.defense = defense
        self.xp = xp

    #as with Weapon
    def __str__(self):
        return self.name

    #this is roughly where the second half of your init has gone. Engages in
    #combat with a player, generating a random amount of damage, and doing all
    #of the defense/attack malarkey. The damage is not stored as a field (using
    #self.) as it is only needed for the duration of the combat
    def combat(self, player):
        print("{} attacks {} with {}.".format(self, player, self.weapon))
        damage = get_damage(20, self.attack)
        total_damage = damage - player.defense
        if total_damage < 0:
            total_damage = 0
        player.take_damage(self, total_damage)

#function constructing a couple of objects and using them to do a 'fight'
#I've used some key word arguments with the goblin and the player. I'd advise
#you to keep doing the same, as it helps a lot with clarity.
def play():
    dagger = Weapon("a goblin dagger", 1, 5)
    goblin = Enemy("an ugly goblin", dagger, hp=3, attack=2, defense=1, xp=150)
    aragorn = Player("Aragorn", defense=3, hp=100)
    goblin.combat(aragorn)
    print("{} now has {} hp".format(aragorn, aragorn.hp))

play()

我已经包含了一些评论,试图解释什么是改变的,什么是什么,为什么,希望。

我希望它坚持你的代码愿景。主要的变化是稍微重构一下你的代码。在你的敌人__init__中,你最初拥有的代码现在最终出现在Enemy.combat中。您还没有包含武器或玩家类,虽然您的代码构造了一个武器并引用了player,所以我已经添加了这些。如果您需要更多说明,请告诉我。

以下是此代码的示例示例:

an ugly goblin attacks Aragorn with a goblin dagger.
an ugly goblin deals 10 damage to Aragorn
Aragorn now has 90 hp