Я пытаюсь заставить свое движение шара просто двигаться в жидкости, как движение. Как получить, чтобы при нажатии клавиши «вверх», «вниз», «влево» или «вправо» он не двигался вверх на одну единицу, не останавливался и не продолжал двигаться. Кроме того, как я могу заставить его двигаться в двух направлениях одновременно, не останавливая другое направление при отпускании ключа?
Спасибо
if(GetAsyncKeyState(VK_UP))
{
if(g_nGameState == SETTINGUPSHOT_GAMESTATE || g_nGameState == INITIAL_GAMESTATE)
{
g_cObjectWorld.AdjustCueBallY(MOVEDELTA);
g_cObjectWorld.ResetImpulseVector();
}
}
if(GetAsyncKeyState(VK_DOWN))
{
if(g_nGameState == SETTINGUPSHOT_GAMESTATE || g_nGameState == INITIAL_GAMESTATE)
{
g_cObjectWorld.AdjustCueBallY(-MOVEDELTA);
g_cObjectWorld.ResetImpulseVector();
}
}
if(GetAsyncKeyState(VK_LEFT))
{
if(g_nGameState == SETTINGUPSHOT_GAMESTATE || g_nGameState == INITIAL_GAMESTATE)
{
g_cObjectWorld.AdjustCueBallX(-MOVEDELTA);
g_cObjectWorld.ResetImpulseVector();
}
}
if(GetAsyncKeyState(VK_RIGHT))
{
if(g_nGameState == SETTINGUPSHOT_GAMESTATE || g_nGameState == INITIAL_GAMESTATE)
{
g_cObjectWorld.AdjustCueBallX(MOVEDELTA);
g_cObjectWorld.ResetImpulseVector();
}
}
Вы можете сделать что-то вроде этого:
Используйте SetTimer, чтобы создать таймер на вашем оконном цикле событий с интервалом в 10 мс, который будет хорошим для того, чего вы хотите Причина, по которой это должно быть в оконном потоке, заключается в том, что GetAsyncKeyState не даст желаемых результатов при вызове из другого потока.
Мы используем таймер, так как вызов GetAsyncKeyState должен быть в другом сообщении, чем события обработки ключа, поэтому ключ все еще находится в очереди.
В функции таймера вы можете сделать что-то вроде этого
int deltaX = 0, deltaY = 0;
unsigned int downDown = GetAsyncKeyState(VK_DOWN);
unsigned int upDown = GetAsyncKeyState(VK_UP);
unsigned int leftDown = GetAsyncKeyState(VK_LEFT);
unsigned int rightDown = GetAsyncKeyState(VK_RIGHT);
if(downDown & 0x00008000)deltaY -= MOVEDELTA;
if(upDown & 0x00008000)deltaY += MOVEDELTA;
if(leftDown & 0x00008000)deltaX -= MOVEDELTA;
if(rightDown & 0x00008000)deltaX += MOVEDELTA;
g_cObjectWorld.AdjustCueBallX(deltaX);
g_cObjectWorld.AdjustCueBallY(deltaY);
g_cObjectWorld.ResetImpulseVector();
Таким образом, вы также можете убедиться, что движение останавливается при включении (deltaX == 0 && deltaY == 0)
Я не уверен, какова семантика AdjustCueBall (X | Y), но если вы убедитесь, что они перестают двигаться в этом направлении, когда они получают 0, все должно работать нормально.
Также вы должны заметить, что ваша клавиатура должна поддерживать аппаратное нажатие нескольких клавиш, чтобы вы могли перемещаться по диагонали с помощью двух клавиш. Если это произойдет, решение, приведенное выше, будет работать, если этого не произойдет, вы все равно сможете перемещаться в любой из них. из четырех основных направлений.
Один дизайн состоит в том, чтобы использовать клавиатуру только для изменения направления.
Пусть мяч продолжает двигаться в своем текущем направлении, пока не будет получено нажатие клавиши, которое изменит его направление. Это уменьшает нагрузку на процессор от непрерывного прерывания нажатиями клавиш.
Что касается движения в неортогональных направлениях, используйте больше ключей. Посмотрите на «клавиатуру». Некоторые клавиши расположены по диагонали от клавиш «5». Используйте те.