Pygame 碰撞错误



我正在pygame中编写一个简单的闪避游戏,希望我能开发它来构建类似小行星的东西。

我用.collidelist()来识别与随机生成的"小行星"的碰撞。但是当玩家进入小行星下方或上方时,会检测到碰撞。

# -------------------- COLLISION  --------------------
collision =  player_rect.collidelist(objects)
if collision != -1:
lives -= 1
if lives >= 0:
gameLoop()
else:
pygame.quit()
quit()

我的小行星似乎只是在垂直方向上移动,而不是水平方向,即使我已经改变了它们的水平值。

for x in random_x_pos:
random_y_pos[random_x_pos.index(x)] += object_y_vel[random_x_pos.index(x)]
x += object_x_vel[random_x_pos.index(x)]

这是我的其余代码:

import pygame, random
from pygame.locals import *
pygame.init()
pygame.display.set_caption('Dodge')
#icon = pygame.image.load('icon.png')
#pygame.display.set_icon(icon)
# -------------------- Colours  --------------------
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
green = (0,155,0)
blue = (0,0,255)
pink = (233,30,98)
# -------------------- Variables  --------------------
display_width = 600
display_height = 600
FPS = 60
lives = 3
clock = pygame.time.Clock()
gameDisplay = pygame.display.set_mode((display_width, display_height))
# -------------------- Actual Game  --------------------
def gameLoop():
global lives
# -------------------- Player  --------------------
player_dim = 20
x_pos = ((display_width / 2) - player_dim)
y_pos = ((display_height / 2) - player_dim)
vel = 5
player_rect = pygame.draw.rect(gameDisplay, pink, (x_pos, y_pos, player_dim, player_dim))
# -------------------- Random Objects  --------------------
object_dimensions  = 30
amount_of_objects = 10
random_x_pos, random_y_pos, object_x_vel, object_y_vel, objects = [], [], [], [], []
for int in range(amount_of_objects):
x, y, x_vel, y_vel = random.randint(0, display_width), random.randint(0, display_height), random.randint(-5,5), random.randint(-5,5)
rect1 = pygame.draw.rect(gameDisplay, white, (x, y, 30, 30))
again = rect1.colliderect(player_rect)
while again:
x, y = random.randint(0, display_width), random.randint(0, display_height)
rect1 = pygame.draw.rect(gameDisplay, white, (x, y, 30, 30))
again = rect1.colliderect(player_rect)
random_x_pos.append(x)
random_y_pos.append(y)
object_x_vel.append(x_vel)
object_y_vel.append(y_vel)
# -------------------- Event Handling  --------------------
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_ESCAPE]:
pygame.quit()
quit()
if keys[pygame.K_UP] and y_pos > 0:
y_pos -= vel
if keys[pygame.K_DOWN] and (y_pos + player_dim) < display_height:
y_pos += vel
if keys[pygame.K_LEFT] and x_pos > 0:
x_pos -= vel
if keys[pygame.K_RIGHT] and (x_pos + player_dim) < display_width:
x_pos += vel
for x in random_x_pos:
random_y_pos[random_x_pos.index(x)] += object_y_vel[random_x_pos.index(x)]
x += object_x_vel[random_x_pos.index(x)]
# -------------------- COLLISION  --------------------
collision =  player_rect.collidelist(objects)
if collision != -1:
lives -= 1
if lives >= 0:
gameLoop()
else:
pygame.quit()
quit()
gameDisplay.fill(black)
player_rect = pygame.draw.rect(gameDisplay, pink, (x_pos, y_pos, player_dim, player_dim))
for obj in random_x_pos:
y = random_y_pos[random_x_pos.index(obj)]
var = pygame.draw.rect(gameDisplay, white, (obj, y, object_dimensions, object_dimensions))
objects.append(var)
pygame.display.update()
clock.tick(FPS)

gameLoop()

for obj in random_x_pos:循环中,您疯狂地将新矩形附加到objects列表中。你不移动和绘制这些旧矩形,所以你很快就会得到数千个不可见的矩形,这些矩形仍然用于碰撞检测。

您必须重新构建代码。我建议创建一个矩形列表及其速度。

objects = []
for i in range(amount_of_objects):
rect = pygame.Rect(random.randint(0, display_width), random.randint(0, display_height), 30, 30)
velocity = [random.randint(-5,5), random.randint(-5,5)]
# Put the rect and the velocity into a list and append it to the objects.
objects.append([rect, velocity])

更新 for 循环中的矩形位置。您可以同时进行碰撞检测。

collision = False
for rect, velocity in objects:
rect.x += velocity[0]
rect.y += velocity[1]
if player_rect.colliderect(rect):
collision = True
if collision:
lives -= 1
# etc.

像这样绘制矩形:

for rect, velocity in objects:
pygame.draw.rect(gameDisplay, white, rect)

您的问题之一在于此代码片段:

for x in random_x_pos:
random_y_pos[random_x_pos.index(x)] += object_y_vel[random_x_pos.index(x)]
x += object_x_vel[random_x_pos.index(x)]

在这个循环中,x是循环变量,它在循环的每个循环中都会发生变化。行x += object_x_vel[random_x_pos.index(x)]对代码没有影响,因为这紧随其后的是下一个循环迭代,其中 x 被分配给下一个值random_x_pos

相反,您可以尝试如下操作:

for i in range(len(random_x_pos)):
random_y_pos[i] += object_y_vel[i]
random_x_pos[i] += object_x_vel[i]

但是,请注意,代码中还有其他缺陷。例如,您将 python 内部int分配给循环变量,从而覆盖它。这可能会导致不必要的行为。

最新更新