Обнаружение столкновений для 2D-платформера - PullRequest
2 голосов
/ 01 марта 2020

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

velocity += acceleration
position += velocity + 0.5 * acceleration

Все переменные являются векторами со значениями x и y. Это работает, как и ожидалось, проблема со столкновением. Мои правила:

  • Прекратите падать при приземлении на платформу.
  • Начните падать при беге с платформы.
  • Прекратите движение вверх при ударе по платформе во время прыжка.
  • Прекратите движение в сторону при ударе о стену, но сможете двигаться в противоположном направлении.

Проверка, сталкивается ли дно с платформой, довольно просто, но сложно определить, какая сторона столкнулась с платформой и иметь возможность установить правильную позицию для игрока.

Я пытался определить углы и середину со всех сторон, но так как моя скорость не равна 1px за кадр, иногда игрок падает быстро и обнаруживается как сторона а также.

Каков хороший подход для определения столкновения какой стороны?

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Хорошо, вот код, который может помочь определить, когда вы можете прыгнуть с платформы:

self.rect.y += 2
platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
self.rect.y -= 2

# If it is ok to jump, set our speed upwards
if len(platform_hit_list) > 0:
    velocity += acceleration
    position += velocity + 0.5 * acceleration

Затем код для обнаружения, когда вы падаете на платформу:

if self.rect.y >= constants.SCREEN_HEIGHT and self.change_y >= 0:
    self.change_y = 0
    self.rect.y = constants.SCREEN_HEIGHT

И, наконец, код столкновения:

block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
    # If we are moving right,
    # set our right side to the left side of the item we hit
    if self.change_x > 0:
        self.rect.right = block.rect.left
    elif self.change_x < 0:
        # Otherwise if we are moving left, do the opposite.
        self.rect.left = block.rect.right

# Move up/down
velocity += acceleration
position += velocity + 0.5 * acceleration

# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:

    # Reset our position based on the top/bottom of the object.
    if self.change_y > 0:
        self.rect.bottom = block.rect.top
    elif self.change_y < 0:
        self.rect.top = block.rect.bottom

    # Stop our vertical movement
    self.change_y = 0

Надеюсь, что все это каким-то образом поможет вам получить ответ, который вам необходим. Обратите внимание, что блоки ссылаются на платформы и будут проверять каждую платформу в данном списке, и я использую rects, поскольку это один из лучших способов проверки коллизий. Что касается change_x и change_y, то это просто переменные, которые хранят информацию о том, на сколько игрок будет двигаться.

0 голосов
/ 01 марта 2020

У меня есть пара платформерных игр в javascript, и вот как я реализовал столкновение:

1. Прекратите падать, когда приземлитесь на платформу: Вы можете задать свой спрайт прямоугольником в качестве граничной области, а затем использовать встроенный класс Pygames Rect для обнаружения пересечения. Когда это пересечение происходит между вашим хитбоксом спрайтов (прямоугольник) и прямоугольником платформ (еще один прямоугольник), вы устанавливаете скорость Y игроков на 0.

2. Начните падать, когда бегаете вне платформы. У меня обычно есть переменная, посвященная гравитации, и просто постоянно применяю это к спрайту, чтобы выложить sh вниз. Таким образом, после того как вы перестанете пересекаться с платформой, она упадет вниз.

3. Прекратите движение вверх, когда попадаете на платформу во время прыжка: То же, что и перед пересечением, просто установите скорость Y на 0 после столкновения с прямоугольником и позвольте игроку упасть из-за постоянной гравитации.

4. Прекратите двигаться в сторону, когда попали в стену, но сможете двигаться в противоположном направлении: То же самое, но на этот раз установите скорость X на 0. (если вы застряли в стене, вы всегда можете установить X на более чем 0, чтобы подтолкнуть вас обратно в игру)

Еще одна нота, если вы хотите что-то сделать только тогда, когда ваш спрайт достигнет определенного края платформы, вы можете просто создать прямоугольник, который выравнивается со стороной спрайта. Например, если бы я хотел увидеть, пересекается ли что-то с левой стороной моего спрайта, я мог бы использовать - высота: такая же высота - ширина: 1 - x: x + ширина - y: то же y

Документация на прямоугольники: https://www.pygame.org/docs/ref/rect.html

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