我正在尝试使用 SFML 用 C++ 编写一个基本的小行星游戏。虽然我能够相当轻松地移动我的三角形(玩家),但它的移动方式我并不十分满意。
目前,运动与它所面对的方向无关。例如,如果我按“w”向前移动,三角形将简单地向上移动屏幕而不管它的方向。
我想让三角形做的是在按下“w”键时向前移动,但使其实际移动方向(相对于屏幕尺寸)相对于它所面对的实际方向。
所以,如果三角形的前端朝右,当按下“W”时,它会向右移动。如果在这种情况下按下“S”,它将向左移动。“A”会使其向上移动,当然“D”会使其向下移动。
我当前的代码没有完成这一点 - 我认为对此有一个非常hacky的解决方案,但如果可能的话,我宁愿从更数学和更优雅的角度来解决这个问题。
那么,实现这一目标的最佳方法是什么?
我有三种相关方法:一种用于处理键盘输入,另一种用于处理鼠标移动,以及一种更新方法。
代码
void Game::OnKeyPress( void )
{
int count = 0;
const float playerCenterMag = Magnitude( mPlayer.GetShape().GetCenter() );
//Shoddy attempt resulting in absolutely nothing of note
const float moveRateX = ( cosf( mMouseAoR ) * playerCenterMag ) + mPlayer.MoveSpeed;
const float moveRateY = ( sinf( mMouseAoR ) * playerCenterMag ) + mPlayer.MoveSpeed;
if ( mInput.IsKeyDown( sf::Key::W ) ) // Up
{
mPlayer.Position.y -= moveRateY;
++count;
}
if ( mInput.IsKeyDown( sf::Key::S ) ) // Down
{
mPlayer.Position.y += moveRateY;
++count;
}
if ( mInput.IsKeyDown( sf::Key::A ) ) // Left
{
mPlayer.Position.x -= moveRateX;
++count;
}
if ( mInput.IsKeyDown( sf::Key::D ) ) // Right
{
mPlayer.Position.x += moveRateX;
++count;
}
std::cout << "Key Press Rate => " << count << " seconds" << std::endl;
}
void Game::OnMouseEvent( void )
{
mPlayer.GetShape().Rotate( mMouseAoR + 5 );
}
void Game::Update( void )
{
const int x = mInput.GetMouseX();
const int y = mInput.GetMouseY();
mMouseAoR = ( y == 0 ) ? 0
: tanf( x / y );
PrintInfo();
}