Answer the question
In order to leave comments, you need to log in
Why does the program freeze for half a second when two keys are pressed at the same time?
I am trying to write a simple tennis game.
If you press the A / Z, OEM_2 / OEM_7 keys, you can move the first and second paddle up and down, respectively.
The problem is that if I hold down one key and press another, then there is a slight delay. Let me explain with an example.
Let's say I move my left paddle up. At some point, I press a button that moves the right paddle down. In this case, everything stops for half a second and then continues as it should. How to get rid of this half second delay?
#include <windows.h>
const double PI = 3.141592653;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
char szClassName[] = "CG_WAPI_Template";
/////////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmd
{
HWND hWnd;
MSG lpMsg;
WNDCLASS wc;
// Заполняем структуру класса окна
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = (LPCWSTR)szClassName;
// Регистрируем класс окна
if (!RegisterClass(&wc))
{
MessageBox(NULL, (LPCWSTR)"Не могу зарегистрировать класс окна!", (LPCWSTR)"Ошибка", MB_O
return 0;
}
// Создаем основное окно приложения
hWnd = CreateWindow(
(LPCWSTR)szClassName, // Имя класса
L"Шаблон WinAPI приложения", // Текст заголовка
WS_OVERLAPPEDWINDOW, // Стиль окна
50, 50, // Позиция левого верхнего угла
600, 600, // Ширина и высота окна
(HWND) NULL, // Указатель на родительское окно NULL
(HMENU) NULL, // Используется меню класса окна
(HINSTANCE)hInstance, // Указатель на текущее приложение
NULL ); // Передается в качестве lParam в событие WM_CREATE
if (!hWnd)
{
MessageBox(NULL, (LPCWSTR)"Не удается создать главное окно!", (LPCWSTR)"Ошибка", MB_OK);
return 0;
}
// Показываем наше окно
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Выполняем цикл обработки сообщений до закрытия приложения
while (GetMessage(&lpMsg, NULL, 0, 0))
{
TranslateMessage(&lpMsg);
DispatchMessage(&lpMsg);
}
return (lpMsg.wParam);
}
/////////////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT Rect;
Директива препроцессора #include <windows.h> открывает доступ к тысячам описаний констант,
структур, типов данных и функций Windows.
WinAPI приложение является в своей основе процедурным приложением и содержит два основных
модуля – функции WinMain и WndProc.
HDC hdc, hCmpDC;
HBITMAP hBmp;
switch (messg)
{
case WM_PAINT:
GetClientRect(hWnd, &Rect);
hdc = BeginPaint(hWnd, &ps);
// Создание теневого контекста для двойной буферизации
hCmpDC = CreateCompatibleDC(hdc);
hBmp = CreateCompatibleBitmap(hdc, Rect.right - Rect.left,
Rect.bottom - Rect.top);
SelectObject(hCmpDC, hBmp);
// Закраска фоновым цветом
LOGBRUSH br;
br.lbStyle = BS_SOLID;
br.lbColor = 0xEECCCC;
HBRUSH brush;
brush = CreateBrushIndirect(&br);
FillRect(hCmpDC, &Rect, brush);
DeleteObject(brush);
// Здесь рисуем на контексте hCmpDC
// Копируем изображение из теневого контекста на экран
SetStretchBltMode(hdc, COLORONCOLOR);
BitBlt(hdc, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top,
hCmpDC, 0, 0, SRCCOPY);
// Удаляем ненужные системные объекты
DeleteDC(hCmpDC);
DeleteObject(hBmp);
hCmpDC = NULL;
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
speed=10;
if (GetAsyncKeyState(0x41)){
pos1+=speed;
if (pos1>320){
pos1=320;
}
}
if (GetAsyncKeyState(0x5A)){
pos1-=speed;
if (pos1<0){
pos1=0;
}
}
if (GetAsyncKeyState(VK_OEM_7)){
pos2+=speed;
if (pos2>320){
pos2=320;
}
}
if (GetAsyncKeyState(VK_OEM_2)){
pos2-=speed;
if (pos2<0){
pos2=0;
}
}
InvalidateRect(hWnd,0,false);
UpdateWindow(hWnd);
break;
default:
return (DefWindowProc(hWnd, messg, wParam, lParam));
}
Answer the question
In order to leave comments, you need to log in
Found a solution to the problem. The bottom line is that in the WM_KEYDOWN block, set the values of the boolean variables is1up_pressed, is1down_pressed, is2up_pressed, is2down_pressed, each of which is responsible for its own button. I also added a WM_KEYUP block where I check if the keys are released.
I change the position of the racket on a timer 25 times per second
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question