如何使用 Python/Pygame 类修复 AttributeError 并将属性内容打印到终端

问题描述 投票:0回答:1

请指导我如何解决此问题以及如何检查类属性是否确实对预期值进行了排序。下面的程序意味着当程序运行时在监视器中显示彩色监视器。

但是,我遇到了“AttributeError: type object 'monitor' has no attribute 'x'”回溯的一致问题。我不确定原始类中的类方法部分是否是问题的一部分。

代码如下。

import pygame
import os
import math 

clock = pygame.time.Clock()

class monitor(object):
    def __init__(self, x, y, color, length, width, offset, offsetcolor):
            self.x = x
            self.y = y
            self.color = color
            self.color =(100,100,100)
            self.length = length
            self.width = width
            self.offset = offset
            self.offsetcolor = offsetcolor
                
    @classmethod  
    def draw(cls, win):
        #attribute checker
        if hasattr(cls, m.x):
                print("Monitor's X attribute is ", {cls.x})
            
            else:
                print("Monitor's x feature is not working...")
        
                #monitor drawing
        border = pygame.Rect(cls.x, cls.y, cls.width, cls.length)
            oborder = pygame.Rect(cls.x + cls.offset, cls.y + cls.offset, cls.width - (10* cls.offset), cls.length - (10* cls.offset))
        pygame.draw.rect(win, cls.color, border)
        pygame.draw.rect(win, cls.offsetcolor, oborder)
        print(cls.color + ' ' +cls.offsetcolor)
        my_monitor = monitor(10, 10, (255, 0, 0), 100, 50, 5, (0, 255, 0))
        my_monitor.draw(win)
        pygame.display.update()

        def redrawGameWindow():
                monitor.draw(win)

#mainloop & variables 
m = monitor(100,100,(100,100,100), 800, 1000, 2, (150,150,150))
m.x = 100
m.y = 100
m.width = 1000
m.length = 800
m.offset = 2

while run:
    clock.tick(27)
        
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
            pygame.quit()
        
    keys = pygame.key.get_pressed()

    if keys[pygame.K_ESCAPE]:
    run = False
    pygame.quit()
        
    #if keys[pygame.K_SPACE]:
    redrawGameWindow()           
  
pygame.quit()

作为参考,该代码的所有其他功能在我使用面向类模型之前就可以工作。

完整回溯如下:

Traceback (most recent call last):
  File "Monitor.py", line 115, in <module>
    redrawGameWindow()           
  File "Monitor.py", line 70, in redrawGameWindow
    monitor.draw(win)
  File "Monitor.py", line 45, in draw
    border = pygame.Rect(cls.x, cls.y, cls.width, cls.length)
AttributeError: type object 'monitor' has no attribute 'x'

我已经交换了属性,看看是否可以解决这个错误,但当我尝试绘制监视器时,似乎只有 cls 才适用于 classmethod 部分。类方法是否需要与普通方法不同的方式来继承属性?

我还尝试在主循环中放置相同的变量,作为将这些值传递给monitor.draw()函数的一种方式,但我仍然遇到同样的问题。除了使用它们来制定游戏规则之外,主循环中的这些变量是否是多余的,或者它们对于监视器的初始放置是否是必需的?

我还尝试将属性打印到终端,以查看是否确实有一个值记录在那里,但我没有运气。有人可以澄清缺少什么以及如何捕获这些错误吗?

python object methods pygame game-development
1个回答
0
投票

我修改了您的代码以消除错误并对其进行了一些整理,尽管这涉及忽略/颠覆 classmethod 意图。

import pygame
import os
import math 

class monitor(object):
    def __init__(self, x, y, color, length, width, offset, offsetcolor):
            self.x = x
            self.y = y
            self.color = color
            self.color =(100,100,100)
            self.length = length
            self.width = width
            self.offset = offset
            self.offsetcolor = offsetcolor
                
    @classmethod  
    def draw(cls, instance, win):
        border = pygame.Rect(instance.x, instance.y, instance.width, instance.length)
        oborder = pygame.Rect(instance.x + instance.offset, instance.y + instance.offset, instance.width - (10* instance.offset), instance.length - (10* instance.offset))
        pygame.draw.rect(win, instance.color, border)
        pygame.draw.rect(win, instance.offsetcolor, oborder)

win = pygame.display.set_mode((1200, 800))
my_monitor = monitor(10, 10, (255, 0, 0), 100, 50, 5, (0, 255, 0))  
m = monitor(100,100,(100,100,100), 800, 1000, 2, (150,150,150))
clock = pygame.time.Clock()
run = True
while run:   
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                run = False

    monitor.draw(m, win)
    monitor.draw(my_monitor, win)
    pygame.display.update()       
    clock.tick(27)
    
pygame.quit()

用精灵来实现更惯用:

class Monitor(pygame.sprite.Sprite):
    def __init__(self, x, y, color, length, width, offset, offsetcolor):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((width + 2*offset, length + 2*offset), pygame.SRCALPHA)
        border = pygame.Rect(0, 0, width, length)
        oborder = pygame.Rect(offset, offset, width - (10* offset), length - (10* offset))
        pygame.draw.rect(self.image, color, border )
        pygame.draw.rect(self.image, offsetcolor, oborder )
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
    
    def update(self):
        pass

您也可以使用精灵组来管理它们:

monitors = pygame.sprite.Group()
my_monitor = Monitor(10, 10, (255, 0, 0), 100, 50, 5, (0, 255, 0))  
m = Monitor(100,100,(100,100,100), 800, 1000, 2, (150,150,150))
monitors.add(m, my_monitor)

这会让你的游戏循环变得简单:

 # update state
monitors.update()
# draw background
win.fill("black")
# draw sprites
monitors.draw(win)
# update screen
pygame.display.update()       
clock.tick(27)

请注意,您的边框可能看起来不像您想要的那样,但是一旦您看到它们,就会更容易找出如何修复它们。

© www.soinside.com 2019 - 2024. All rights reserved.