【问题标题】:AttributeError: type object 'projectile' has no attribute 'dir'AttributeError:类型对象'projectile'没有属性'dir'
【发布时间】:2019-07-18 16:49:09
【问题描述】:

大家好,很抱歉打扰您,但我现在浪费了几个小时来修补以使其正常工作。

代码运行良好,但射弹在发射后不断改变方向,所以我尝试为每个子弹分配自己的 dir 值并将移动子弹的射击函数放入射弹类。但我不断收到错误消息:

Traceback(最近一次调用最后):文件“PycharmProjects/Game/Pygame.py”,第 90 行,在 update() 文件“PycharmProjects/Game/Pygame.py”,第 73 行,在 update get_input() 文件中“ PycharmProjects/Game/Pygame.py",第 55 行,在 get_input projectile.dir == {'N'} AttributeError: type object 'projectile' has no attribute 'dir'

我认为很明显我是编码新手,因此非常感谢您的帮助。

将 get_input 函数中的 projectile.dir 更改为 bullet.dir 和只是 dir。 将方向放在括号中。在 get_input 函数之外分配方向。在初始化函数之前在类 projectile 中分配了字母

class player():
    x = WIDTH / 2
    y = HEIGHT / 2
    width = 50
    height = 50
    speed = 1

    def draw(self):
        pygame.draw.rect(win, (0, 0, 255), (self.x, self.y, self.width, self.height))

class projectile():

    radius = 10
    speed = 8

    def __init__(self, x, y, dir={}):
        self.x = x
        self.y = y
        self.dir = dir

    def shot(self):
        for bullet in bullets:
            if self.dir == 'N':
                print('N')
                self.y -= 1
            if self.dir == 'W':
                print('W')
                self.x -= 1
            if self.dir == 'S':
                print('S')
                self.y += 1
            if self.dir == 'E':
                print('E')
                self.x += 1

    def draw(self):
        pygame.draw.circle(win, (255, 0, 0), (self.x, self.y), self.radius)


def get_input():
    keys = pygame.key.get_pressed()
    ev = pygame.event.get()

    if keys[pygame.K_w]:
        player.y -= player.speed
        projectile.dir == 'N'
    if keys[pygame.K_a]:
        player.x -= player.speed
        projectile.dir == 'W'
    if keys[pygame.K_s]:
        player.y += player.speed
        projectile.dir == 'S'
    if keys[pygame.K_d]:
        player.x += player.speed
        projectile.dir == 'E'
    for event in ev:
        if event.type == pygame.MOUSEBUTTONDOWN:
            bullets.append(projectile(round(player.x + player.width//2), round(player.y + player.height//2), dir))


def update():
    clock.tick(300)
    win.fill ((0, 0, 0))
    get_input()
    player.draw()
    for bullet in bullets:
        bullet.draw()
        bullet.shot()
    pygame.display.update()


running = True
player = player()
bullets = []

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    update()

#pygame.quit()

【问题讨论】:

  • 这里是错误消息:Traceback(最近一次调用最后一次):文件“PycharmProjects/Game/Pygame.py”,第 90 行,在 update() 文件“PycharmProjects/Game/Pygame .py”,第 73 行,更新 get_input() 文件“PycharmProjects/Game/Pygame.py”,第 55 行,get_input projectile.dir == {'N'} AttributeError: type object 'projectile' has no attribute 'dir '

标签: python python-3.x class object pygame


【解决方案1】:

.dir 现在是instance attribute,所以类属性projectile.dir 不再存在。
在全局命名空间中创建一个变量current_dir。使用global statement写入函数get_input中的变量,并在构造新的projectile对象时使用变量设置方向:

current_dir = 'N'
def get_input(ev):
    global current_dir

    keys = pygame.key.get_pressed()
    if keys[pygame.K_w]:
        player.y -= player.speed
        current_dir = 'N'
    if keys[pygame.K_a]:
        player.x -= player.speed
        current_dir = 'W'
    if keys[pygame.K_s]:
        player.y += player.speed
        current_dir = 'S'
    if keys[pygame.K_d]:
        player.x += player.speed
        current_dir = 'E'

    for event in ev:
        if event.type == pygame.MOUSEBUTTONDOWN:
            px, py = round(player.x + player.width//2), round(player.y + player.height//2)
            new_prj = projectile(px, py, current_dir)
            bullets.append(new_prj)

旁注,== 是比较相等运算符。要设置current_dir,您必须使用赋值运算符=

避免在主循环中多次调用pygame.event.get()。获取事件一次并将事件列表传递给函数updateget_input

def update(ev):
    clock.tick(300)
    win.fill ((0, 0, 0))
    get_input(ev)
    player.draw()
    for bullet in bullets:
        bullet.draw()
        bullet.shot()
    pygame.display.update()

running = True
player = player()
bullets = []

while running:
    ev = pygame.event.get()
    for event in ev:
        if event.type == pygame.QUIT:
            running = False

    update(ev)

【讨论】:

  • 为什么?我以为方向只是在四个按键检查之一中设置的。
  • @Guimute 是的,但是当按下鼠标按钮时,状态会被存储和使用。注意current_dir 不是“重置”,当按下鼠标按钮时,子弹必须在最后选择的方向上发射。 current_dir 不允许未定义,在原始代码(问题)中它是一个类属性并且也是持久的。
  • 非常感谢,尤其是关于多个事件调用的提示:)
猜你喜欢
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 2021-11-09
  • 2019-06-08
  • 2022-01-12
  • 2016-11-18
  • 2019-02-25
  • 2021-09-01
相关资源
最近更新 更多