【问题标题】:I am trying to make an enemy move toward my player, but am getting an Attribute Error我试图让敌人向我的玩家移动,但出现属性错误
【发布时间】:2019-05-10 08:17:38
【问题描述】:

这是我遇到问题的代码的相关部分。 player.x 和 player.y 在调试控制台中出现“AttributeError: type object 'player' has no attribute 'x'”错误。我有一个名为“玩家”的单独类,我想在它四处移动时获得它的 x 和 y 坐标,以便敌人可以向它移动。这也是相关的播放器类开始部分:

class player(object):
    def __init__(self, x, y, sprintMultiplier, fps):
        self.x = x
        self.y = y
        self.vel = 1/fps * 150


class enemy(object):
    def __init__(self, fps, difficulty):
      pass

    def draw(self, window):
        self.moveTowardsPlayer()
        window.blit(self.downStanding, (self.x, self.y))

    def moveTowardsPlayer(self):
        dx, dy = self.x - player.x, self.y - player.y
        dist = math.hypot(dx, dy)
        dx, dy = dx/dist, dy/dist
        self.x += dx * self.vel
        self.y += dy * self.vel

【问题讨论】:

  • 愚蠢的说法,但可能是因为播放器类中 init 的标识,看起来需要再推一下 :) 是我下面的人,有了正确的答案,始终将您的 ClassNames 驼峰化,您引用的是类而不是 movetowards def 中的实例。
  • class player 没有 xy 属性。只有类的实例有。
  • 向我们展示完整的错误信息,并向我们展示您如何创建播放器实例。
  • 只是一个旁注:一旦你熟悉了三角函数,也可以看看向量,因为它们会让你的生活更轻松。这是一个简短的example,其中包含一个向鼠标移动的对象。

标签: python oop pygame attributeerror


【解决方案1】:

根据提供的代码,您似乎将一个 class 与该类的一个 object(实例)混合在一起。

player 这里是一个类,您可以在其中创建对象。 player 类本身没有 class attributes(即由类的所有成员共享的变量);它只有 instance 属性(类的各个实例独有的变量)。因此,预期用途是您创建一个或多个实例(可能对您的程序来说是全局的)并对其进行操作。

因此,我认为您需要三重:

  1. 要像这样创建player 对象:the_player = player(starting_x, starting_y, multiplier, starting_fps)
  2. player 的参数添加到enemy 的初始化程序中,如下所示:

    class enemy(object):
        def __init__(self, player_to_track, fps, difficulty):
            self.player_to_track = player_to_track
    
  3. the_player 传递给您创建的enemy 对象。

(不管怎样,许多人都遵循将类名大写而实例小写的惯例。这有助于在阅读代码时区分明显——你会得到类似my_player = Player( . . . ) 的东西,如果你曾经写过Player.foo,它有助于指出您在谈论 class 属性,而不是成员变量。)

【讨论】:

    【解决方案2】:

    代码错误

    • 您将类 player 的 x 和 y 变量声明为私有实例变量,而在敌人类中您将这些 x 和 y 值作为全局变量访问。

    所以解决问题的方法是。

    您可以将 x 和 y 值声明为全局变量,如下所示 并在构造函数中将这些 x 和 y 变量作为全局变量访问 如下所示。

    class player(object):
         x = 0
         y = 0
         def __init__(self, x, y, sprintMultiplier, fps):
           player.x = x
           player.y = y
           self.vel = 1/fps * 150
    

    或将播放器实例传递给方法 moveTowardsPlayer() 内 如果您不想保留 x 和 y 变量(玩家的 类)作为全局/类变量。代码如下。

    def moveTowardsPlayer(self, player1):
        dx, dy = self.x - player1.x, self.y - player1.y
        dist = math.hypot(dx, dy)
        dx, dy = dx/dist, dy/dist
        self.x += dx * self.vel
        self.y += dy * self.vel
    

    【讨论】:

    • 我已尝试添加您的建议,但是我收到一条错误消息,指出未定义 player1。我有一个 main.py 文件,我的 mainloop 所在的位置以及我使用 character.py 中的 Player 类的位置。我将所有有“player”的部分重命名为“player1”,并将类的名称改为“Player”,而不是全部小写。有什么明显的我错过了吗?
    • 使用该播放器类对象传递到方法 moveTowardsPlayer() 例如。如果您将播放器创建为 player1 = player(4, 5, 10, 20),则可以将方法称为 moveTowardsPlayer(player1)
    • 如果您为每个类使用单独的文件,请确保在使用它们的位置正确导入每个文件。
    • 谢谢!在括号中添加 (player1) 有效,但是敌人只会向玩家生成的那个坐标移动,然后不会跟随他。我将如何更新玩家的坐标以便敌人跟随它?
    • 你可以使用玩家的坐标来设置敌人在每一个动作中各自的坐标。您需要根据敌人的速度和力量值查看敌人应该如何向玩家移动的算法。
    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    相关资源
    最近更新 更多