Путь 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 ответ
- Вам нужно исходное положение тоже, а не только направление
- Может быть, вам нужно больше разрешения
- какие? удалить "ложную" оценку
- Вычисления для следующей позиции немного сложнее
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.