碰撞检测在 pygame 中无法正常运行
collision detection not functioning properly in pygame
我正在处理我的第一个 pygame 项目,但似乎无法让碰撞检测正常工作,
这是我到目前为止的情况,我不太确定问题出在哪里
import random
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((288, 512))
clock = pygame.time.Clock()
game_font = pygame.font.Font('freesansbold.ttf', 40)
def draw_bg():
screen.blit(bg_surface, (0, bg_y_pos))
screen.blit(bg_surface, (0, bg_y_pos + 512))
def create_hazzard():
random_hazzard_pos = random.choice(hazzard_length)
left_hazzard = hazzard_surface.get_rect(midright=(random_hazzard_pos, 520))
right_hazzard = hazzard_surface.get_rect(midleft=(random_hazzard_pos + 75, 520))
return right_hazzard, left_hazzard
def move_hazzards(hazzards):
for hazzard in hazzards:
hazzard.centery -= 2
visible_hazzard = [hazzard for hazzard in hazzards if hazzard.top > -50]
return visible_hazzard
def draw_hazzards(hazzards):
for hazzard in hazzards:
if hazzard.left >= 288:
screen.blit(hazzard_surface, hazzard)
else:
flip_hazzard = pygame.transform.flip(hazzard_surface, True, False)
screen.blit(flip_hazzard, hazzard)
def check_collision(hazzards):
for hazzard in hazzards:
if player_rect.colliderect(hazzard):
death_sound.play()
print('collision')
return False
else:
return True
bg_y_pos = 0
player_x_pos = 144
player_y_pos = 256
player_x_change = 0
character_movement = 0
game_active = True
score = 0
player_surface = pygame.image.load('player.png').convert_alpha()
player_surface = pygame.transform.scale2x(player_surface)
player_rect = player_surface.get_rect(center=(player_x_pos, player_y_pos))
bg_surface = pygame.image.load('temp.png').convert()
hazzard_surface = pygame.image.load('temp_hazard.png')
death_sound = pygame.mixer.Sound('temp_hit.mp3')
hazzard_list = []
SPAWNHAZARD = pygame.USEREVENT
pygame.time.set_timer(SPAWNHAZARD, 1200)
hazzard_length = [200, 50, 100]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x_change -= 2
if event.key == pygame.K_RIGHT:
player_x_change += 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or pygame.K_RIGHT:
player_x_change = 0
if event.type == SPAWNHAZARD:
hazzard_list.extend(create_hazzard())
player_x_pos += player_x_change
# scolling background
bg_y_pos -= 2
if bg_y_pos <= -512:
bg_y_pos = 0
if game_active:
draw_bg()
hazzard_list = move_hazzards(hazzard_list)
draw_hazzards(hazzard_list)
player_rect.centerx += player_x_change
screen.blit(player_surface, player_rect)
check_collision(hazzard_list)
pygame.display.update()
clock.tick(120)
只有right_hazzard检测到碰撞,left_hazzard没有。如果我 return left_hazzard 在 right_hazzard 之前,那么 left_hazzard 可以检测到碰撞但不能 right_hazzard.
这里的问题与您可能已经发现的 check_collision
函数的逻辑有关。具体来说,问题是该函数在完全到达循环末尾之前 return 正在计算结果。
我猜您正在寻找的逻辑是,如果 'left_hazard' 或 'right_hazard' 有问题,则 return 错误,但将其扩展为任意长的列表。因为它实际上是一个很长的 'or' 语句。当检测到碰撞时,您仍然可以 return 'False',但是在循环完成之前不要 return true。
所以代码看起来更像这样:
def check_collision(hazzards):
for hazzard in hazzards:
if player_rect.colliderect(hazzard):
death_sound.play()
print('collision')
return False
# Outside the loop above
return True
注意:我假设函数 player_rect.colliderect
和 create_hazzard
的输出没有问题,因为我不确定前者是如何实现的。因此,虽然上述问题确实是一个有效的错误,但如果它不能解决您的问题,我会更仔细地查看 player_rect.colliderect
函数并检查传递给它的正确输入。
我正在处理我的第一个 pygame 项目,但似乎无法让碰撞检测正常工作, 这是我到目前为止的情况,我不太确定问题出在哪里
import random
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((288, 512))
clock = pygame.time.Clock()
game_font = pygame.font.Font('freesansbold.ttf', 40)
def draw_bg():
screen.blit(bg_surface, (0, bg_y_pos))
screen.blit(bg_surface, (0, bg_y_pos + 512))
def create_hazzard():
random_hazzard_pos = random.choice(hazzard_length)
left_hazzard = hazzard_surface.get_rect(midright=(random_hazzard_pos, 520))
right_hazzard = hazzard_surface.get_rect(midleft=(random_hazzard_pos + 75, 520))
return right_hazzard, left_hazzard
def move_hazzards(hazzards):
for hazzard in hazzards:
hazzard.centery -= 2
visible_hazzard = [hazzard for hazzard in hazzards if hazzard.top > -50]
return visible_hazzard
def draw_hazzards(hazzards):
for hazzard in hazzards:
if hazzard.left >= 288:
screen.blit(hazzard_surface, hazzard)
else:
flip_hazzard = pygame.transform.flip(hazzard_surface, True, False)
screen.blit(flip_hazzard, hazzard)
def check_collision(hazzards):
for hazzard in hazzards:
if player_rect.colliderect(hazzard):
death_sound.play()
print('collision')
return False
else:
return True
bg_y_pos = 0
player_x_pos = 144
player_y_pos = 256
player_x_change = 0
character_movement = 0
game_active = True
score = 0
player_surface = pygame.image.load('player.png').convert_alpha()
player_surface = pygame.transform.scale2x(player_surface)
player_rect = player_surface.get_rect(center=(player_x_pos, player_y_pos))
bg_surface = pygame.image.load('temp.png').convert()
hazzard_surface = pygame.image.load('temp_hazard.png')
death_sound = pygame.mixer.Sound('temp_hit.mp3')
hazzard_list = []
SPAWNHAZARD = pygame.USEREVENT
pygame.time.set_timer(SPAWNHAZARD, 1200)
hazzard_length = [200, 50, 100]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x_change -= 2
if event.key == pygame.K_RIGHT:
player_x_change += 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or pygame.K_RIGHT:
player_x_change = 0
if event.type == SPAWNHAZARD:
hazzard_list.extend(create_hazzard())
player_x_pos += player_x_change
# scolling background
bg_y_pos -= 2
if bg_y_pos <= -512:
bg_y_pos = 0
if game_active:
draw_bg()
hazzard_list = move_hazzards(hazzard_list)
draw_hazzards(hazzard_list)
player_rect.centerx += player_x_change
screen.blit(player_surface, player_rect)
check_collision(hazzard_list)
pygame.display.update()
clock.tick(120)
只有right_hazzard检测到碰撞,left_hazzard没有。如果我 return left_hazzard 在 right_hazzard 之前,那么 left_hazzard 可以检测到碰撞但不能 right_hazzard.
这里的问题与您可能已经发现的 check_collision
函数的逻辑有关。具体来说,问题是该函数在完全到达循环末尾之前 return 正在计算结果。
我猜您正在寻找的逻辑是,如果 'left_hazard' 或 'right_hazard' 有问题,则 return 错误,但将其扩展为任意长的列表。因为它实际上是一个很长的 'or' 语句。当检测到碰撞时,您仍然可以 return 'False',但是在循环完成之前不要 return true。
所以代码看起来更像这样:
def check_collision(hazzards):
for hazzard in hazzards:
if player_rect.colliderect(hazzard):
death_sound.play()
print('collision')
return False
# Outside the loop above
return True
注意:我假设函数 player_rect.colliderect
和 create_hazzard
的输出没有问题,因为我不确定前者是如何实现的。因此,虽然上述问题确实是一个有效的错误,但如果它不能解决您的问题,我会更仔细地查看 player_rect.colliderect
函数并检查传递给它的正确输入。