使用 Sprite 组时 Sprite 移动不起作用
Sprite movement not working when using Sprite groups
游戏的重点是敌人向你移动,如果锤子与他们相撞,他们就会消失。但由于某种原因,敌人要么不动,要么在被击中时不消失。这是检查碰撞的代码:
if len(enemy_group) <= 0:
enemy = Enemy(random.randint(0, 1000), random.randint(0, 700))
enemy_group.add(enemy)
for enemy in enemy_group:
enemy.move(player.x, player.y)
if pygame.sprite.spritecollide(hammer, enemy_group, True):
move_away, move_back = False, True
enemy_group.draw(screen)
此代码确实会移除被击中的敌人,但它们不会向玩家移动。相反,如果我这样做:
if len(enemy_group) <= 0:
enemy = Enemy(random.randint(0, 1000), random.randint(0, 700))
enemy_group.add(enemy)
for enemy in enemy_group:
enemy.move(player.x, player.y)
enemy.draw(screen)
if pygame.sprite.spritecollide(hammer, enemy_group, True):
move_away, move_back = False, True
然后敌人向玩家移动,但被击中后并没有消失。我不能让他们同时做这两件事。
如果需要的话,这里有锤子和敌人类:
class Hammer:
def __init__(self, x, y, image):
self.image = image
self.x = x
self.y = y
self.rect = self.image.get_rect(center = (self.x, self.y))
self.rot = 0
def draw(self, screen):
screen.blit(self.rot_image, (self.rect))
def get_movement_hammer(self, x, y):
dirx, diry = x - self.x, y - self.y
direc = dirx, diry
length = math.hypot(*direc)
if length == 0.0:
dirx, diry = 0, -1
else:
dirx, diry = dirx/length, diry/length
return dirx, diry
def move_hammer(self, dirx, diry, xspeed, yspeed):
self.rot_speed = 15
self.rot = (self.rot + self.rot_speed) % 360
self.rot_image = pygame.transform.rotozoom(self.image, self.rot, 1)
self.rect = self.rot_image.get_rect(center = (self.x, self.y))
self.x += (dirx * xspeed)
self.y += (diry * yspeed)
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.image = enemy_image
self.rect = self.image.get_rect(center = (self.x, self.y))
def move(self, px, py):
dirx, diry = px - self.x, py - self.y
direc = dirx, diry
length = math.hypot(*direc)
if length == 0.0:
dirx, diry = 0, -1
else:
dirx, diry = dirx/length, diry/length
self.x += dirx * 2
self.y += diry * 2
def draw(self, screen):
screen.blit(self.image, (self.x, self.y))
阅读文档 pygame.sprite.Group.draw()
:
Draws the contained Sprites to the Surface argument. This uses the Sprite.image
attribute for the source surface, and Sprite.rect
for the position.
rect
属性也用于碰撞检测(例如 pygame.sprite.spritecollide
)。因此,移动后需要更新敌人的rect
属性:
class Enemy(pygame.sprite.Sprite):
# [...]
def move(self, px, py):
dirx, diry = px - self.x, py - self.y
direc = dirx, diry
length = math.hypot(*direc)
if length == 0.0:
dirx, diry = 0, -1
else:
dirx, diry = dirx/length, diry/length
self.x += dirx * 2
self.y += diry * 2
self.rect.center = round(self.x), round(self.y) # <---
# [...]
游戏的重点是敌人向你移动,如果锤子与他们相撞,他们就会消失。但由于某种原因,敌人要么不动,要么在被击中时不消失。这是检查碰撞的代码:
if len(enemy_group) <= 0:
enemy = Enemy(random.randint(0, 1000), random.randint(0, 700))
enemy_group.add(enemy)
for enemy in enemy_group:
enemy.move(player.x, player.y)
if pygame.sprite.spritecollide(hammer, enemy_group, True):
move_away, move_back = False, True
enemy_group.draw(screen)
此代码确实会移除被击中的敌人,但它们不会向玩家移动。相反,如果我这样做:
if len(enemy_group) <= 0:
enemy = Enemy(random.randint(0, 1000), random.randint(0, 700))
enemy_group.add(enemy)
for enemy in enemy_group:
enemy.move(player.x, player.y)
enemy.draw(screen)
if pygame.sprite.spritecollide(hammer, enemy_group, True):
move_away, move_back = False, True
然后敌人向玩家移动,但被击中后并没有消失。我不能让他们同时做这两件事。
如果需要的话,这里有锤子和敌人类:
class Hammer:
def __init__(self, x, y, image):
self.image = image
self.x = x
self.y = y
self.rect = self.image.get_rect(center = (self.x, self.y))
self.rot = 0
def draw(self, screen):
screen.blit(self.rot_image, (self.rect))
def get_movement_hammer(self, x, y):
dirx, diry = x - self.x, y - self.y
direc = dirx, diry
length = math.hypot(*direc)
if length == 0.0:
dirx, diry = 0, -1
else:
dirx, diry = dirx/length, diry/length
return dirx, diry
def move_hammer(self, dirx, diry, xspeed, yspeed):
self.rot_speed = 15
self.rot = (self.rot + self.rot_speed) % 360
self.rot_image = pygame.transform.rotozoom(self.image, self.rot, 1)
self.rect = self.rot_image.get_rect(center = (self.x, self.y))
self.x += (dirx * xspeed)
self.y += (diry * yspeed)
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.image = enemy_image
self.rect = self.image.get_rect(center = (self.x, self.y))
def move(self, px, py):
dirx, diry = px - self.x, py - self.y
direc = dirx, diry
length = math.hypot(*direc)
if length == 0.0:
dirx, diry = 0, -1
else:
dirx, diry = dirx/length, diry/length
self.x += dirx * 2
self.y += diry * 2
def draw(self, screen):
screen.blit(self.image, (self.x, self.y))
阅读文档 pygame.sprite.Group.draw()
:
Draws the contained Sprites to the Surface argument. This uses the
Sprite.image
attribute for the source surface, andSprite.rect
for the position.
rect
属性也用于碰撞检测(例如 pygame.sprite.spritecollide
)。因此,移动后需要更新敌人的rect
属性:
class Enemy(pygame.sprite.Sprite):
# [...]
def move(self, px, py):
dirx, diry = px - self.x, py - self.y
direc = dirx, diry
length = math.hypot(*direc)
if length == 0.0:
dirx, diry = 0, -1
else:
dirx, diry = dirx/length, diry/length
self.x += dirx * 2
self.y += diry * 2
self.rect.center = round(self.x), round(self.y) # <---
# [...]