#python #pygame #pygame-surface
#python #pygame #pygame-поверхность
Вопрос:
Итак, я только начал учиться программировать, и я пытался создать эту небольшую игру с движущимися платформами. Я могу заставить работать обычные стены / платформы, но, похоже, я не могу понять, как заставить эти движущиеся платформы работать. Я продолжаю получать трассировку, которая выглядит следующим образом:
Traceback (most recent call last):
File "C:UsersJacobDesktopgametest.py", line 227, in <module>
walls.update()
File "C:Python34libsite-packagespygamesprite.py", line 462, in update
s.update(*args)
File "C:UsersJacobDesktopgametest.py", line 111, in update
hit = pygame.sprite.collide_rect(self, self.player)
File "C:Python34libsite-packagespygamesprite.py", line 1300, in collide_rect
return left.rect.colliderect(right.rect)
AttributeError: 'NoneType' object has no attribute 'rect'
Я думаю, что проблема связана с некоторыми из этих фрагментов кода, которые у меня есть, но я не совсем уверен.
class Wall(pygame.sprite.Sprite):
def __init__(self, width, height):
#creates the wall
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.image.fill(blue)
self.rect = self.image.get_rect()
######################################################
class MovingEnemy(Wall):
change_x = 0
change_y=0
boundary_top = 0
boundary_bottom = 0
boundary_left = 0
boundary_right = 0
player = None
level = None
def update(self):
# Move left/right
self.rect.x = self.change_x
# See if we hit the player
hit = pygame.sprite.collide_rect(self, self.player)
if hit:
# We did hit the player. Shove the player around and
# assume he/she won't hit anything else.
# If we are moving right, set our right side
# to the left side of the item we hit
if self.change_x < 0:
self.player.rect.right = self.rect.left
else:
# Otherwise if we are moving left, do the opposite.
self.player.rect.left = self.rect.right
# Move up/down
self.rect.y = self.change_y
# Check and see if we the player
hit = pygame.sprite.collide_rect(self, self.player)
if hit:
# We did hit the player. Shove the player around and
# assume he/she won't hit anything else.
# Reset our position based on the top/bottom of the object.
if self.change_y < 0:
self.player.rect.bottom = self.rect.top
else:
self.player.rect.top = self.rect.bottom
# Check the boundaries and see if we need to reverse
# direction.
if self.rect.bottom > self.boundary_bottom or self.rect.top < self.boundary_top:
self.change_y *= -1
cur_pos = self.rect.x - self.level.world_shift
if cur_pos < self.boundary_left or cur_pos > self.boundary_right:
self.change_x *= -1
wall = MovingEnemy(70,40)
wall.rect.x = 500
wall.rect.y = 400
wall.boundary_left = 250
wall.boundary_right = 800
wall.change_x = 1
walls.add(wall)
Я не уверен, что предоставил правильную информацию для получения помощи, но я честно пытаюсь. Я часами просматривал Интернет в поисках способа сделать это, и все, что я пытаюсь, похоже, не работает. Если кто-нибудь может понять этот беспорядочный беспорядок, который у меня есть, и помочь мне, я был бы очень признателен.
Редактировать: у меня есть класс player, должен ли я установить player в MovingEnemy в класс? Я не уверен, возможно ли это или на что именно я должен его установить. Вот мой класс игрока, если это упростит задачу.
class Player(pygame.sprite.Sprite):
#Sets the starting speed
change_x = 0
change_y = 0
walls = None
def __init__(self, x, y):
#creates the sprite for the player
pygame.sprite.Sprite.__init__(self)
#sets the size
self.image = pygame.Surface([25,25])
self.image.fill(green)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
def movement(self, x, y):
self.change_x = x
self.change_y = y
def update(self):
#changes the position of the player moving left and right
self.rect.x = self.change_x
#checks to see if the player sprite hits the wall
collision = pygame.sprite.spritecollide(self, self.walls, False)
for block in collision:
# If the player hits a block while moving right, it is set back
# to the left side of the block that was hit.
if self.change_x > 0:
self.rect.right = block.rect.left
# Does the same as above, except with moving left.
else:
self.rect.left = block.rect.right
#changes the position of the player moving up and down
self.rect.y = self.change_y
collision = pygame.sprite.spritecollide(self, self.walls, False)
for block in collision:
# Does the same as the above "for" except for moving up and down
if self.change_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.bottom
Ответ №1:
В вашем MovingEnemy
классе у вас есть атрибут с именем player
. player
‘s начинается с None
. Нигде в вашем коде вы не меняете player
ничего, кроме, None
, следовательно, player имеет тип none или a NoneType
. Ничто не имеет метода rect
, который используется вызываемым collide_rect
вами методом.
Ответ №2:
Ваш компилятор сообщает вам, что не так.
walls.update()
Сначала ваша программа вызывает walls.update , с чего и начинаются проблемы.
hit = pygame.sprite.collide_rect(self, self.player)
Затем вы пытаетесь обнаружить обнаружение попадания между стеной и игроком.
File "C:Python34libsite-packagespygamesprite.py", line 1300, in collide_rect
return left.rect.colliderect(right.rect)
Обратите внимание, что следующая подсказка появляется в этой строке, поскольку в конечном итоге это строка, которая вызвала проблему, и в ней сказано следующее:
AttributeError: 'NoneType' object has no attribute 'rect'
Либо ваша стена (self), либо (self.player) имеет тип None и, следовательно, не имеет атрибута ‘rect’, с помощью которого он может определить столкновение. Теперь обратите внимание:
player = None
Вы никогда не устанавливаете плеер! Таким образом, player имеет тип None и не имеет атрибута ‘rect’ для обнаружения столкновений.