简体   繁体   English

如何修复:“AttributeError:'Class' 对象没有属性 'rect'”

[英]How to fix: "AttributeError: 'Class' object has no attribute 'rect'"

I am making walls on the screen so my player sprite cannot go past them.我正在屏幕上制作墙壁,因此我的播放器精灵无法通过它们。 I think I have done all the .get_rect() but I keep getting this error:我想我已经完成了所有的.get_rect()但我不断收到这个错误:

TypeError: Argument must be rect style object类型错误:参数必须是矩形样式对象

def apartment_movement():

    keys = pygame.key.get_pressed()

    boundary = pygame.sprite.spritecollide(scarn, apartment_walls, False, False)

    if boundary:
        scarn.left = False
        scarn.right = False
        scarn.up = False
        scarn.down = False
        scarn.standing = False
        scarn.sleeping = False
    if not boundary:
        if keys[pygame.K_LEFT] and scarn.x > 110 - scarn.width - scarn.vel:  # allows the player to move left
            scarn.x -= scarn.vel
            scarn.left = True
            scarn.right = False
            scarn.up = False
            scarn.down = False
            scarn.standing = False
            scarn.sleeping = False
        elif keys[pygame.K_RIGHT] and scarn.x < 795 - scarn.width - scarn.vel:  # allows the player to move right
            scarn.x += scarn.vel
            scarn.right = True
            scarn.left = False
            scarn.up = False
            scarn.down = False
            scarn.standing = False
            scarn.sleeping = False
        elif keys[pygame.K_UP] and scarn.y > 130 - scarn.height - scarn.vel:
            scarn.y -= scarn.vel
            scarn.up = True
            scarn.right = False
            scarn.left = False
            scarn.down = False
            scarn.standing = False
            scarn.sleeping = False
        elif keys[pygame.K_DOWN] and scarn.y < 540 - scarn.height - scarn.vel:
            scarn.y += scarn.vel
            scarn.down = True
            scarn.right = False
            scarn.left = False
            scarn.up = False
            scarn.standing = False
            scarn.sleeping = False
        else:  # clarifies the player is not moving left or right
            scarn.walkCount = 0


class apartment_walls(pygame.sprite.Sprite):  # creates the walls of the apartment (1st scene)

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.boundary1 = pygame.Rect(243, 60, 8, 275)
        self.boundary2 = pygame.Rect(510, 60, 8, 275)
        self.boundary3 = pygame.Rect(243, 421, 215, 5)
        self.boundary4 = pygame.Rect(243, 330, 220, 5)
        self.boundary5 = pygame.Rect(510, 421, 145, 5)
        self.boundary6 = pygame.Rect(510, 330, 145, 5)
        self.boundary7 = pygame.Rect(700, 421, 57, 5)
        self.boundary8 = pygame.Rect(700, 330, 57, 5)
        self.boundary9 = pygame.Rect(43, 410, 120, 10)
        self.boundary10 = pygame.Rect(510, 335, 5, 90)
        self.boundary11 = pygame.Rect(460, 335, 5, 90)
        self.boundary12 = pygame.Rect(700, 335, 5, 90)
        self.boundary13 = pygame.Rect(650, 335, 5, 90)


def draw_apartment():  # draws the apartment (1st scene)

    win.blit(bg, (0, 0))
    win.blit(bed, (322, 120))

    pygame.draw.rect(win, black, (200, 470, 100, 10), 0)
    pygame.draw.polygon(win, black, [(180, 473), (200, 488), (200, 458)], 0)

    scarn.draw(win)


class Scarn(pygame.sprite.Sprite):  # creates attributes for Michael Scarn (player)

    def __init__(self, x, y, width, height):
        pygame.sprite.Sprite.__init__(self)
        # loads sprites for animations
        self.rect = pygame.Rect(pygame.image.load('Michael Scarn Forward Standing.png')), pygame.Rect(
            pygame.image.load('Michael Scarn Backward Standing.png')), pygame.Rect(
            [pygame.image.load('Michael Scarn Up 1.png'), pygame.image.load('Michael Scarn Up 2.png')]), [
                        pygame.image.load('Michael Scarn Down 1.png'), pygame.image.load('Michael Scarn Down 2.png')], [
                        pygame.image.load('Michael Scarn Right 1.png'), pygame.image.load('Michael Scarn Right 2.png'),
                        pygame.image.load('Michael Scarn Right 3.png'),
                        pygame.image.load('Michael Scarn Right 4.png')], [pygame.image.load('Michael Scarn Left 1.png'),
                                                                          pygame.image.load('Michael Scarn Left 2.png'),
                                                                          pygame.image.load('Michael Scarn Left 3.png'),
                                                                          pygame.image.load(
                                                                              'Michael Scarn Left 4.png')], pygame.image.load(
            'Michael Scarn Sleeping.png')

There were many problems in code so it is hard to describe all changes.代码中存在很多问题,因此很难描述所有更改。

This is not ideal solution but at least it works.这不是理想的解决方案,但至少它有效。

It checks collision with walls and it draws animation (dots in different colors) when it moves down.它检查与墙壁的碰撞,并在向下移动时绘制动画(不同颜色的点)。

import pygame
import os
import sys

# --- constants --- (UPPER_CASE_NAMES)

# folder with script
HOME = os.path.abspath(os.path.dirname(sys.argv[0]))
print('HOME:', HOME)

# subfolder with images
#RESOURCE = os.path.join(HOME, 'resource')
RESOURCE = '.'
print('RESOURCE:', RESOURCE)

BLACK = (0, 0, 0)
WHITE = (255,255,255)
RED   = (255, 0, 0)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

