您如何解决:“AttributeError: 'Boundary' 对象没有属性 'rect'"? [英] How do you fix: "AttributeError: 'Boundary' object has no attribute 'rect'"?
问题描述
我正在制作一个平台游戏,在关卡的开头有一个边界,所以玩家不能无缘无故地继续向左走.我决定创建一个名为边界的类并将其添加到一个列表中,其中的规则是您不能通过它.但是,我不断收到此错误:AttributeError: 'Boundary' 对象没有属性 'rect'".有人可以解决这个问题吗?此外,也可以接受更好的方法来做到这一点.谢谢!
I am making a platformer game where there is a boundary in the beginning of the level, so the player can't just keep going to the left for no reason. I decided to make a class called boundary and add it into a list where the rules are you can't pass it. However, I keep getting this error: "AttributeError: 'Boundary' object has no attribute 'rect'". Can anybody fix this? Also, a better way to do this would also be accepted. Thanks!
class Boundary(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.boundary = pygame.Surface([15,600])
self.boundary.fill(WHITE)
self.boundary.set_colorkey(WHITE)
self.boundary_rect =
self.boundary.get_rect()
self.boundary_rect.x = -50
self.boundary_rect.y = 0
class Level01(Level):
def __init__(self, player):
Level.__init__(self, player)
level_boundary = [Boundary()]
for _ in level_boundary:
boundary = Boundary()
boundary.player = self.player
self.platform_boundary_list.add
(boundary)
class Player(pygame.sprite.Sprite):
def__init__(self):
super().init()
self.rect.x += self.change_x
block_hit_list = pygame.sprite.spritecollide(self,
self.level.platform_boundary_list, False)
for block in block_hit_list:
if self.change_x > 0:
self.rect.right = block.rect.left
elif self.change_x < 0:
self.rect.left = block.rect.right
self.rect.y += self.change_y
block_hit_list = pygame.sprite.spritecollide(self,
self.level.platform_boundary_list, False)
for block in block_hit_list:
if self.change_y > 0:
self.rect.bottom = block.rect.top
elif self.change_y < 0:
self.rect.top = block.rect.bottom
self.change_y = 0
推荐答案
没有运行代码,但是错误信息似乎合理.你的 Boundary
类有一个属性,boundary_rect
而不是 rect
(它似乎没有被 pygame 的 Sprite直接暴露)代码>类).用
block.boundary_rect
替换 block.rect
应该可以解决这个问题.
Haven't ran the code, but the error message seems reasonable. Your Boundary
class has a property, boundary_rect
rather than rect
(which doesn't appear to be directly exposed by pygame's Sprite
class). Replacing block.rect
with block.boundary_rect
should correct this.
更新:查看您的代码,我发现了一些问题,Player
和 Boundary
类都引用了不直接属于它们的 rect
属性父级,pygame.sprite.Sprite
.根据您的评论,我决定将代码重写为演示碰撞测试,不仅可以修复错误,还可以为您考虑如何组织代码提供一些想法.
Update:
Looking through your code, I saw a few issues, with both the Player
and the Boundary
classes referring to rect
properties that did not directly belong their parent, pygame.sprite.Sprite
. Based on your comments, I decided to rewrite the code into a demo collision test to not only fix the errors but also provide some ideas for how you could consider organizing your code.
演示非常简单;一个玩家和一堆随机块被绘制到屏幕上.玩家方块会在屏幕边缘反弹,碰撞的方块会被重新绘制成不同的颜色.结果如下:
The demo is pretty simple; a player and a bunch of random blocks are drawn to the screen. The player block bounces around the edges of the screen, and the colliding blocks are redrawn in a different color. The results look like this:
这是上面演示的代码.我添加了一堆注释来阐明代码的作用.如果有什么不清楚的,请告诉我:
Here is the code for the above demo. I added a bunch of comments to clarify what the code does. If anything is unclear, let me know:
import random
import pygame
from pygame.rect import Rect
from pygame.sprite import Sprite
from pygame.surface import Surface
class Block(Sprite):
def __init__(self, rect):
super().__init__()
self.idle_color = (255, 255, 255, 255)#white - if not colliding
self.hit_color = (0, 255, 0, 255)#green - if colliding
self.image = Surface((rect.w, rect.h))
self.color = self.idle_color#default
#Do NOT set color here, decided by collision status!
self.rect = rect
class Player(Sprite):
def __init__(self, rect):
super().__init__()
self.color = (255, 0, 0, 255)#red
self.image = Surface((rect.w, rect.h))
self.image.fill(self.color)
self.rect = rect
class Level(object):
def __init__(self, screen, player, blocks):
self.color = (20, 20, 20, 255)#gray background
self.screen = screen
self.player = player
self.blocks = blocks
#hard-coded player x and y speed for bounding around
self.player_speed_x = 1
self.player_speed_y = 1
#Bounces player off the screen edges
#Simply dummy method - no collisions here!
def move_player(self):
p_rect = self.player.rect
s_rect = self.screen.get_rect()
if p_rect.right >= s_rect.right or p_rect.left <= s_rect.left:
self.player_speed_x *= -1
if p_rect.top <= s_rect.top or p_rect.bottom >= s_rect.bottom:
self.player_speed_y *= -1
p_rect.move_ip(self.player_speed_x, self.player_speed_y)#modifies IN PLACE!
def handle_collisions(self):
#First set all blocks to default color
for block in self.blocks:
block.color = block.idle_color
hit_blocks = pygame.sprite.spritecollide(self.player, self.blocks, False)
for block in hit_blocks:
block.color = block.hit_color
#Clear screen with background color, then draw blocks, then draw player on top!
def draw(self):
self.screen.fill(self.color)
for block in self.blocks:
#update fill to color decided by handle_collisions function...
block.image.fill(block.color)
self.screen.blit(block.image, block.rect)
self.screen.blit(self.player.image, self.player.rect)
def update(self):
self.move_player()
self.handle_collisions()
self.draw()
if __name__ == "__main__":
pygame.init()
width = 400
height = 300
fps = 60
title = "Collision Test"
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption(title)
clock = pygame.time.Clock()
running = True
#Create a player
player_size = 20
player_x = random.randint(0, width - player_size)
player_y = random.randint(0, height - player_size)
player_rect = Rect(player_x, player_y, player_size, player_size)
player = Player(player_rect)
#Create some random blocks
blocks = []
num_blocks = 50
for i in range(num_blocks):
block_size = 20
block_x = random.randint(0, width - block_size)
block_y = random.randint(0, height - block_size)
block_rect = Rect(block_x, block_y, block_size, block_size)
block = Block(block_rect)
blocks.append(block)
#Create the level
level = Level(screen, player, blocks)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
level.update()
pygame.display.update()
clock.tick(fps)
这篇关于您如何解决:“AttributeError: 'Boundary' 对象没有属性 'rect'"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!