Code:
#include <windows.h>
#include <math.h>
#include <iostream.h>
#define PI 3.14159265358979323846
int map[10][10] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
CONST int PlayerHeight = 32;
CONST int WallHeight = 64;
CONST double DegreeChange = 60.0/320.0;
CONST int DistanceToProjection = 277;
int PlayerAngle = 45;
double Distance(double, double, double);
HWND hWnd;
const char ClsName[] = "Ray-Casting Test";
const char WindowCaption[] = "Ray-Casting Test";
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
WNDCLASSEX WndClsEx;
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = NULL;
WndClsEx.cbWndExtra = NULL;
WndClsEx.hInstance = hInstance;
WndClsEx.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
RegisterClassEx(&WndClsEx);
hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
ClsName,
WindowCaption,
WS_OVERLAPPEDWINDOW,
100,
120,
320,
200,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT Ps;
COLORREF Red = RGB(255, 0, 0);
COLORREF Green = RGB(0, 255, 0);
COLORREF Blue = RGB(0 ,0, 255);
HPEN RedPen = CreatePen(PS_SOLID, 0, Red);
HPEN GreenPen = CreatePen(PS_SOLID, 0, Green);
HPEN BluePen = CreatePen(PS_SOLID, 0, Blue);
double y = -30;
double distance;
double degrees;
double height;
int top;
int bottom;
switch(Msg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &Ps);
for (int i = 0; i <= 320; i++) {
distance = Distance(PlayerAngle + y, 256, 256);
distance = distance * cos(y*PI/180);
degrees = atan(32.0/distance) / PI * 180;
height = tan(degrees*PI/180) * DistanceToProjection;
SelectObject(hDC, BluePen);
MoveToEx(hDC, i, 100 + height, NULL);
LineTo(hDC, i, 100 - height);
SelectObject(hDC, RedPen);
MoveToEx(hDC, i, 100 - height, NULL);
LineTo(hDC, i, 0);
y = y + DegreeChange;
}
EndPaint(hWnd, &Ps);
break;
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
case WM_KEYDOWN:
if (wParam == VK_LEFT) {
PlayerAngle = PlayerAngle - 5;
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
}
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
double Distance(double Angle, double PlayerX, double PlayerY) {
double DistanceChange = 1;
double Distance = 0;
double X = PlayerX;
double Y = PlayerY;
int i = 0;
int XCord;
int YCord;
double XChange = cos(Angle*PI/180) * 1;
double YChange = sin(Angle*PI/180) * 1;
while (i == 0) {
Distance = Distance + DistanceChange;
X = X + XChange;
Y = Y - YChange;
XCord = floor(X/64);
YCord = floor(Y/64);
if (map[XCord][YCord] == 1)
i = 1;
}
return Distance;
}
Distance is a function that traces a ray to a wall and returns the distance.