Я изучаю, как перемещаться по 2D-карте и вам нужна помощь с использованием функций тригонометрии.
Вот мой текущий код.
const Uint8 * key = SDL_GetKeyboardState(NULL);
if(key[SDL_SCANCODE_D]){
if(render_arrow){
arrow.Angle(1);
}
}
if(key[SDL_SCANCODE_A]){
if(render_arrow){
arrow.Angle(-1);
}
}
if(key[SDL_SCANCODE_LEFT]){
if(render_arrow){
arrow.set_location(arrow.X_Co() - 1, arrow.Y_Co());
}
}
if(key[SDL_SCANCODE_RIGHT]){
if(render_arrow){
arrow.set_location(arrow.X_Co() + 1, arrow.Y_Co());
}
}
if(key[SDL_SCANCODE_UP]){
if(render_arrow){
arrow.set_location(arrow.X_Co(), arrow.Y_Co() - 1);
}
}
if(key[SDL_SCANCODE_DOWN]){
if(render_arrow){
arrow.set_location(arrow.X_Co(), arrow.Y_Co() + 1);
}
}
Но это имеет очевидные ограничения и отсутствие связи между направлением и углом.
Я знаю, что есть функция, которая каким-то образом использует коэффициент касательной для вычисления квадранта, с которым вы сталкиваетесь, и дает вам некоторые номера для настройки местоположения. Однако я не знаю функции и как правильно ее использовать.
То, что я хотел бы сделать, - это стрелка двигаться в том направлении, в котором оно указывается, когда я нажимаю UP, а назад, когда нажимаю DOWN. И чтобы сражаться сбоку с ЛЕВОЙ и ПРАВОЙ. Клавиши A и D используются для поворота угла.
Любые полезные алгоритмы, которые вы, возможно, знаете, будут очень признательны.
Изменение: Угол (0) возвращает текущий угол.
if(key[SDL_SCANCODE_UP]){
if(render_arrow){
deltaX = AMOUNT_TO_MOVE_IN_FROM_ONE_KEYSTROKE * cos (arrow.angle());
deltaY = AMOUNT_TO_MOVE_IN_FROM_ONE_KEYSTROKE * sin (arrow.angle());
arrow.set_location(arrow.X_Co()+deltaX, arrow.Y_Co() +deltaY);
}
}
if(key[SDL_SCANCODE_DOWN]){
if(render_arrow){
//Note the -'s
deltaX = - AMOUNT_TO_MOVE_IN_FROM_ONE_KEYSTROKE * cos (arrow.angle());
deltaY = - AMOUNT_TO_MOVE_IN_FROM_ONE_KEYSTROKE * sin (arrow.angle());
arrow.set_location(arrow.X_Co()+deltaX, arrow.Y_Co() +deltaY);
}
}
Для получения дополнительной информации о преобразовании из угла в координаты xy см. Эту страницу http://www.mathsisfun.com/polar-cartesian-coordinates.html (прокрутите вниз до "Преобразовать с полярного в декартово"), или Google "преобразует полярность" декартово ".
Из того, что я вижу, проблема заключается в том, что вы комбинируете свой код страйфа с кодом направления. Эти два должны быть раздельными. Для обстрела все, что вам нужно сделать, это умножить свою скорость на единичный вектор. Для направления вы умножаете вектор2 (содержащий ваши компоненты cos и sin) на скорость. Вот пример:
// Our unit vectors
namespace vec
{
Vector2f UpVec{0.0f, -1.0f};
Vector2f DownVec{0.0f, 1.0f};
Vector2f LeftVec{-1.0f, 0.0f};
Vector2f RightVec{1.0f, 0.0f};
}
if (Keyboard::isKeyPressed(Keyboard::Left))
{
player.vel = player.speed * vec::LeftVec;
}
if (Keyboard::isKeyPressed(Keyboard::Right))
{
player.vel = player.speed * vec::RightVec;
}
if (Keyboard::isKeyPressed(Keyboard::Up))
{
float angle = player.angle * M_PI / 180;
Vector2f dir{(float)cos(angle), (float)sin(angle)};
player.vel = player.speed * dir;
}
if (Keyboard::isKeyPressed(Keyboard::Down))
{
float angle = player.angle * M_PI / 180;
Vector2f dir{-(float)cos(angle), -(float)sin(angle)};
player.vel = player.speed * dir;
}
Это использует cos и sin из <cmath>
поэтому он ожидает, что аргумент будет в радианах. Затем вы просто делаете player.position += player.velocity * deltaTime
.