Re: Как обнаружить и завершить игру, когда спрайт pygame попадает в хвост?

Я создал игру, похожую на змейку, в которой пользователь перемещает спрайт, а спрайт оставляет след. Если пользователь наткнется на созданный им след, я бы хотел, чтобы игра закончилась, а игрок проиграл.

Одна из моих идей заключалась в том, чтобы каким-то образом отследить прошлые позиции спрайта (возможно, в списке), а затем создать оператор if, который приведет к проигрышу в игре (однако мне было немного непонятно, как это сделать).

Я получил ответ на этот вопрос, относящийся к этому списку:

"Я думаю, вы могли бы объявить двухмерный список следующим образом: pastPositions = [[400, 300]] Затем каждый раз, когда позиция игрока перемещается, проверяйте список:
на наличие строки в прошломPositions: If (player.rect.x == pastPositions[row][0] and player.rect.y == pastPositions[row][1]): done = true # game over Если игрок еще не был там, тогда добавьте эту позицию в список. pastPositions.append([player.rect.x, player.rect.y])

Похоже, это должно работать, но когда я пытаюсь запустить код (в Python Interactive), я получаю сообщение об ошибке, которое гласит: "line 86, in <module> if player.rect.x == astPositions[row][0] and player.rect.y == pastPositions[row][1]: IndexError: list index out of range"

Что бы вы посоветовали изменить диапазон, чтобы этого не произошло? Я попытался установить его ширину и высоту окна pygame.

import pygame

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

class Player(pygame.sprite.Sprite):

   def __init__(self, x, y):
       super().__init__()

       self.image = pygame.Surface([15, 15])
       self.image.fill(WHITE)

       self.rect = self.image.get_rect()
       self.rect.x = x
       self.rect.y = y

       self.change_x = 0
       self.change_y = 0


   def changespeed(self, x, y):
       self.change_x += x
       self.change_y += y


   def update(self):
       self.rect.x += self.change_x
       self.rect.y += self.change_y

pygame.init()

screen = pygame.display.set_mode([800, 600])

pygame.display.set_caption('The Etch-a-Sketch Game')

myfont = pygame.font.SysFont('Times', 20)
textsurface = myfont.render('This is the Etch-a-Sketch Game', False, (255, 255, 255))
screen.blit(textsurface,(0,0))

myfont = pygame.font.SysFont('Times', 15)
textsurface = myfont.render('Feel free to draw, but if you cross your own    path, you will die.', False, (255, 255, 255))
screen.blit(textsurface,(0,20))


player = Player(400, 300)
all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(player)

clock = pygame.time.Clock()
done = False

while not done:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player.changespeed(-3, 0)
            elif event.key == pygame.K_RIGHT:
                player.changespeed(3, 0)
            elif event.key == pygame.K_UP:
                player.changespeed(0, -3)
            elif event.key == pygame.K_DOWN:
                player.changespeed(0, 3)

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                player.changespeed(3, 0)
            elif event.key == pygame.K_RIGHT:
                player.changespeed(-3, 0)
            elif event.key == pygame.K_UP:
                player.changespeed(0, 3)
            elif event.key == pygame.K_DOWN:
                player.changespeed(0, -3)

    player.update()

    all_sprites_list.draw(screen)

    pygame.display.flip()
    clock.tick(75)

pygame.quit ()

person Gal    schedule 14.01.2019    source источник


Ответы (1)


Запись точек очень длинного пути кажется медленным способом проверки собственного хвоста.

Если цвет фона известен, возможно, проверьте цвета пикселей, отличных от фона, в области, в которую игрок собирается переместиться.

Можно получить цвет одного пикселя с помощью Surface.get_at ( ) функция. Это возвращает цвет RGBA, этот цвет можно сравнить с одним цветом фона (или известным цветом фона из растрового изображения в этой точке), что позволяет определить коллизию.

В player.update():

if (screen.get_at((player_next_x, player_next_y)) != BACKGROUND_COLOUR):
    # player hit tail

Конечно, может потребоваться проверить оба угла спрайта игрока (по направлению движения).

person Kingsley    schedule 15.01.2019
comment
Большое вам спасибо за ваш ответ! Вроде как работает, но у меня есть пара вопросов: - person Gal; 15.01.2019
comment
# 1 - Как вы определяете (player_next_x) и (player_next_y), принимая во внимание ввод пользователя с помощью клавиш направления? - person Gal; 15.01.2019
comment
# 2 - Я спрашиваю, потому что я пробовал это, просто используя (player.rect.x) и (player.rect.y), которые я уже определил, и, конечно же, система немедленно закрылась, потому что она обнаружила столкновение с ее текущим положением. - person Gal; 15.01.2019
comment
Когда код собирается нарисовать позицию следующего игрока, он использует эти координаты. Так что просто проверьте перед тем, как рисовать на растровом изображении. - person Kingsley; 16.01.2019