Python Pygame碰撞错误

Python Pygame碰撞错误,python,pygame,collision,rect,Python,Pygame,Collision,Rect,我正在用pygame编写一个简单的躲避类游戏,希望我能开发它来构建类似小行星的东西 我使用.collidatelist()识别与随机生成的“小行星”的碰撞。但是当玩家进入小行星下方或上方时,会检测到碰撞 # -------------------- COLLISION -------------------- collision = player_rect.collidelist(objects) if collision != -1:

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

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

# -------------------- 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()
导入pygame,随机
从pygame.locals导入*
pygame.init()
pygame.display.set_标题('Dodge')
#icon=pygame.image.load('icon.png'))
#pygame.display.set_图标(图标)
#---------颜色--------------------
黑色=(0,0,0)
白色=(255255)
红色=(255,0,0)
绿色=(0155,0)
蓝色=(0,0255)
粉红色=(233,30,98)
#---------变量--------------------
显示宽度=600
显示高度=600
FPS=60
生命=3
clock=pygame.time.clock()
gameDisplay=pygame.display.set_模式((显示宽度、显示高度))
#-------实际比赛--------------------
def gameLoop():
全球生活
#---------玩家--------------------
播放器尺寸=20
x_位置=((显示宽度/2)-播放器尺寸)
y_位置=((显示高度/2)-播放器尺寸)
水平=5
player_rect=pygame.draw.rect(游戏显示,粉红色,(x_位置,y_位置,player_尺寸,player_尺寸))
#---------随机对象--------------------
对象尺寸=30
_对象的数量=10
random_x_pos,random_y_pos,object_x_vel,object_y_vel,objects=[],[],[],[],[],[]
对于范围内的整数(对象的数量):
x、 y,x水平,y水平=random.randint(0,显示宽度),random.randint(0,显示高度),random.randint(-5,5),random.randint(-5,5)
rect1=pygame.draw.rect(游戏显示,白色,(x,y,30,30))
再次=rect1.collide rect(player_rect)
同时:
x、 y=random.randint(0,显示宽度),random.randint(0,显示高度)
rect1=pygame.draw.rect(游戏显示,白色,(x,y,30,30))
再次=rect1.collide rect(player_rect)
随机位置附加(x)
随机位置附加(y)
对象x级追加(x级)
对象y级追加(y级)
#--------------事件处理--------------------
尽管如此:
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
pygame.quit()
退出
keys=pygame.key.get_pressed()
如果键[pygame.K_ESCAPE]:
pygame.quit()
退出
如果键[pygame.K_UP]和y_pos>0:
y_位置-=水平
如果键[pygame.K_DOWN]和(y_pos+player_dim)<显示高度:
y_位置+=水平
如果键[pygame.K_LEFT]和x_pos>0:
x_位置-=水平
如果键[pygame.K_RIGHT]和(x_pos+player_dim)<显示宽度:
x_位置+=水平
对于随机位置中的x:
随机位置[随机位置索引(x)]+=对象位置级别[随机位置索引(x)]
x+=对象x级[随机x位置索引(x)]
#---------碰撞--------------------
碰撞=玩家直接碰撞列表(对象)
如果发生碰撞!=-1:
寿命-=1
如果寿命>=0:
gameLoop()
其他:
pygame.quit()
退出
游戏显示。填充(黑色)
player_rect=pygame.draw.rect(游戏显示,粉红色,(x_位置,y_位置,player_尺寸,player_尺寸))
对于随机位置的obj:
y=随机位置[随机位置索引(obj)]
var=pygame.draw.rect(游戏显示,白色,(对象,y,对象尺寸,对象尺寸))
objects.append(var)
pygame.display.update()
时钟滴答声(FPS)
gameLoop()

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

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\ux\vel[random\ux\u pos.index(x)]
对代码没有影响,因为这之后紧接着是下一个循环迭代,其中x被分配给
random\ux\u 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
赋值给循环变量,从而覆盖它。这可能会导致不必要的行为。

for obj In random_x_pos:
循环中,您正在疯狂地向
对象
列表添加新的矩形。您不需要移动和绘制这些旧的矩形,因此您可以很快地获得数千个不可见的矩形,这些矩形仍然用于碰撞检测

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

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循环中的rect位置。您可以同时执行碰撞检测

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)

非常感谢,非常感谢。