我正在学习如何在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);
}
}
但这有明显的局限性,方向和角度之间没有联系。
我所知道的是,有一个函数,它以某种方式使用正切比来计算你所面对的象限,并给你一些数字来调整位置。但是我不知道这个函数,也不知道如何正确使用它。
我想做的是,当我按向上时,箭头沿着它所指的方向移动,当我按下向下时,箭头向后移动。左右两侧扫射。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);
}
}
有关从角度转换为x-y坐标的更多信息,请参阅本页http://www.mathsisfun.com/polar-cartesian-coordinates.html(向下滚动至"从极坐标转换为笛卡尔坐标"),或谷歌"转换极坐标笛卡尔坐标"。
从我所看到的,问题是您将strafe代码与direction代码相结合。两者应该是分开的。对于扫射,你所要做的就是将你的速度乘以一个单位向量。对于方向,可以将Vector2(包含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;
}
这使用来自<cmath>
的cos和sin,因此它希望参数以弧度为单位。然后你就做player.position += player.velocity * deltaTime
。