Игрок продолжает придерживаться платформы Collision Pygame - PullRequest
1 голос
/ 04 августа 2020

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

ВИДЕО <как вы видите, мой плеер продолжает застрял на платформе, то же самое для левого и правого, когда я сталкиваюсь с платформой, мой игрок просто застревает без надлежащего столкновения </p>

        # collisions
        for platform in platforms:
            if playerman.rect.colliderect(platform.rect):
                collide = True
                playerman.isJump = False
                if (platform.rect.collidepoint(playerman.rect.right, playerman.rect.bottom) or
                    platform.rect.collidepoint(playerman.rect.left, playerman.rect.bottom)):
                    playerman.y = platform.rect.top - playerman.height + 1
                    playerman.moveright = True
                    playerman.moveleft = True
                
                if (platform.rect.collidepoint(playerman.rect.right, playerman.rect.top) or
                    platform.rect.collidepoint(playerman.rect.right, playerman.rect.bottom - 10)):
                    playerman.moveright = False
                elif (platform.rect.collidepoint(playerman.rect.left, playerman.rect.top) or
                      platform.rect.collidepoint(playerman.rect.left, playerman.rect.bottom - 10)):
                    playerman.moveleft = False
            else:
                playerman.moveright = True
                playerman.moveleft = True
                


мой полный код: скрипт

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

1 Ответ

1 голос
/ 04 августа 2020

Судя по вашему видео, обнаружение столкновений не работает, если вы подходите к блоку снизу.

В общем (см. Пример ниже): Я столкнулся с той же «головоломкой» с моей игрой и, насколько я понял, есть два возможных пути.

  1. Предварительная проверка

Вы проверяете, насколько далеко игрок от ближайший «блок» и позволить игроку двигаться только пока. Это включает:

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

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

  • перемещает игрока в соответствии с его скоростью в полной мере
  • проверьте коллизии для всех близких блоков (или всех блоков на карте для начала, и вы можете улучшить производительность оттуда)
  • если вы получите столкновение, рассчитайте, насколько игрок пересекается со встречным блоком. Это легко, если хитбокс вашего игрока представляет собой прямоугольник и вы работаете с тайловой картой, составленной из блоков rect angular, вы можете просто вычесть координаты player.x и block.x
  • переместить игрока назад (перед обновлением экран) на это количество пикселей.

Если вы хотите узнать об этом больше и получить подробные примеры кода (если вы не хотите пытаться ошибиться самостоятельно, пока не поймете это out) Я предлагаю поискать на youtube обнаружение столкновений pygame-2D, там есть отличные учителя.

Вот отрывок из моего метода collisiondetection_x_axis () (сам ссылается на игрока!)

# move player etc ...
for tile in map_tiles: # for all tiles on the map
    if pygame.sprite.collide_rect(self.hitboxBody, tile):
        if self.SpeedX < 0 and tile.rect.right > self.hitboxBody.rect.left:  # moving left and collision
             # move char back to "in front of the wall"
             self.rect.x += tile.rect.right - self.hitboxBody.rect.left
             self.SpeedX = 0  # set speedX to zero, as we cannot move in that direction anymore

        elif self.SpeedX > 0 and self.hitboxBody.rect.right > tile.rect.left:  # moving right and collision
             # move char back to "in front of the wall"
             self.rect.x -= self.hitboxBody.rect.right - tile.rect.left
             self.SpeedX = 0  # set speedX to zero, as we cannot move in that direction anymore

collision_detection_y_axis:

for tile in map_tiles: # for all tiles on the map
    if pygame.sprite.collide_rect(self.hitboxBody, tile):
        if self.SpeedY < 0 and tile.rect.bottom > self.hitboxBody.rect.top:  # moving up
            self.rect.y += tile.rect.bottom - self.hitboxBody.rect.top # move char back to "below the wall"
            self.SpeedY = 0
        elif self.SpeedY > 0 and self.hitboxBody.rect.bottom > tile.rect.top:  # moving downwards
            self.rect.y -= self.hitboxBody.rect.bottom - tile.rect.top # move back to "on top of the wall"
            self.SpeedY = 0
            self.jumping = False  # on ground

Изменить: это требует, чтобы ваше перемещение между проверками столкновений было меньше ширины блока, иначе ваш персонаж может «глючить» через блоки, если у него достаточно скорости.

Примечание: вы должны учитывать направление, в котором движется ваш игрок перед вы выполняете тесты столкновений, он делает это легче определить, с какой стороны игрок может первой столкнуться с блоком. Например, если вы двигаетесь вправо, то правая сторона игрока столкнется с левой стороной блока. Затем напишите обнаружение столкновения для этих двух точек, а также последующее действие (например, сброс в позицию перед блоком и speed_x = 0)

PS: Попробуйте использовать функцию pygame.Rect. colliderect , он проверяет, перекрываются ли два прямоугольника (= столкновение), я чувствую, как вы настраиваете свои функции точки столкновения, не возвращают столкновения для всех возможных сценариев ios.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...