2D在特定方向上的移动

时间:2014-08-30 11:02:56

标签: c++ 2d sdl 2d-games

我正在学习如何在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);
        }
    }

但这有明显的局限性,方向和角度之间没有联系。

我所知道的是,有一个功能在某种程度上使用切线比率来计算你所面对的象限,并给你一些数字来调整位置。但是,我不知道该功能,也不知道如何正确使用它。

我希望能够做的是当我按下向上时箭头朝向它指向的方向移动,当我按下向下时向后移动箭头。与LEFT和RIGHT左右并肩。 A和D键用于转动角度。

非常感谢您可能知道的任何有用的算法。

编辑:角度(0)返回当前角度。

2 个答案:

答案 0 :(得分:1)

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(向下滚动到“从极坐标转换为笛卡尔”)或Google“转换极坐标笛卡尔”。

答案 1 :(得分:0)

从我所看到的,问题是你将你的strafe代码与你的方向代码结合起来。这两者应该是分开的。对于扫射,你所要做的就是将你的速度乘以单位矢量。对于方向,您将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