Code:
#include <windows.h>
#include <stdio.h>
#define CLASS_NAME "Tenis"
// Global variables
int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
COORD P1Pos = {0, 0};
COORD P2Pos = {0, 0};
bool EnemyMove = true;
// Functions Protypes
void DrawPaddle(HDC _hdc, COORD Pos, HDC hdcRacket);
void MoveBall(COORD &BP, COORD &BA, int &speed);
void DrawBall(HDC _hdc, COORD BP, HDC hdcBall);
void KeyboardInput();
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
RECT WindowRect = { 0, 0, ScreenWidth, ScreenHeight };
HDC hdc;
// Court bmp
HBITMAP hbitCourt;
HDC hdcCourt;
HBITMAP hbitOld_Court;
// Racket p1 bmp
HBITMAP hbitRacketP1;
HDC hdcRacketP1;
HBITMAP hbitOld_RacketP1;
// Racket p2 bmp
HBITMAP hbitRacketP2;
HDC hdcRacketP2;
HBITMAP hbitOld_RacketP2;
// Ball bmp
HBITMAP hbitBall;
HDC hdcBall;
HBITMAP hbitOld_Ball;
// Others
COORD BallPos = {0, 0};
COORD BallAngle = {0, 0};
int Speed = 5;
int P1Score = 0;
int P2Score = 0;
char cP1Score[256];
char cP2Score[256];
wndclass.cbSize = sizeof (wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = CLASS_NAME;
wndclass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
RegisterClassEx(&wndclass);
hwnd = CreateWindow(CLASS_NAME,
"MDMA(c) 2004",
WS_OVERLAPPEDWINDOW,
0, 0,
ScreenWidth, ScreenHeight,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
srand(GetTickCount());
// Init
hdc = GetWindowDC(hwnd);
// Court bmp
hbitCourt = (HBITMAP)LoadImage(hInstance, "Court.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
hdcCourt = CreateCompatibleDC(hdc);
hbitOld_Court = (HBITMAP)SelectObject(hdcCourt, hbitCourt);
// Racket p1 bmp
hbitRacketP1 = (HBITMAP)LoadImage(hInstance, "RacketP1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
hdcRacketP1 = CreateCompatibleDC(hdc);
hbitOld_RacketP1 = (HBITMAP)SelectObject(hdcRacketP1, hbitRacketP1);
// Racket p2 bmp
hbitRacketP2 = (HBITMAP)LoadImage(hInstance, "RacketP2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
hdcRacketP2 = CreateCompatibleDC(hdc);
hbitOld_RacketP2 = (HBITMAP)SelectObject(hdcRacketP2, hbitRacketP2);
// Ball bmp
hbitBall = (HBITMAP)LoadImage(hInstance, "Ball.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
hdcBall = CreateCompatibleDC(hdc);
hbitOld_Ball = (HBITMAP)SelectObject(hdcBall, hbitBall);
BallPos.X = ScreenWidth / 2;
BallPos.Y = ScreenHeight / 2;
BallAngle.X = ((rand() % 2) ? 2 : -2);
BallAngle.Y = ((rand() % 2) ? 1 : -1);
P1Pos.Y = ScreenHeight / 2;
P1Pos.X = 4;
P2Pos.Y = ScreenHeight / 2;
P2Pos.X = ScreenWidth - 10;
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
KeyboardInput(); // <---- Here?
} else {
// Scores
sprintf(cP1Score, "%d", P1Score);
sprintf(cP2Score, "%d", P2Score);
TextOut(hdc, 5, 5, cP1Score, strlen(cP1Score));
TextOut(hdc, ScreenWidth - 12, 5, cP2Score, strlen(cP2Score));
DrawPaddle(hdc, P1Pos, hdcRacketP1);
DrawPaddle(hdc, P2Pos, hdcRacketP2);
DrawBall(hdc, BallPos, hdcBall);
MoveBall(BallPos, BallAngle, Speed);
// Move enemy paddle
if (EnemyMove)
{
if (BallPos.Y > P2Pos.Y)
P2Pos.Y += 10 + (P1Score - P2Score);
if (BallPos.Y < P2Pos.Y)
P2Pos.Y -= 10 - (P1Score - P2Score);
}
// Check for loss
if (BallPos.X < -50)
{
BallPos.X = ScreenWidth / 2;
BallPos.Y = ScreenHeight / 2;
P2Score++;
Speed = 5;
if (P2Score > 5)
{
MessageBox(hwnd, "YOU LOSE!", "HAHAHA!", MB_OK);
break;
}
}
// Check for win
if (BallPos.X > ScreenWidth + 50)
{
BallPos.X = ScreenWidth / 2;
BallPos.Y = ScreenHeight / 2;
P1Score++;
Speed = 5;
if (P1Score > 5)
{
MessageBox(hwnd, "YOU WIN!", "w00t", MB_OK);
break;
}
}
Sleep(50);
// Redraw screen
BitBlt(hdc, 0, 0, 1024, 748, hdcCourt, 0, 0, SRCCOPY);
}
}
//DeInit
// Court bmp
SelectObject(hdcCourt, hbitOld_Court);
DeleteObject(hbitCourt);
DeleteDC(hdcCourt);
// Racket p1 bmp
SelectObject(hdcRacketP1, hbitOld_RacketP1);
DeleteObject(hbitRacketP1);
DeleteDC(hdcRacketP1);
// Racket p2 bmp
SelectObject(hdcRacketP2, hbitOld_RacketP2);
DeleteObject(hbitRacketP2);
DeleteDC(hdcRacketP2);
// Ball bmp
SelectObject(hdcBall, hbitOld_Ball);
DeleteObject(hbitBall);
DeleteDC(hdcBall);
ReleaseDC(hwnd, hdc);
UnregisterClass(CLASS_NAME, hInstance);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch (iMsg)
{
case WM_PAINT:
BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
case WM_KEYDOWN:
switch (wParam)
{
/*case VK_UP:
if (P1Pos.Y > 20)
P1Pos.Y -= 16;
break;
case VK_DOWN:
if (P1Pos.Y < ScreenHeight - 50)
P1Pos.Y += 16;
break;*/
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
// Functions Definitions
void DrawPaddle(HDC _hdc, COORD Pos, HDC hdcRacket)
{
BitBlt(_hdc, Pos.X, Pos.Y - 20, 10, 40, hdcRacket, 0, 0, SRCCOPY);
}
void MoveBall(COORD &BP, COORD &BA, int &speed)
{
BP.X += BA.X * speed;
BP.Y += BA.Y * speed;
if (BP.Y < 160)
{
BA.Y *= -1;
}
if (BP.Y >= ScreenHeight - 20 - 170)
{
BA.Y *= -1;
}
if (BP.X < 5 && BP.Y > (P1Pos.Y - 27) && BP.Y < (P1Pos.Y + 27))
{
EnemyMove = true;
BA.X *= -1;
}
if (BP.X >= (ScreenWidth - 5) && BP.Y > (P2Pos.Y - 27) && BP.Y < (P2Pos.Y + 27))
{
EnemyMove = false;
BA.X *= -1;
speed++;
}
}
void DrawBall(HDC _hdc, COORD BP, HDC hdcBall)
{
BitBlt(_hdc, BP.X - 7, BP.Y - 7, 14, 14, hdcBall, 0, 0, SRCCOPY);
}
void KeyboardInput()
{
if (GetKeyState(VK_UP) & 0x80)
P1Pos.Y -= 16;
if (GetKeyState(VK_DOWN) & 0x80)
P1Pos.Y += 16;
}