Thread: Help! My Ray-Casting Engine keeps freezing!

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    27

    Help! My Ray-Casting Engine keeps freezing!

    Code:
    #include <windows.h>
    #include <math.h>
    #include <fstream.h>
    
    #pragma resource "icon.res"
    
    #define ID_TEXTURE 1000
    #define ID_ICON 100
    #define PI 3.14159265358979323846
    
    CONST float SizeMult = 1.7;
    CONST double DegreeChange = 60.0/(320.0 * SizeMult);
    CONST int DistanceToProjection = 277;
    CONST int MoveSpeed = 30;
    CONST int LagMult = 10;
    CONST int MouseSensitivity = 2;
    
    HDC bufferDC;
    HDC Image;
    HDC hDC;
    
    HINSTANCE DLL = LoadLibrary("Images");
    
    HBITMAP Texture = (HBITMAP)LoadBitmap(DLL, MAKEINTRESOURCE(ID_TEXTURE));
    HBITMAP Buffer;
    
    HPEN BluePen = CreatePen(PS_SOLID, 0, RGB(0 ,0, 255));
    HPEN GrayPen = CreatePen(PS_SOLID, 0, RGB(117, 117, 117));
    
    UINT Timer;
    
    HDC hdc;
    
    PAINTSTRUCT Ps;
    
    double y = -30;
    double PlayerVerticalAngle = 0;
    double PlayerX = 256.0;
    double PlayerY = 256.0;
    double distance1;
    double degrees;
    double height;
    
    int WindowsStatus = 1;
    int PlayerAngle = 45;
    int BitmapColumn;
    int MidPoint;
    int temp1;
    int temp2;
    
    POINT NewMouse;
    POINT OldMouse;
    POINT Center;
    
    int map[100][100];
    
    double Distance(double, double, double, int *, int *);
    void LoadMap(char *);
    
    HWND hWnd;
    const char ClsName[] = "Ray-Casting Test";
    const char WindowCaption[] = "3d World - Made by EDITED";
    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, MAKEINTRESOURCE(ID_ICON));
        WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
        WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        WndClsEx.lpszMenuName  = NULL;
        WndClsEx.lpszClassName = ClsName;
        WndClsEx.hIconSm       = LoadIcon(hInstance, MAKEINTRESOURCE(ID_ICON));
    
        RegisterClassEx(&WndClsEx);
    
        hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                              ClsName,
                              WindowCaption,
                              WS_OVERLAPPEDWINDOW,
                              100,
                              120,
                              320 * SizeMult,
                              200 * SizeMult,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);
    
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
    
        FreeLibrary(DLL);
    
        while( GetMessage(&Msg, NULL, 0, 0) )
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
    
        return Msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	if (WindowsStatus == 1) {
    		switch (Msg)
    		{
    
    		case WM_CREATE:
    			{
    				bufferDC = CreateCompatibleDC(GetDC(hWnd));
    				Buffer = CreateCompatibleBitmap(GetDC(hWnd), 320 * SizeMult, 200 * SizeMult);
    				SelectObject(bufferDC, Buffer);
    				DeleteObject(Buffer);
    
    				Image = CreateCompatibleDC(GetDC(hWnd));
    
    				Timer = SetTimer(hWnd, 105, 10, TIMERPROC(NULL));
    
    				GetCursorPos(&OldMouse);
    				Center.x = 160 * SizeMult;
    				Center.y = 160 * SizeMult;
    				ClientToScreen(hWnd, &Center);
    				ShowCursor(0);
    
    				LoadMap("map.txt");
    				return 0;
    			}
    
    		case WM_PAINT:
    			{
    				hDC = BeginPaint(hWnd, &Ps);
    
    				y = -30;
    			    	for (int i = 0; i <= (320 * SizeMult); i++) {
        					distance1 = Distance(PlayerAngle + y, PlayerX, PlayerY, &BitmapColumn, &MidPoint);
      					distance1 = distance1 * cos(y*PI/180);
        					degrees = atan(64.0/distance1) / PI * 180;
        					height = tan(degrees*PI/180) * DistanceToProjection;
        					SelectObject(bufferDC, GrayPen);
        					MoveToEx(bufferDC, i, 0, NULL);
        					LineTo(bufferDC, i, MidPoint - height);
    					SelectObject(Image, Texture);
    					StretchBlt(bufferDC, i, MidPoint - height, 1, height * 2, Image, BitmapColumn - 1, 0, 1, 64, SRCCOPY);
    					SelectObject(bufferDC, BluePen);
    					MoveToEx(bufferDC, i, MidPoint + height, NULL);
        					LineTo(bufferDC, i, (200 * SizeMult));
        					y = y + DegreeChange;
    				}
    
    				BitBlt( hDC, 0, 0, 320 * SizeMult, 200 * SizeMult, bufferDC, 0, 0, SRCCOPY );
    				break;
    			}
    
    		case WM_TIMER:
    			{
    
    			GetCursorPos(&NewMouse);
    			int i = 0;
    
    			if (OldMouse.y > NewMouse.y) {
    					if (PlayerVerticalAngle <= 19) {
    						PlayerVerticalAngle = PlayerVerticalAngle + (OldMouse.y - NewMouse.y)/MouseSensitivity;
    						i = 1;
    					}
    			}
    			else if (OldMouse.y < NewMouse.y) {
    				if (PlayerVerticalAngle >= -19) {
    						PlayerVerticalAngle = PlayerVerticalAngle - (NewMouse.y - OldMouse.y)/MouseSensitivity;
    						i = 1;
    				}
    			}
    
    			if (OldMouse.x > NewMouse.x) {
         				PlayerAngle = PlayerAngle - (OldMouse.x - NewMouse.x)/MouseSensitivity;
    				if (PlayerAngle < 0)
    					PlayerAngle = PlayerAngle + 360;
    				i = 1;
    			}
    			else if (OldMouse.x < NewMouse.x) {
         				PlayerAngle = PlayerAngle + (NewMouse.x - OldMouse.x)/MouseSensitivity;
    				if (PlayerAngle > 360)
    					PlayerAngle = PlayerAngle - 360;
    				i = 1;
    			}
    
    			if((GetAsyncKeyState(87)) || (GetAsyncKeyState(VK_UP))) {
    				int a = 0;
    				double X;
    				double Y;
    				for (int y = 1; y <= MoveSpeed; y++) {
    					X = PlayerX + cos(PlayerAngle*PI/180) * y;
    					Y = PlayerY - sin(PlayerAngle*PI/180) * y;
    					temp1 = floor(X/64);
    					temp2 = floor(Y/64);
    					if (map[temp1][temp2] == 1)
    						a = 1;	
    				}
    				if (a != 1) {
    					PlayerX = X;
    					PlayerY = Y;
    					i = 1;
    				}
    			}
    
    			if ((GetAsyncKeyState(83)) || (GetAsyncKeyState(VK_DOWN))) {
    				int a = 0;
    				double X;
    				double Y;
    				for (int y = 1; y <= MoveSpeed; y++) {
    					X = PlayerX - cos(PlayerAngle*PI/180) * y;
    					Y = PlayerY + sin(PlayerAngle*PI/180) * y;
    					temp1 = floor(X/64);
    					temp2 = floor(Y/64);
    					if (map[temp1][temp2] == 1) {
    						a = 1;
    						y = MoveSpeed + 1;
    					}
    			
    				}
    				if (a != 1) {
    					PlayerX = X;
    					PlayerY = Y;
    					i = 1;
    				}
    			}
    
    			if (GetAsyncKeyState(65)) {
    				int a = 0;
    				double X;
    				double Y;
    				for (int y = 1; y <= MoveSpeed - 5; y++) {
    					X = PlayerX - cos((PlayerAngle + 90)*PI/180) * y;
    					Y = PlayerY + sin((PlayerAngle + 90)*PI/180) * y;
    					temp1 = floor(X/64);
    					temp2 = floor(Y/64);
    					if (map[temp1][temp2] == 1) {
    						a = 1;
    						y = MoveSpeed + 1;
    					}
    				}
    				if (a != 1) {
    					PlayerX = X;
    					PlayerY = Y;
    					i = 1;
    				}
    			}
    
    
    			if (GetAsyncKeyState(68)) {
    				int a = 0;
    				double X;
    				double Y;
    				for (int y = 1; y <= MoveSpeed - 5; y++) {
    					X = PlayerX + cos((PlayerAngle + 90)*PI/180) * y;
    					Y = PlayerY - sin((PlayerAngle + 90)*PI/180) * y;
    					temp1 = floor(X/64);
    					temp2 = floor(Y/64);
    					if (map[temp1][temp2] == 1) {
    						a = 1;
    						y = MoveSpeed + 1;
    					}
    				}
    				if (a != 1) {
    					PlayerX = X;
    					PlayerY = Y;
    					i = 1;
    				}
    			}
    
    			if (i == 1) {
    				i = 0;
    				InvalidateRect(hWnd, 0, 0);
    				UpdateWindow(hWnd);
    			}
    
    			if ((NewMouse.x <= 1) || (NewMouse.x >= Center.x + 300)) {
    				SetCursorPos(Center.x, Center.y);
    				NewMouse.x = Center.x;
    				NewMouse.y = Center.y;
    			}
    
    			OldMouse.x = NewMouse.x;
    			OldMouse.y = NewMouse.y;
    
    			break;
    			}
    
    		case WM_DESTROY:
    			{
    				ShowCursor(1);
    				DeleteObject(BluePen);
    				DeleteObject(GrayPen);
    				DeleteDC(Image);
    				DeleteDC(bufferDC);
    				ReleaseDC(hWnd, hDC);
    				PostQuitMessage(WM_QUIT);
    			}
    
    		default:
    			return DefWindowProc(hWnd, Msg, wParam, lParam);
    		}
    	}
    }
    
    double Distance(double Angle, double PlayerX, double PlayerY, int *Bitmap, int *MidPoint) {
    	double DistanceChange = 1;
    	double Distance = 0;
    	double X = PlayerX;
    	double Y = PlayerY;
    	int i = 0;
    	int mode = 0;
    	int XCord;
    	int YCord;
    	double XChange = cos(Angle*PI/180) * 1;
    	double YChange = sin(Angle*PI/180) * 1;
    
    	while (i == 0) {
    		if (mode == 0) {
    			Distance = Distance + (DistanceChange * LagMult);
    			X = X + (XChange * LagMult);
    			Y = Y - (YChange * LagMult);
    		} else {
    			Distance = Distance + DistanceChange;
    			X = X + XChange;
    			Y = Y - YChange;
    		}
    
    		XCord = floor(X/64);
    		YCord = floor(Y/64);
    
    		if (map[XCord][YCord] == 1)
    			if (mode == 0) {
    				Distance = (Distance - DistanceChange * LagMult);
    				X = X - (XChange * LagMult);
    				Y = Y + (YChange * LagMult);
    				mode = 1;
    			} else
    			i = 1;
    	
    	}
    
    	if (PlayerX > X)
    		X = ceil(X);
    	else 
    		X = floor(X);
    
    	if (PlayerY > Y)
    		Y = ceil(Y);
    	else 
    		Y = floor(Y);
    
    	if (floor(X/64) == X/64) {
    		while (Y > 64)
    			Y = Y - 64;
    		*Bitmap = Y;
    	}
    
    	
    	if (floor(Y/64) == Y/64) {
    		while (X > 64)
    			X = X - 64;
    		*Bitmap = X;
    	}
    
    	if (PlayerVerticalAngle == 0)
    		*MidPoint = (100 * SizeMult);
    	else if (PlayerVerticalAngle > 0)
    		*MidPoint = (100 * SizeMult) + (tan(PlayerVerticalAngle*PI/180) * 277);
    	else if (PlayerVerticalAngle < 0)
    		*MidPoint = (100 * SizeMult) + (tan(PlayerVerticalAngle*PI/180) * 277);
    
    	return Distance;
    }
    
    void LoadMap(char *filename) {
    
    	char mapholder[100][100];
    
    	ifstream input_file(filename);
    
    	for (int i = 0; i <= 19; i++) {
    		input_file.getline(mapholder[i], sizeof(map[i]));
    	}
    
    	for (int i = 0; i <= 19; i++) {
    		for (int y = 0; y <= 19; y++) {
    			switch (mapholder[i][y]) {
    				case '1':
    						map[i][y] = 1;
    						break;
    				case '0':
    						map[i][y] = 0;
    						break;
    			}
    		}
    	}
    
    	input_file.close();
    }
    As you can see, this is a Ray-Casting engine that loads a map of 0s and 1s from a text file. However, if ANY spot past 20x20 map units is visible to the player, the engine freezes. Any help?

  2. #2
    Registered User
    Join Date
    Mar 2004
    Posts
    27
    Note:
    for (int i = 0; i <= 19; i++)

    should be i <= 99

  3. #3
    Registered User
    Join Date
    Mar 2004
    Posts
    27
    Nevermind, problem fixed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help designing a recursive function.
    By broli86 in forum C Programming
    Replies: 3
    Last Post: 07-24-2008, 12:45 PM
  2. Game Engine Link Prob
    By swgh in forum Game Programming
    Replies: 2
    Last Post: 01-26-2006, 12:14 AM
  3. ray casting
    By lambs4 in forum Game Programming
    Replies: 62
    Last Post: 01-09-2003, 06:57 PM
  4. What's a 3D engine?
    By Garfield in forum Game Programming
    Replies: 6
    Last Post: 12-18-2001, 04:06 PM