Путь XNA Vector2, содержащийся внутри прямоугольника

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

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

//the cursor's coordinates should be the center of the target position
float x = mouseState.X - this.position.Width / 2;
float y = mouseState.Y - this.position.Height / 2;
Vector2 targetVector = new Vector2(x, y);
Vector2 dir = (targetVector - this.Center); //vector from source center to target
                                            //center

Я представляю мир, используя мозаичную карту, каждая ячейка имеет размер 32х32 пикселя.

int tileMap[,];

То, что я хочу сделать, это проверить, проходит ли вектор направления через синие плитки на карте. Синяя плитка равна 1 на карте.

Я не уверен, как это сделать. Я думал об использовании линейного уравнения и тригонометрических формул, но мне трудно это реализовать. Я попытался нормализовать вектор и умножить на 32, чтобы получить 32-пиксельные интервалы вдоль пути вектора, но это, похоже, не работает. Может кто-нибудь сказать мне, если есть что-то не так, или другой способ решить эту проблему? Спасибо

//collision with blue wall. Returns point of impact
    private bool CheckCollisionWithBlue(Vector2 dir)
    {
        int num = Worldmap.size; //32
        int i = 0;
        int intervals = (int)(dir.Length() / num + 1);  //the number of 32-pixel length 
                                                        //inervals on the vector, with an edge
        Vector2 unit = Vector2.Normalize(dir) * num;    //a vector of length 32 in the same 
                                                        //direction as dir.
        Vector2 v = unit;
        while (i <= intervals & false)
        {
            int x = (int)(v.X / num);
            int y = (int)(v.Y / num);
            int type = Worldmap.getType(y, x);
            if (type == 1) //blue tile
            {
                return true;
            }
            else
            {
                i++;
                v = unit * i;
            }
        }
        return false;
    }

1 ответ

Решение
  1. Вам нужно исходное положение тоже, а не только направление
  2. Может быть, вам нужно больше разрешения
  3. какие? удалить "ложную" оценку
  4. Вычисления для следующей позиции немного сложнее

 private bool CheckCollisionWithBlue(Vector2 source, Vector2 dir)
 {
    int num = 8; // pixel blocks of 8
    int i = 0;
    int intervals = (int)(dir.Length() / num);   

    Vector2 step = Vector2.Normalize(dir)*num;

    while (i <= intervals)
    {
        int x = (int)(source.X);
        int y = (int)(source.Y);
        int type = Worldmap.getType(y, x);
        if (type == 1) //blue tile
        {
            return true;
        }
        else
        {
            i++;
            source+=step;
        }
    }
    return false;
}

Это улучшит ваш код, но, возможно, неточно... это зависит от того, что вы пытаетесь сделать...

Возможно, вы найдете интересный алгоритм линии Брезенхема http://en.wikipedia.org/wiki/Bresenham's_line_algorithm

Вы должны понимать, что вы делаете не столкновение с объемом, а столкновение с линией, если корабль или персонаж или что-то еще, находящееся в исходной позиции, возможно, вам придется добавить больше calcs.

Другие вопросы по тегам