Обнаружение столкновений плиток 2D-игр

#c# #xna #collision-detection #xna-4.0

#c# #xna #обнаружение столкновений #xna-4.0

Вопрос:

У меня есть что-то вроде этого:

         // checking on which tile are players corners
        // ignore this big mess below, please. It can be put in smaller
        //  equations, but for now it does its job
        left_downX = ((int)Position.X) / 32 * 32 / 32 - map.mapOffsetX / 32 * 32 / 32;
        left_downY = ((int)Position.Y   height) / 32 * 32 / 32 - map.mapOffsetY / 32 * 32 / 32;

        right_downX = ((int)Position.X   width) / 32 * 32 / 32 - map.mapOffsetX / 32 * 32 / 32;
        right_downY = ((int)Position.Y   height) / 32 * 32 / 32 - map.mapOffsetY / 32 * 32 / 32;

        left_upX = ((int)Position.X) / 32 * 32 / 32 - map.mapOffsetX / 32 * 32 / 32;
        left_upY = ((int)Position.Y) / 32 * 32 / 32 - map.mapOffsetY / 32 * 32 / 32;

        right_upX = ((int)Position.X   width) / 32 * 32 / 32 - map.mapOffsetX / 32 * 32 / 32;
        right_upY = ((int)Position.Y) / 32 * 32 / 32 - map.mapOffsetY / 32 * 32 / 32;

        // checking if there is collision and responding to it
        if (map.mapData[left_downX, left_downY] == (int)Map.Tiles.air amp;amp;
            map.mapData[left_upX, left_upY] == (int)Map.Tiles.air)
        {
            if (keyboardState.IsKeyDown(Keys.A))
            {
                Speed.X = playerSpeed;
                Direction.X = MOVE_LEFT;
            }
        }
        if (map.mapData[right_downX, right_downY] == (int)Map.Tiles.air amp;amp;
            map.mapData[right_upX, right_upY] == (int)Map.Tiles.air)
        {
            if (keyboardState.IsKeyDown(Keys.D))
            {
                Speed.X = playerSpeed;
                Direction.X = MOVE_RIGHT;
            }
        }
        if (map.mapData[left_downX, left_downY] == (int)Map.Tiles.air amp;amp;
            map.mapData[right_downX, right_downY] == (int)Map.Tiles.air)
        {
            if (keyboardState.IsKeyDown(Keys.S))
            {
                Speed.Y = playerSpeed;
                Direction.Y = MOVE_DOWN;
            }
        }
        if (map.mapData[left_downX, left_downY] == (int)Map.Tiles.air amp;amp;
            map.mapData[right_downX, right_downY] == (int)Map.Tiles.air)
        {
            if (keyboardState.IsKeyDown(Keys.W))
            {
                Speed.Y = playerSpeed;
                Direction.Y = MOVE_UP;
            }
        }
  

И, поскольку кажется, что это работает правильно, это не так.
Например, когда игрок сталкивается с землей, он остается на ней и не может двигаться ни в каком направлении.
Это похоже на столкновение только с плитками по бокам, но там вы можете перейти на другую сторону.

Что я сделал не так? Может быть, есть лучшие способы проверки столкновений без перебора всех плиток?

Ответ №1:

Первые 8 строк вашего кода должны быть заменены прямоугольным объектом, который должен иметь тот же размер / местоположение, что и ваш спрайт.

Тогда вы можете просто вызвать прямоугольник.Метод пересечения с плитками, которые вы проверяете на столкновение.

Комментарии:

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

2. Лучшее, что можно сделать с картой на основе плиток, это проверять только те плитки, которые находятся рядом с объектом, который проверяется на столкновение. Это должно быть достаточно легко сделать с координатами рассматриваемого объекта. Для меня ваш плеер застревает, потому что ваше столкновение не работает должным образом.