如何解决:“ AttributeError:'Class'对象没有属性'rect'”

时间:2019-07-29 01:19:53

标签: python python-3.x pygame pycharm

我正在屏幕上砌墙,所以我的玩家精灵无法越过它们。我想我已经完成了所有的“ get_rect”操作,但是我一直收到此错误消息: TypeError:参数必须是矩形样式对象

 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')

1 个答案:

答案 0 :(得分:-1)

代码中存在许多问题,因此很难描述所有更改。

这不是理想的解决方案,但至少可以起作用。

它检查与墙壁的碰撞,并在向下移动时绘制动画(不同颜色的点)。

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()

enter image description here dot-1.png

enter image description here dot-2.png

enter image description here dot-3.png