Ошибка столкновения Pygame - PullRequest
0 голосов
/ 11 мая 2018

Я пишу простую увлекательную игру в 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()

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

В цикле 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)
0 голосов
/ 11 мая 2018

Одна из ваших проблем заключается в следующем фрагменте кода:

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]

Однако обратите внимание, что в вашем коде есть и другие недостатки. Например, вы присваиваете внутреннему питону int переменную цикла и, следовательно, переопределяете его. Это может привести к нежелательному поведению.

...