为什么删除命令对我的 Pygame 精灵列表不起作用?
Why won't the remove command work for my Pygame sprite list?
我正在 Pygame 中制作一个游戏,精灵刚好走到屏幕的尽头然后传送回来,并产生 1-2 个障碍物。当 1 个障碍物产生时,另一个障碍物仍然存在但不可见并结束游戏。即使我杀了它并将它从 sprite 列表中删除。我的代码有什么问题?
import pygame
import random
import time
jump_v = 7
isjump = False
v = 5
m = 1
o = 2
GRAY = (192, 192, 192)
RED = (255, 0, 0)
BLACK = (0 , 0, 0)
class Player(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
global o
self.rect.x += 7
if self.rect.colliderect(obstacle1.rect):
self.rect.x = 0
o = random.randint(0,2)
if o == 1:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.kill()
all_sprites_list.remove(obstacle2)
if o == 2:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if obstacle2.rect.x - obstacle1.rect.x > 0:
while obstacle1.rect.x - obstacle2 .rect.x < 100:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if self.rect.colliderect(obstacle2.rect):
self.rect.x = 0
o = random.randint(0,2)
if o == 1:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.kill()
all_sprites_list.remove(obstacle2)
if o == 2:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if obstacle2.rect.x - obstacle1.rect.x > 0:
while obstacle1.rect.x - obstacle2 .rect.x < 100:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if self.rect.x >= 950:
self.rect.x = 0
o = random.randint(0,2)
if o == 1:
obstacle1.rect.x = (random.randint(300, 900))
all_sprites_list.remove(obstacle2)
obstacle2.kill()
if o == 2:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if obstacle2.rect.x - obstacle1.rect.x > 0:
while obstacle1.rect.x - obstacle2 .rect.x < 100:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
class Obstacle1(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight,):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Obstacle2(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight,):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#main
color_line = (0,0,0)
pygame.init()
screen = pygame.display.set_mode([1000, 500])
all_sprites_list = pygame.sprite.Group()
player_width = 50
player_weight = 50
player = Player(RED, 0, 413, 50, 50)
if o == 1:
obstacle1 = Obstacle1(BLACK, random.randint(300, 900), 410 , 25, 100)
all_sprites_list.add(obstacle1)
if o == 2:
obstacle1 = Obstacle1(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle2 = Obstacle2(BLACK, random.randint(300, 900), 410 , 25, 100)
all_sprites_list.add(obstacle1)
all_sprites_list.add(obstacle2)
all_sprites_list.add(player)
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#clicks
keys = pygame.key.get_pressed()
if isjump == False:
#Up arrow key
if keys[pygame.K_UP]:
isjump = True
v = jump_v
#W key
if keys[pygame.K_w]:
isjump = True
v = jump_v
#Space bar
if keys[pygame.K_SPACE]:
isjump = True
v = jump_v
else:
m = 1 if v >= 0 else -1
F = m * (v**2)
player.rect.y -= F
v -= 1
if v < -jump_v:
isjump = False
#updates
all_sprites_list.update()
#draws
screen.fill((255, 255, 255))
pygame.display.set_caption('Jump game thing')
pygame.draw.line(screen, color_line, (0, 500), (1000, 500), 75)
all_sprites_list.draw(screen)
pygame.display.flip()
o = random.randint(0, 2)
clock.tick(30)
pygame.quit()
不需要调用all_sprites_list.remove()
。 kill
从所有组中删除精灵。
为障碍物创建一个单独的pygame.sprite.Group
和一个移除所有当前障碍物并生成新障碍物的函数:
all_sprites_list = pygame.sprite.Group()
obstacle_group = pygame.sprite.Group()
def create_new_obstacles():
for obstacle in obstacle_group:
obstacle.kill()
o = random.randint(0, 1)+1
if o > 0:
obstacle1 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle1)
all_sprites_list.add(obstacle1)
if o > 1:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
while abs(obstacle1.rect.x - obstacle2.rect.x) < 100:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle2)
all_sprites_list.add(obstacle2)
使用pygame.sprite.spritecollide
检测玩家与障碍物的碰撞。检测到碰撞时创建新障碍物:
class Player(pygame.sprite.Sprite):
# [...]
def update(self):
self.rect.x += 7
if pygame.sprite.spritecollide(self, obstacle_group, False):
self.rect.x = 0
create_new_obstacles()
if self.rect.x >= 950:
self.rect.x = 0
create_new_obstacles()
classes 的概念是您有 1 个 class 但多个具有相同 class 类型的对象(参见 Classes)。您不需要 classes Obstacle1
和 Obstacle2
。 Obstacle
就够了。
完整示例:
import pygame
import random
jump_v = 7
isjump = False
v = 5
m = 1
GRAY = (192, 192, 192)
RED = (255, 0, 0)
BLACK = (0 , 0, 0)
class Player(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
self.rect.x += 7
if pygame.sprite.spritecollide(self, obstacle_group, False):
self.rect.x = 0
create_new_obstacles()
if self.rect.x >= 950:
self.rect.x = 0
create_new_obstacles()
class Obstacle(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight,):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#main
color_line = (0,0,0)
pygame.init()
screen = pygame.display.set_mode([1000, 500])
player_width = 50
player_weight = 50
def create_new_obstacles():
for obstacle in obstacle_group:
obstacle.kill()
o = random.randint(0, 1)+1
if o > 0:
obstacle1 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle1)
all_sprites_list.add(obstacle1)
if o > 1:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
while abs(obstacle1.rect.x - obstacle2.rect.x) < 100:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle2)
all_sprites_list.add(obstacle2)
all_sprites_list = pygame.sprite.Group()
obstacle_group = pygame.sprite.Group()
player = Player(RED, 0, 413, 50, 50)
create_new_obstacles()
all_sprites_list.add(player)
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#clicks
keys = pygame.key.get_pressed()
if isjump == False:
#Up arrow key
if keys[pygame.K_UP]:
isjump = True
v = jump_v
#W key
if keys[pygame.K_w]:
isjump = True
v = jump_v
#Space bar
if keys[pygame.K_SPACE]:
isjump = True
v = jump_v
else:
m = 1 if v >= 0 else -1
F = m * (v**2)
player.rect.y -= F
v -= 1
if v < -jump_v:
isjump = False
#updates
all_sprites_list.update()
#draws
screen.fill((255, 255, 255))
pygame.display.set_caption('Jump game thing')
pygame.draw.line(screen, color_line, (0, 500), (1000, 500), 75)
all_sprites_list.draw(screen)
pygame.display.flip()
clock.tick(30)
pygame.quit()
我正在 Pygame 中制作一个游戏,精灵刚好走到屏幕的尽头然后传送回来,并产生 1-2 个障碍物。当 1 个障碍物产生时,另一个障碍物仍然存在但不可见并结束游戏。即使我杀了它并将它从 sprite 列表中删除。我的代码有什么问题?
import pygame
import random
import time
jump_v = 7
isjump = False
v = 5
m = 1
o = 2
GRAY = (192, 192, 192)
RED = (255, 0, 0)
BLACK = (0 , 0, 0)
class Player(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
global o
self.rect.x += 7
if self.rect.colliderect(obstacle1.rect):
self.rect.x = 0
o = random.randint(0,2)
if o == 1:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.kill()
all_sprites_list.remove(obstacle2)
if o == 2:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if obstacle2.rect.x - obstacle1.rect.x > 0:
while obstacle1.rect.x - obstacle2 .rect.x < 100:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if self.rect.colliderect(obstacle2.rect):
self.rect.x = 0
o = random.randint(0,2)
if o == 1:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.kill()
all_sprites_list.remove(obstacle2)
if o == 2:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if obstacle2.rect.x - obstacle1.rect.x > 0:
while obstacle1.rect.x - obstacle2 .rect.x < 100:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if self.rect.x >= 950:
self.rect.x = 0
o = random.randint(0,2)
if o == 1:
obstacle1.rect.x = (random.randint(300, 900))
all_sprites_list.remove(obstacle2)
obstacle2.kill()
if o == 2:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
if obstacle2.rect.x - obstacle1.rect.x > 0:
while obstacle1.rect.x - obstacle2 .rect.x < 100:
obstacle1.rect.x = (random.randint(300, 900))
obstacle2.rect.x = (random.randint(300, 900))
class Obstacle1(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight,):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Obstacle2(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight,):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#main
color_line = (0,0,0)
pygame.init()
screen = pygame.display.set_mode([1000, 500])
all_sprites_list = pygame.sprite.Group()
player_width = 50
player_weight = 50
player = Player(RED, 0, 413, 50, 50)
if o == 1:
obstacle1 = Obstacle1(BLACK, random.randint(300, 900), 410 , 25, 100)
all_sprites_list.add(obstacle1)
if o == 2:
obstacle1 = Obstacle1(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle2 = Obstacle2(BLACK, random.randint(300, 900), 410 , 25, 100)
all_sprites_list.add(obstacle1)
all_sprites_list.add(obstacle2)
all_sprites_list.add(player)
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#clicks
keys = pygame.key.get_pressed()
if isjump == False:
#Up arrow key
if keys[pygame.K_UP]:
isjump = True
v = jump_v
#W key
if keys[pygame.K_w]:
isjump = True
v = jump_v
#Space bar
if keys[pygame.K_SPACE]:
isjump = True
v = jump_v
else:
m = 1 if v >= 0 else -1
F = m * (v**2)
player.rect.y -= F
v -= 1
if v < -jump_v:
isjump = False
#updates
all_sprites_list.update()
#draws
screen.fill((255, 255, 255))
pygame.display.set_caption('Jump game thing')
pygame.draw.line(screen, color_line, (0, 500), (1000, 500), 75)
all_sprites_list.draw(screen)
pygame.display.flip()
o = random.randint(0, 2)
clock.tick(30)
pygame.quit()
不需要调用all_sprites_list.remove()
。 kill
从所有组中删除精灵。
为障碍物创建一个单独的pygame.sprite.Group
和一个移除所有当前障碍物并生成新障碍物的函数:
all_sprites_list = pygame.sprite.Group()
obstacle_group = pygame.sprite.Group()
def create_new_obstacles():
for obstacle in obstacle_group:
obstacle.kill()
o = random.randint(0, 1)+1
if o > 0:
obstacle1 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle1)
all_sprites_list.add(obstacle1)
if o > 1:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
while abs(obstacle1.rect.x - obstacle2.rect.x) < 100:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle2)
all_sprites_list.add(obstacle2)
使用pygame.sprite.spritecollide
检测玩家与障碍物的碰撞。检测到碰撞时创建新障碍物:
class Player(pygame.sprite.Sprite):
# [...]
def update(self):
self.rect.x += 7
if pygame.sprite.spritecollide(self, obstacle_group, False):
self.rect.x = 0
create_new_obstacles()
if self.rect.x >= 950:
self.rect.x = 0
create_new_obstacles()
classes 的概念是您有 1 个 class 但多个具有相同 class 类型的对象(参见 Classes)。您不需要 classes Obstacle1
和 Obstacle2
。 Obstacle
就够了。
完整示例:
import pygame
import random
jump_v = 7
isjump = False
v = 5
m = 1
GRAY = (192, 192, 192)
RED = (255, 0, 0)
BLACK = (0 , 0, 0)
class Player(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def update(self):
self.rect.x += 7
if pygame.sprite.spritecollide(self, obstacle_group, False):
self.rect.x = 0
create_new_obstacles()
if self.rect.x >= 950:
self.rect.x = 0
create_new_obstacles()
class Obstacle(pygame.sprite.Sprite):
def __init__(self, color, x, y, width, weight,):
super().__init__()
self.color = color
self.image = pygame.Surface([width, weight])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#main
color_line = (0,0,0)
pygame.init()
screen = pygame.display.set_mode([1000, 500])
player_width = 50
player_weight = 50
def create_new_obstacles():
for obstacle in obstacle_group:
obstacle.kill()
o = random.randint(0, 1)+1
if o > 0:
obstacle1 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle1)
all_sprites_list.add(obstacle1)
if o > 1:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
while abs(obstacle1.rect.x - obstacle2.rect.x) < 100:
obstacle2 = Obstacle(BLACK, random.randint(300, 900), 410 , 25, 100)
obstacle_group.add(obstacle2)
all_sprites_list.add(obstacle2)
all_sprites_list = pygame.sprite.Group()
obstacle_group = pygame.sprite.Group()
player = Player(RED, 0, 413, 50, 50)
create_new_obstacles()
all_sprites_list.add(player)
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#clicks
keys = pygame.key.get_pressed()
if isjump == False:
#Up arrow key
if keys[pygame.K_UP]:
isjump = True
v = jump_v
#W key
if keys[pygame.K_w]:
isjump = True
v = jump_v
#Space bar
if keys[pygame.K_SPACE]:
isjump = True
v = jump_v
else:
m = 1 if v >= 0 else -1
F = m * (v**2)
player.rect.y -= F
v -= 1
if v < -jump_v:
isjump = False
#updates
all_sprites_list.update()
#draws
screen.fill((255, 255, 255))
pygame.display.set_caption('Jump game thing')
pygame.draw.line(screen, color_line, (0, 500), (1000, 500), 75)
all_sprites_list.draw(screen)
pygame.display.flip()
clock.tick(30)
pygame.quit()