Обнаружение столкновения против игрока и блоков на карте - PullRequest
2 голосов
/ 29 января 2020

Я сделал игровую карту, подобную этой

class Game_map:
    def __init__(self):
        self.land = pygame.image.load(r"C:\Users\name\OneDrive\Documents\A level python codes\final game\land.png").convert()
        self.height = 200
        self.width = 200
        self.land = pygame.transform.scale(self.land, (420,  250))
        self.land.set_colorkey((0, 0, 0))

        self.map_width = 6000
        self.map_height = 2000

        # 0 = emepty
        # 1 = land

        self.layout = [[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0 ],
                              [ 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0 ]]



    def draw_map(self):
        y = 0
        for layer in self.layout:
            x = 0
            for land in layer:
                if land == 1:
                    D.blit(self.land, (x * 400 - scroll[0],  y * 250 - scroll[1]))

                if land == 0:
                    pass

                x += 1
            y += 1




game_map = Game_map()

У меня есть класс игрока с self.x, self.y, self.width и self.height. Как бы я реализовать обнаружение столкновений с этим? Моя первоначальная идея заключалась в том, что я бы использовал self.x и self.y в функции draw_map(), чтобы потом можно было проверять наличие таких столкновений

 def draw_map(self):
        for layer in self.layout:
            for land in layer:
                if land == 1:
                    D.blit(self.land, (self.x * 400 - scroll[0], self. y * 250 - scroll[1]))

                if land == 0:
                    pass

                x += 1
            y += 1

Но когда я это делаю, ничто не обращается к экран. Я также попытался добавить значения x и y в оригинальной функции draw_map, упомянутой выше, в список и обнаружить коллизию с этим, но это стало действительно грязным и не работало. Есть ли другой способ обнаружения столкновений? Спасибо

1 Ответ

2 голосов
/ 29 января 2020

Прямой способ - найти столкновения прямоугольника игрока и прямоугольников препятствий.

Создать список индексов полей всех препятствий:

obstacles = [(i, j) for i in range(len(game_map.layout))
                    for j in range(len(game_map.layout[i]))
                    if game_map.layout[i][j] == 1]

Настройка a pygame.Rect для игрока:

player_rect = pygame.Rect(player.x, player.y, player.width, player.height) 

Используйте colliderect(), чтобы найти столкновения игрока и препятствия:

hit = [obj for obj in obstacles
           if player_rect.colliderect(
               pygame.Rect(obj[0]*400-scroll[0], obj[1]*250-scroll[1], 400, 250))]

if any(hit):
    print("hit")

Более хитрым и гораздо более эффективным методом является вычисление индексов поля для 4 углов прямоугольника игрока и оценка того, находится ли один из углов в поле с препятствием.

Настройка Игрок прямоугольник:

player_rect = pygame.Rect(player.x, player.y, player.width, player.height) 

Вычислить координаты для углов прямоугольника:

player_corners = [player_rect.topleft, player_rect.topright, 
                  player_rect.bottomleft, player_rect.bottomright]

Вычислить индексы поля, где угловые точки:

corner_indices = [((p[0]+scroll[0])//400, (p[1]+scroll[1])//250) for p in player_corners]

Оценить, содержит ли какое-либо поле препятствие:

hit = [ind for ind in corner_indices if game_map.layout[ind[0]][ind[1]]]

if (any(hit)):
    print("hit")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...