Методы реализации обнаружения столкновений для предотвращения движения персонажей сквозь стены

Чтобы персонаж мог двигаться по осям X и Y, не пробегая сквозь стены, вы можете реализовать обнаружение столкновений в своей игре или приложении. Вот несколько методов, которые вы можете использовать, а также примеры кода:

  1. Обнаружение столкновений на основе сетки:

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

    Пример кода (псевдокод в стиле Python):

    def move_character(x, y, dx, dy, grid):
       target_x = x + dx
       target_y = y + dy
    
       if grid[target_x][target_y] == 0:
           # Move the character to the target position
           x = target_x
           y = target_y
       else:
           # Collision detected, do not move the character
           print("Collision detected!")
  2. Ограничительные рамки, выровненные по осям (AABB):

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

    Пример кода (Unity C#):

    public class Character : MonoBehaviour
    {
       public float speed = 5f;
    
       private void Update()
       {
           float moveX = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
           float moveY = Input.GetAxis("Vertical") * speed * Time.deltaTime;
    
           // Calculate the target position
           Vector3 targetPosition = transform.position + new Vector3(moveX, moveY, 0f);
    
           // Check for collision with walls
           Collider2D[] colliders = Physics2D.OverlapBoxAll(targetPosition, transform.localScale, 0f);
           foreach (Collider2D collider in colliders)
           {
               if (collider.CompareTag("Wall"))
               {
                   // Collision detected, do not move the character
                   return;
               }
           }
    // Move the character to the target position
           transform.position = targetPosition;
       }
    }
  3. Рейкастинг:

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

    Пример кода (JavaScript с использованием игровой платформы Phaser 3):

    function update() {
       const cursors = this.input.keyboard.createCursorKeys();
       const speed = 200;
       const player = this.player;
    
       if (cursors.left.isDown) {
           player.setVelocityX(-speed);
       } else if (cursors.right.isDown) {
           player.setVelocityX(speed);
       } else {
           player.setVelocityX(0);
       }
    
       if (cursors.up.isDown) {
           player.setVelocityY(-speed);
       } else if (cursors.down.isDown) {
           player.setVelocityY(speed);
       } else {
           player.setVelocityY(0);
       }
    // Check for collision with walls
       const walls = this.wallLayer.getTilesWithinWorldXY(
           player.x, player.y, player.width, player.height, { isColliding: true }
       );
    
       if (walls.length > 0) {
           // Collision detected, stop the player's movement
           player.setVelocity(0);
       }
    }