# --- classes --- (CamelCaseNames)

class Scarn(pygame.sprite.Sprite):  # creates attributes for Michael Scarn (player)

    def __init__(self, x, y):
        super().__init__() # pygame.sprite.Sprite.__init__(self)

        # loads sprites for animations
        self.animations = {
            'forward': [
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Forward Standing.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-1.png')),
            ],
            'backward': [
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Backward Standing.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-1.png')),
            ],
            'up': [
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Up 1.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Up 2.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-1.png')),
            ],
            'down': [
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Down 1.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Down 2.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-1.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-2.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-3.png')),
            ],
            'right': [
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Right 1.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Right 2.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Right 3.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Right 4.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-1.png')),
            ],
            'left': [
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Left 1.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Left 2.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Left 3.png')),
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Left 4.png')),
                pygame.image.load(os.path.join(RESOURCE, 'dot-1.png')),
            ],
            'sleep': [
                #pygame.image.load(os.path.join(RESOURCE, 'Michael Scarn Sleeping.png'))
                pygame.image.load(os.path.join(RESOURCE, 'dot-1.png')),
            ]
        }
         
        # current state of animation
        self.frame = 0 # frame for animation
        self.state = 'forward'
        self.moving = False
        
        # current image and position
        self.image = self.animations[self.state][self.frame]          
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        # instead of self.state ???
        self.state_left = False
        self.state_right = False
        self.state_up = False
        self.state_down = False
        self.state_standing = False
        self.state_sleeping = False
           
        self.is_collide = False
        self.vel = 5
        
    def draw(self, screen):
        self.image = self.animations[self.state][self.frame]          
        screen.blit(self.image, self.rect)
                 
    def update(self):
        # next frame of animation
        if self.moving:
            self.frame += 1
            if self.frame >= len(self.animations[self.state]):
                self.frame = 0

    def check_collisions(self, walls):
        
        self.is_collide = False

        for wall in walls:
            if self.rect.colliderect(wall):
                self.is_collide = True
                if self.state == 'left':
                    #self.rect.x += self.vel
                    self.rect.left = wall.right
                elif self.state == 'right':
                    #self.rect.x -= self.vel
                    self.rect.right = wall.left
                elif self.state == 'up':
                    #self.rect.y += self.vel
                    self.rect.top = wall.bottom
                elif self.state == 'down':
                    #self.rect.y -= self.vel
                    self.rect.bottom = wall.top
                break

    def handle_event(self, event=None):
        # instead of def apartment_movement():

        keys = pygame.key.get_pressed()

        self.moving = True
        
        if keys[pygame.K_LEFT]:
            if self.rect.left - self.vel >= 0 :  # allows the player to move left
                self.rect.x -= self.vel
                if self.state != 'up':
                    self.state = 'up'
                    self.frame = 0
        elif keys[pygame.K_RIGHT]:
            if self.rect.right + self.vel <= SCREEN_WIDTH:  # allows the player to move right
                self.rect.x += self.vel
                if self.state != 'right':
                    self.state = 'right'
                    self.frame = 0
        elif keys[pygame.K_UP]:
            if self.rect.top - self.vel >= 0:
                self.rect.y -= self.vel
                if self.state != 'up':
                    self.state = 'up'
                    self.frame = 0
        elif keys[pygame.K_DOWN]: 
            if self.rect.bottom + scarn.vel <= SCREEN_HEIGHT:
                self.rect.y += self.vel
                if self.state != 'down':
                    self.state = 'down'
                    self.frame = 0
        else: # clarifies the player is not moving left or right
            self.walk_count = 0
            self.moving = False
            
# --- functions --- (lower_case_names)
    
def draw_apartment(win):  # draws the apartment (1st scene)

    win.blit(bg, (0, 0))
    win.blit(bed, (322, 120))

    pygame.draw.rect(win, BLACK, (200, 470, 100, 10), 0)
    pygame.draw.polygon(win, BLACK, [(180, 473), (200, 488), (200, 458)], 0)

    for wall in all_walls:
        pygame.draw.rect(win, BLACK, wall)

    scarn.draw(win)

# --- main ---

# - init -

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()

# - objects -

all_walls = [
    pygame.Rect(243, 60, 8, 275),
    pygame.Rect(510, 60, 8, 275),
    pygame.Rect(243, 421, 215, 5),
    pygame.Rect(243, 330, 220, 5),
    pygame.Rect(510, 421, 145, 5),
    pygame.Rect(510, 330, 145, 5),
    pygame.Rect(700, 421, 57, 5),
    pygame.Rect(700, 330, 57, 5),
    pygame.Rect(43, 410, 120, 10),
    pygame.Rect(510, 335, 5, 90),
    pygame.Rect(460, 335, 5, 90),
    pygame.Rect(700, 335, 5, 90),
    pygame.Rect(650, 335, 5, 90),
]

scarn = Scarn(0, 0)

bg = pygame.surface.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
bg.fill(WHITE)

bed = pygame.surface.Surface((10, 20))
bed.fill(RED)

# - mainloop -

clock = pygame.time.Clock()
running = True

while running:

    # - events -
        
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

    scarn.handle_event()

    # - updates -

    scarn.check_collisions(all_walls)
    
    scarn.update() # update animation
    
    # - draws -
                    
    draw_apartment(screen)

    pygame.display.flip()
    
    clock.tick(30) # 30 FPS
    
# - end -
    
pygame.quit()

在此处输入图片说明 dot-1.png dot-1.png

在此处输入图片说明 dot-2.png dot-2.png

在此处输入图片说明 dot-3.png dot-3.png

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM