I am trying to multi-thread my game so that one thread updates and renders the player, while the other listens for inputs. I used a while loop to keep my detached thread running in the background, which is working, but my player isn't moving even though the code tells it to do exactly that. If I put MessageBox(NULL, "Testing", "Alert", NULL)
in Player::update or Player::draw in Player.cpp, the window spams message boxes, which means the code IS running, but the player is NOT moving. Is it a problem with one of the Player functions or with the thread itself?
Window.cpp
#include <windows.h>
void quit();
void setup(HDC, PAINTSTRUCT, HWND);
const char g_szClassName[] = "myWindowClass";
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
quit();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hwnd, &ps);
setup(hdc, ps, hwnd);
EndPaint(hwnd, &ps);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Testing!!!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Main.cpp
#include <iostream>
#include <thread>
#include <windows.h>
#include "Functions.h"
#include "Player.h"
using namespace std;
void draw(HDC);
void startThreads();
void checkForInput();
bool Quit = false;
HDC hdc;
PAINTSTRUCT ps;
HWND hwnd;
Player player(50, 50);
void setup(HDC hDC, PAINTSTRUCT pS, HWND hWND)
{
hdc = hDC;
ps = pS;
hwnd = hWND;
startThreads();
}
void checkForInput()
{
while (!Quit)
{
if (GetKeyState(27) & 0x8000)
{
Quit = true;
}
}
}
void quit()
{
Quit = true;
}
void draw(HDC hdc)
{
while (!Quit)
{
player.draw(hdc);
player.update();
Sleep(16);
}
}
void startThreads()
{
thread mm(draw, hdc);
thread input(checkForInput);
input.detach();
mm.detach();
}
Player.cpp
#include <windows.h>
#include "Player.h"
#include "Functions.h"
Player::Player(int xx, int yy)
{
x = xx;
y = yy;
}
void Player::update()
{
x++;
}
void Player::draw(HDC hdc)
{
rect(hdc, x, y, 50, 50);
}
Player.h
#pragma once
#include <Windows.h>
struct Player {
public:
int x;
int y;
Player(int, int);
void update();
void draw(HDC hdc);
};
Functions.cpp
#include "Functions.h"
void rect(HDC hdc, int x, int y, int w, int h)
{
Rectangle(hdc, x, y, x + w, y + h);
}
void ellipse(HDC hdc, int x, int y, int w, int h)
{
Ellipse(hdc, x, y, x + w, y + h);
}
Functions.h
#pragma once
#include <windows.h>
void rect(HDC, int, int, int, int);
void ellipse(HDC, int, int, int, int);