Судя по вашему видео, обнаружение столкновений не работает, если вы подходите к блоку снизу.
В общем (см. Пример ниже): Я столкнулся с той же «головоломкой» с моей игрой и, насколько я понял, есть два возможных пути.
- Предварительная проверка
Вы проверяете, насколько далеко игрок от ближайший «блок» и позволить игроку двигаться только пока. Это включает:
- проверку того, какие блоки наиболее близки к игроку
- проверку расстояния до каждого ближайшего блока и вычисление оставшихся возможных 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.