Advertisement
alien_fx_fiend

2D-Racing-App Improved, Big Chunk O' Mess!

Apr 19th, 2025
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 39.66 KB | Source Code | 0 0
  1. ==++ Here's the full source for (file 1/1) "RaceCar.cpp"::: ++==
  2. ```RaceCar.cpp
  3. #include <Windows.h>
  4. #include <ctime>
  5. #include <cstdlib>
  6. #include <math.h>
  7. #include <stdio.h>
  8. #include <string>
  9. #include "resource.h"  // Add this with your other includes
  10.  
  11. // Global Variables
  12. const int WIDTH = 1366;
  13. const int HEIGHT = 768;
  14. const int ROAD_WIDTH = 200;
  15. const int CAR_WIDTH = 50;
  16. const int CAR_HEIGHT = 100;
  17. const int TYRE_SIZE = 10;
  18. const int FPS = 60;
  19. const int TIMER = 4;
  20. const int TURN_RADIUS = 5;
  21. const double PI = 3.14159265358979323846;
  22. const double M_PI = 3.14159265358979323846;
  23.  
  24. int playerX = 100;
  25. int playerY = HEIGHT - CAR_HEIGHT - 50;
  26. int playerSpeedX = 0;
  27. int playerSpeedY = 0;
  28. int aiX = playerX + CAR_WIDTH + 20;
  29. int aiY = playerY;
  30. float aiAngle = -PI / 2;  // Add this line
  31. int aiSpeedX = 0;
  32. int aiSpeedY = 0;
  33. int speed = 5;
  34. int aiSpeed = 5;
  35. int timer = TIMER;
  36. int playerTyre1X = playerX + 10;
  37. int playerTyre1Y = playerY + CAR_HEIGHT - TYRE_SIZE;
  38. int playerTyre2X = playerX + CAR_WIDTH - TYRE_SIZE - 10;
  39. int playerTyre2Y = playerY + CAR_HEIGHT - TYRE_SIZE;
  40. int aiTyre1X = aiX + 10;
  41. int aiTyre1Y = aiY + CAR_HEIGHT - TYRE_SIZE;
  42. int aiTyre2X = aiX + CAR_WIDTH - TYRE_SIZE - 10;
  43. int aiTyre2Y = aiY + CAR_HEIGHT - TYRE_SIZE;
  44. float playerAngle = -PI / 2;  // Initialize to face North by default
  45. //float playerAngle = 0.0f;
  46.  
  47. bool gameStarted = false;
  48. bool gameOver = false;
  49. bool playerWon = false;
  50. bool godMode = true;
  51. //int timer = 30 * 10; // 30 seconds * 10 (timer resolution)
  52.  
  53. // Window Procedure
  54. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  55. {
  56.    switch (message)
  57.    {
  58.    case WM_CREATE:
  59.        SetTimer(hWnd, 1, 1000 / FPS, NULL);
  60.        break;
  61.    case WM_TIMER:
  62.        if (timer > 0)
  63.        {
  64.            timer--;
  65.            InvalidateRect(hWnd, NULL, FALSE);
  66.        }
  67.        else if (!gameStarted)
  68.        {
  69.            gameStarted = true;
  70.            srand((unsigned int)time(0));
  71.            aiSpeed = rand() % 5 + 3;
  72.  
  73.            // Set initial positions for both cars on the lower left road, facing up
  74.            playerX = ROAD_WIDTH / 2 - CAR_WIDTH / 2;
  75.            playerY = HEIGHT - CAR_HEIGHT - 20;
  76.            //playerAngle = -PI / 2; // -90 degrees, pointing straight up
  77.            playerAngle = 0; // 0 degrees, pointing straight up (north)
  78.  
  79.            aiX = ROAD_WIDTH / 2 - CAR_WIDTH / 2;
  80.            aiY = HEIGHT - CAR_HEIGHT - 100;
  81.            //aiAngle = -PI / 2; // -90 degrees, pointing north
  82.            aiAngle = 0; // 0 degrees, pointing north
  83.        }
  84.        else if (!gameOver)
  85.        {
  86.            // Add God Mode toggle
  87.            if (GetAsyncKeyState('G') & 1) // Check if G key was just pressed
  88.            {
  89.                godMode = !godMode;
  90.            }
  91.  
  92.            // Store previous position for collision recovery
  93.            float prevPlayerX = playerX;
  94.            float prevPlayerY = playerY;
  95.            float prevPlayerAngle = playerAngle;
  96.  
  97.            // Player car controls
  98.            if (GetAsyncKeyState(VK_LEFT))
  99.            {
  100.                if (GetAsyncKeyState(VK_DOWN))
  101.                    playerAngle += 0.05f; // Reverse turning
  102.                else
  103.                    playerAngle -= 0.05f; // Forward turning
  104.            }
  105.            if (GetAsyncKeyState(VK_RIGHT))
  106.            {
  107.                if (GetAsyncKeyState(VK_DOWN))
  108.                    playerAngle -= 0.05f; // Reverse turning
  109.                else
  110.                    playerAngle += 0.05f; // Forward turning
  111.            }
  112.  
  113.            // Forward/Backward movement in the direction the car is facing
  114.            if (GetAsyncKeyState(VK_UP))
  115.            {
  116.                // Move forward in the direction of playerAngle
  117.                playerX += sin(playerAngle) * speed;
  118.                playerY -= cos(playerAngle) * speed;
  119.            }
  120.            if (GetAsyncKeyState(VK_DOWN))
  121.            {
  122.                // Move backward in the opposite direction of playerAngle
  123.                playerX -= sin(playerAngle) * speed;
  124.                playerY += cos(playerAngle) * speed;
  125.            }
  126.  
  127.            // Update player headlights position based on car angle
  128.            playerTyre1X = playerX + 10;
  129.            playerTyre1Y = playerY + 5;
  130.            playerTyre2X = playerX + CAR_WIDTH - TYRE_SIZE - 10;
  131.            playerTyre2Y = playerY + 5;
  132.  
  133.            // Road collision detection for player
  134.            bool onRoad = false;
  135.            // Vertical road
  136.            if (playerX >= 0 && playerX <= ROAD_WIDTH - CAR_WIDTH)
  137.                onRoad = true;
  138.            // Horizontal road at top (twice as tall)
  139.            if (playerY >= 0 && playerY <= (ROAD_WIDTH * 2) &&
  140.                playerX >= 0 && playerX <= WIDTH - CAR_WIDTH)
  141.                onRoad = true;
  142.  
  143.            if (!onRoad && !godMode) // Only restrict movement if god mode is off
  144.            {
  145.                // Return to previous position if off road
  146.                playerX = prevPlayerX;
  147.                playerY = prevPlayerY;
  148.                playerAngle = prevPlayerAngle;
  149.            }
  150.  
  151.            // AI car movement logic
  152.            if (aiY > ROAD_WIDTH * 2 && aiX < ROAD_WIDTH / 2)
  153.            {
  154.                aiSpeedX = 0;
  155.                aiSpeedY = -aiSpeed;
  156.                aiAngle = 0;  // Facing upward
  157.            }
  158.            else if (aiY <= ROAD_WIDTH * 2 && aiX < WIDTH - ROAD_WIDTH)
  159.            {
  160.                aiSpeedX = aiSpeed;
  161.                aiSpeedY = 0;
  162.                aiAngle = -PI / 2;  // Facing right
  163.            }
  164.            else if (aiX >= WIDTH - ROAD_WIDTH && aiY <= HEIGHT - ROAD_WIDTH)
  165.            {
  166.                aiSpeedX = 0;
  167.                aiSpeedY = aiSpeed;
  168.                aiAngle = PI;  // Facing downward
  169.            }
  170.            else if (aiX > ROAD_WIDTH && aiY >= HEIGHT - ROAD_WIDTH)
  171.            {
  172.                aiSpeedX = -aiSpeed;
  173.                aiSpeedY = 0;
  174.                aiAngle = PI / 2;  // Facing left
  175.            }
  176.  
  177.            // AI Car Movement and Headlight Update
  178.            aiX += aiSpeedX;
  179.            aiY += aiSpeedY;
  180.  
  181.            // Calculate the front of the car using its angle
  182.            float headlightDistance = CAR_HEIGHT / 2 - 10;
  183.  
  184.            // Calculate headlight positions based on the car's angle
  185.             float headlightOffsetX = cos(aiAngle) * headlightDistance;
  186.             float headlightOffsetY = sin(aiAngle) * headlightDistance;
  187.  
  188.             // Set AI headlights at the front of the car
  189.             //aiTyre1X = aiX + CAR_WIDTH / 4 + headlightOffsetX;
  190.             //aiTyre1Y = aiY + headlightOffsetY;
  191.             //aiTyre2X = aiX - CAR_WIDTH / 4 + headlightOffsetX;
  192.             //aiTyre2Y = aiY + headlightOffsetY;
  193.  
  194.             // Collision detection between player and AI cars            
  195.             // Define the corners of the player car
  196.             int playerCorner1X = playerX;
  197.             int playerCorner1Y = playerY;
  198.             int playerCorner2X = playerX + CAR_WIDTH;
  199.             int playerCorner2Y = playerY;
  200.             int playerCorner3X = playerX + CAR_WIDTH;
  201.             int playerCorner3Y = playerY + CAR_HEIGHT;
  202.             int playerCorner4X = playerX;
  203.             int playerCorner4Y = playerY + CAR_HEIGHT;
  204.  
  205.             // Define the corners of the AI car
  206.             int aiCorner1X = aiX;
  207.             int aiCorner1Y = aiY;
  208.             int aiCorner2X = aiX + CAR_WIDTH;
  209.             int aiCorner2Y = aiY;
  210.             int aiCorner3X = aiX + CAR_WIDTH;
  211.             int aiCorner3Y = aiY + CAR_HEIGHT;
  212.             int aiCorner4X = aiX;
  213.             int aiCorner4Y = aiY + CAR_HEIGHT;
  214.  
  215.             // Check if the player car is too close to the opponent car from behind
  216.             if (!godMode && playerY + CAR_HEIGHT > aiY &&
  217.                 playerY < aiY + CAR_HEIGHT &&
  218.                 playerX + CAR_WIDTH > aiX &&
  219.                 playerX < aiX + CAR_WIDTH)
  220.             {
  221.                 // Prevent the player car from moving forward
  222.                 if (GetAsyncKeyState(VK_UP))
  223.                 {
  224.                     playerX -= sin(playerAngle) * speed;
  225.                     playerY += cos(playerAngle) * speed;
  226.                 }
  227.             }
  228.  
  229.             // Check if any of the player car's corners are inside the AI car
  230.             if (!godMode && ((playerCorner1X > aiCorner1X && playerCorner1X < aiCorner3X &&
  231.                 playerCorner1Y > aiCorner1Y && playerCorner1Y < aiCorner3Y) ||
  232.                 (playerCorner2X > aiCorner1X && playerCorner2X < aiCorner3X &&
  233.                     playerCorner2Y > aiCorner1Y && playerCorner2Y < aiCorner3Y) ||
  234.                 (playerCorner3X > aiCorner1X && playerCorner3X < aiCorner3X &&
  235.                     playerCorner3Y > aiCorner1Y && playerCorner3Y < aiCorner3Y) ||
  236.                 (playerCorner4X > aiCorner1X && playerCorner4X < aiCorner3X &&
  237.                     playerCorner4Y > aiCorner1Y && playerCorner4Y < aiCorner3Y) ||
  238.                 // Check if any of the AI car's corners are inside the player car
  239.                 (aiCorner1X > playerCorner1X && aiCorner1X < playerCorner3X &&
  240.                     aiCorner1Y > playerCorner1Y && aiCorner1Y < playerCorner3Y) ||
  241.                 (aiCorner2X > playerCorner1X && aiCorner2X < playerCorner3X &&
  242.                     aiCorner2Y > playerCorner1Y && aiCorner2Y < playerCorner3Y) ||
  243.                 (aiCorner3X > playerCorner1X && aiCorner3X < playerCorner3X &&
  244.                     aiCorner3Y > playerCorner1Y && aiCorner3Y < playerCorner3Y) ||
  245.                 (aiCorner4X > playerCorner1X && aiCorner4X < playerCorner3X &&
  246.                     aiCorner4Y > playerCorner1Y && aiCorner4Y < playerCorner3Y)))
  247.             {
  248.                 // Move the player car back to prevent collision
  249.                 if (GetAsyncKeyState(VK_UP))
  250.                 {
  251.                     playerX -= sin(playerAngle) * speed;
  252.                     playerY += cos(playerAngle) * speed;
  253.                 }
  254.                 if (GetAsyncKeyState(VK_DOWN))
  255.                 {
  256.                     playerX += sin(playerAngle) * speed;
  257.                     playerY -= cos(playerAngle) * speed;
  258.                 }
  259.  
  260.                 // Move the AI car back to prevent collision
  261.                 aiX -= aiSpeedX;
  262.                 aiY -= aiSpeedY;
  263.             }
  264.  
  265.             /* Victory conditions commented out
  266.             if (playerX > WIDTH - ROAD_WIDTH - CAR_WIDTH && playerY < ROAD_WIDTH)
  267.             {
  268.                 gameOver = true;
  269.                 playerWon = true;
  270.             }
  271.             if (aiX > WIDTH - ROAD_WIDTH - CAR_WIDTH && aiY < Road_WIDTH)
  272.             {
  273.                 gameOver = true;
  274.                 playerWon = false;
  275.             }
  276.             */
  277.  
  278.             InvalidateRect(hWnd, NULL, FALSE);
  279.         }
  280.         break;
  281.     case WM_PAINT:
  282.     {
  283.         PAINTSTRUCT ps;
  284.         HDC hdc = BeginPaint(hWnd, &ps);
  285.  
  286.         // Create memory DC and bitmap for double buffering
  287.         HDC memDC = CreateCompatibleDC(hdc);
  288.         HBITMAP memBitmap = CreateCompatibleBitmap(hdc, WIDTH, HEIGHT);
  289.         HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
  290.  
  291.         // Clear background
  292.         HBRUSH lightGreenBrush = CreateSolidBrush(RGB(144, 238, 144)); // Light green color
  293.         RECT rect = { 0, 0, WIDTH, HEIGHT };
  294.         FillRect(memDC, &rect, lightGreenBrush);
  295.         DeleteObject(lightGreenBrush);
  296.  
  297.         // Draw roads (black rectangles)
  298.         HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0));
  299.         // Vertical road
  300.         RECT verticalRoad = { 0, 0, ROAD_WIDTH, HEIGHT };
  301.         FillRect(memDC, &verticalRoad, blackBrush);
  302.         // Horizontal road (twice as tall)
  303.         RECT horizontalRoad = { 0, 0, WIDTH, ROAD_WIDTH * 2 };
  304.         FillRect(memDC, &horizontalRoad, blackBrush);
  305.         DeleteObject(blackBrush);
  306.  
  307.         // Draw yellow road strips
  308.         HBRUSH yellowBrush = CreateSolidBrush(RGB(255, 255, 0));
  309.         SelectObject(memDC, yellowBrush);
  310.         // Vertical road strips
  311.         for (int y = 0; y < HEIGHT; y += 80) {
  312.             Rectangle(memDC, ROAD_WIDTH / 2 - 5, y, ROAD_WIDTH / 2 + 5, y + 40);
  313.         }
  314.         // Horizontal road strips
  315.         for (int x = 0; x < WIDTH; x += 80) {
  316.             Rectangle(memDC, x, ROAD_WIDTH - 5, x + 40, ROAD_WIDTH + 5);
  317.         }
  318.         DeleteObject(yellowBrush);
  319.  
  320.         // Drawing Player's Car and Headlights
  321.         HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
  322.         SelectObject(memDC, redBrush);
  323.         int savedDC = SaveDC(memDC);
  324.         XFORM xform;
  325.         SetGraphicsMode(memDC, GM_ADVANCED);
  326.         xform.eM11 = (FLOAT)cos(playerAngle);
  327.         xform.eM12 = (FLOAT)sin(playerAngle);
  328.         xform.eM21 = (FLOAT)-sin(playerAngle);
  329.         xform.eM22 = (FLOAT)cos(playerAngle);
  330.         xform.eDx = (FLOAT)playerX + CAR_WIDTH / 2;
  331.         xform.eDy = (FLOAT)playerY + CAR_HEIGHT / 2;
  332.         SetWorldTransform(memDC, &xform);
  333.         Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
  334.  
  335.         //headlights yellow (player)
  336.         SelectObject(memDC, CreateSolidBrush(RGB(255, 255, 0)));
  337.         Rectangle(memDC, -CAR_WIDTH / 2 + 2, -CAR_HEIGHT / 2 + 2, -CAR_WIDTH / 4, -CAR_HEIGHT / 2 + 6);
  338.         Rectangle(memDC, CAR_WIDTH / 4, -CAR_HEIGHT / 2 + 2, CAR_WIDTH / 2 - 2, -CAR_HEIGHT / 2 + 6);
  339.  
  340.         HBRUSH headlightBrush = CreateSolidBrush(RGB(255, 255, 255));
  341.         SelectObject(memDC, headlightBrush);
  342.         // Consistent headlight offset, relative to the car's dimensions
  343.         int headlightSize = 10;
  344.         int playerheadlightOffsetX = 10;
  345.         int playerheadlightOffsetY = -CAR_HEIGHT / 2 + 15;  // Adjusted vertical offset
  346.         Ellipse(memDC, -CAR_WIDTH / 2 + playerheadlightOffsetX, playerheadlightOffsetY,
  347.             -CAR_WIDTH / 2 + playerheadlightOffsetX + headlightSize, playerheadlightOffsetY + headlightSize);
  348.         Ellipse(memDC, CAR_WIDTH / 2 - playerheadlightOffsetX - headlightSize, playerheadlightOffsetY,
  349.             CAR_WIDTH / 2 - playerheadlightOffsetX, playerheadlightOffsetY + headlightSize);
  350.         DeleteObject(headlightBrush);
  351.        
  352. //start
  353.         int wsY = -CAR_HEIGHT / 2 + int(0.38f * CAR_HEIGHT);
  354.         int wsH = CAR_HEIGHT / 6;
  355.         int wsW = int(CAR_WIDTH * 0.7f);
  356.  
  357.         HBRUSH hWin = CreateSolidBrush(RGB(0, 0, 0));
  358.         SelectObject(memDC, hWin);
  359.  
  360.         Rectangle(memDC,
  361.             -wsW / 2, wsY,
  362.             wsW / 2, wsY + wsH
  363.         );
  364.  
  365. //start sidewindow
  366.         int stripW = max(2, CAR_WIDTH / 20);
  367.         int stripH = wsH * 2;
  368.  
  369.         Rectangle(memDC,
  370.             -wsW / 2 - stripW,
  371.             wsY,
  372.             -wsW / 2,
  373.             wsY + stripH
  374.         );
  375.  
  376.         Rectangle(memDC,
  377.             wsW / 2,
  378.             wsY,
  379.             wsW / 2 + stripW,
  380.             wsY + stripH
  381.         );
  382. //end sidewindow
  383.  
  384.         int sideW = CAR_WIDTH / 8;
  385.         Rectangle(memDC,
  386.             -CAR_WIDTH / 2 + 5, wsY,
  387.             -CAR_WIDTH / 2 + 5 + sideW, wsY + wsH
  388.         );
  389.         Rectangle(memDC,
  390.             CAR_WIDTH / 2 - 5 - sideW, wsY,
  391.             CAR_WIDTH / 2 - 5, wsY + wsH
  392.         );
  393.  
  394.         DeleteObject(hWin);
  395.  
  396.         HBRUSH hTy = CreateSolidBrush(RGB(0, 0, 0));
  397.         SelectObject(memDC, hTy);
  398.         int t = TYRE_SIZE;
  399.  
  400.         int fy = -CAR_HEIGHT / 2 + 5;
  401.         Rectangle(memDC, -CAR_WIDTH / 2, fy, -CAR_WIDTH / 2 + t, fy + t);
  402.         Rectangle(memDC, CAR_WIDTH / 2 - t, fy, CAR_WIDTH / 2, fy + t);
  403.  
  404.         int ry = CAR_HEIGHT / 2 - t - 5;
  405.         Rectangle(memDC, -CAR_WIDTH / 2, ry, -CAR_WIDTH / 2 + t, ry + t);
  406.         Rectangle(memDC, CAR_WIDTH / 2 - t, ry, CAR_WIDTH / 2, ry + t);
  407.  
  408.         DeleteObject(hTy);
  409.  
  410. //ends
  411.  
  412.        
  413.         RestoreDC(memDC, savedDC);
  414.         DeleteObject(redBrush);
  415.  
  416.         // Draw AI car (blue rectangle)
  417.         // AI Car Rendering
  418.         // Drawing AI's Car and Headlights
  419.                     // Draw AI car (blue rectangle)
  420.         // AI Car Rendering
  421.         // AI Car Rendering
  422.         //O3's fix working best inconsistent padded positioning tho
  423.             // Draw AI car (blue rectangle)
  424.         // ----- Draw AI Car (blue rectangle) with rotated transform -----
  425.         HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
  426.         SelectObject(memDC, blueBrush);
  427.         int savedDC2 = SaveDC(memDC);  // Save state using a unique variable name
  428.         SetGraphicsMode(memDC, GM_ADVANCED);
  429.         XFORM xform2;
  430.         xform2.eM11 = (FLOAT)cos(aiAngle);
  431.         xform2.eM12 = (FLOAT)sin(aiAngle);
  432.  
  433.  
  434.         xform2.eM21 = (FLOAT)-sin(aiAngle);
  435.         xform2.eM22 = (FLOAT)cos(aiAngle);
  436.         xform2.eDx = (FLOAT)aiX + CAR_WIDTH / 2;
  437.         xform2.eDy = (FLOAT)aiY + CAR_HEIGHT / 2;
  438.         SetWorldTransform(memDC, &xform2);
  439.         Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
  440.         RestoreDC(memDC, savedDC2);
  441.         DeleteObject(blueBrush);
  442.  
  443.         // ----- Dynamic AI Headlight Positioning -----
  444.         //
  445.         // This solution computes the AI car's nose (front) using its center (cx,cy)
  446.         // and a front vector derived from aiAngle. Note that the "front distance" is
  447.         // CAR_HEIGHT/2 when facing up/down (aiAngle == 0 or PI) and CAR_WIDTH/2 when
  448.         // facing right/left (aiAngle == -PI/2 or PI/2). We then move slightly back from
  449.         // the extreme nose by frontMargin, and offset perpendicular (by aiheadlightSeparation)
  450.         // to get the left and right headlight positions.
  451.         //
  452.         // Define parameters (adjust as needed):
  453.         float cx = aiX + CAR_WIDTH / 2.0f;
  454.         float cy = aiY + CAR_HEIGHT / 2.0f;
  455.         float frontMargin = 5.0f;            // Moves headlights slightly inward from the nose
  456.         float aiheadlightSeparation = 10.0f;   // Lateral offset from the nose for each headlight
  457.         int aiheadlightSize = 8;             // Size of the headlight circle
  458.  
  459.         // Determine the front distance depending on orientation:
  460.         float frontDistance;
  461.         if (aiAngle == 0 || aiAngle == PI)
  462.             frontDistance = CAR_HEIGHT / 2.0f;
  463.         else // aiAngle == -PI/2 or PI/2
  464.             frontDistance = CAR_WIDTH / 2.0f;
  465.  
  466.         // The default car drawing uses a local coordinate system where the car's nose is at (0, -1)
  467.         // i.e. at (0, -frontDistance). Thus the front vector (rotated) is:
  468.         float noseX = cx + (-sin(aiAngle)) * frontDistance;
  469.         float noseY = cy + (-cos(aiAngle)) * frontDistance;
  470.  
  471.         // Pull the headlight positions slightly back from the extreme nose using frontMargin:
  472.         float effectiveX = cx + (-sin(aiAngle)) * (frontDistance - frontMargin);
  473.         float effectiveY = cy + (-cos(aiAngle)) * (frontDistance - frontMargin);
  474.  
  475.         // Compute a perpendicular vector to the front. For a front vector f = (-sin(aiAngle), -cos(aiAngle)),
  476.         // a perpendicular is p = (cos(aiAngle), -sin(aiAngle)). (We use -p for the left headlight.)
  477.         float px = cos(aiAngle);
  478.         float py = -sin(aiAngle);
  479.  
  480.         // Compute left and right headlight positions by offsetting perpendicular to the front:
  481.         float leftHeadlightX = effectiveX - px * aiheadlightSeparation;
  482.         float leftHeadlightY = effectiveY - py * aiheadlightSeparation;
  483.  
  484.         float rightHeadlightX = effectiveX + px * aiheadlightSeparation;
  485.         float rightHeadlightY = effectiveY + py * aiheadlightSeparation;
  486.  
  487.         // Draw the AI headlights using the computed world coordinates:
  488.         HBRUSH aiHeadlightBrush = CreateSolidBrush(RGB(255, 255, 255));
  489.         SelectObject(memDC, aiHeadlightBrush);
  490.         Ellipse(memDC, (int)leftHeadlightX, (int)leftHeadlightY,
  491.             (int)(leftHeadlightX + aiheadlightSize), (int)(leftHeadlightY + aiheadlightSize));
  492.         Ellipse(memDC, (int)rightHeadlightX, (int)rightHeadlightY,
  493.             (int)(rightHeadlightX + aiheadlightSize), (int)(rightHeadlightY + aiheadlightSize));
  494.         DeleteObject(aiHeadlightBrush);
  495.  
  496.         //voila! It's working perfectly /w the following dynamic code!!!
  497.         // ----- Draw AI Car (blue rectangle) with rotated transform -----
  498.         { //revert to..
  499.             HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
  500.             SelectObject(memDC, blueBrush);
  501.             int savedDC2 = SaveDC(memDC);  // Save current DC state
  502.             SetGraphicsMode(memDC, GM_ADVANCED);
  503.             XFORM xform2;
  504.             xform2.eM11 = (FLOAT)cos(aiAngle);
  505.             xform2.eM12 = (FLOAT)sin(aiAngle);
  506.             xform2.eM21 = (FLOAT)-sin(aiAngle);
  507.             xform2.eM22 = (FLOAT)cos(aiAngle);
  508.             xform2.eDx = (FLOAT)aiX + CAR_WIDTH / 2;
  509.             xform2.eDy = (FLOAT)aiY + CAR_HEIGHT / 2;
  510.             SetWorldTransform(memDC, &xform2);
  511.             Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
  512.            
  513.  
  514.             /*HBRUSH hlBrush = CreateSolidBrush(RGB(255, 255, 255));
  515.             SelectObject(memDC, hlBrush);
  516.             int hlSize = 8;
  517.             int hlOffset = -CAR_HEIGHT / 2 + 5;
  518.  
  519.             Ellipse(memDC,
  520.                 -CAR_WIDTH / 4 - hlSize / 2, hlOffset,
  521.                 -CAR_WIDTH / 4 + hlSize / 2, hlOffset + hlSize
  522.             );
  523.  
  524.             Ellipse(memDC,
  525.                 +CAR_WIDTH / 4 - hlSize / 2, hlOffset,
  526.                 +CAR_WIDTH / 4 + hlSize / 2, hlOffset + hlSize
  527.             );
  528.             DeleteObject(hlBrush);*/
  529.  
  530.             //revert to ..
  531.  
  532. /*                //headlights yellow (AI)
  533.             SelectObject(memDC, CreateSolidBrush(RGB(255, 255, 0)));
  534.             Rectangle(memDC, -CAR_WIDTH / 2 + 2, -CAR_HEIGHT / 2 + 2, -CAR_WIDTH / 4, -CAR_HEIGHT / 2 + 6);
  535.             Rectangle(memDC, CAR_WIDTH / 4, -CAR_HEIGHT / 2 + 2, CAR_WIDTH / 2 - 2, -CAR_HEIGHT / 2 + 6);
  536.             */
  537.  
  538.             HBRUSH winB = CreateSolidBrush(RGB(0, 0, 0));
  539.             SelectObject(memDC, winB);
  540.  
  541.             int wsY = -CAR_HEIGHT / 2 + int(0.38f * CAR_HEIGHT);
  542.             int wsH = CAR_HEIGHT / 6;
  543.             int wsW = int(CAR_WIDTH * 0.7f);
  544.  
  545.             Rectangle(memDC,
  546.                 -wsW / 2, wsY,
  547.                 wsW / 2, wsY + wsH
  548.             );
  549.  
  550.             int stripW = max(2, CAR_WIDTH / 20);
  551.             int stripH = wsH * 2;
  552.             Rectangle(memDC,
  553.                 -wsW / 2 - stripW, wsY,
  554.                 -wsW / 2, wsY + stripH
  555.             );
  556.             Rectangle(memDC,
  557.                 +wsW / 2, wsY,
  558.                 +wsW / 2 + stripW, wsY + stripH
  559.             );
  560.             DeleteObject(winB);
  561.  
  562.  
  563.             HBRUSH tyB = CreateSolidBrush(RGB(0, 0, 0));
  564.             SelectObject(memDC, tyB);
  565.             int t = TYRE_SIZE;
  566.  
  567.             int fy = -CAR_HEIGHT / 2 + 5;
  568.             Rectangle(memDC, -CAR_WIDTH / 2, fy, -CAR_WIDTH / 2 + t, fy + t);
  569.             Rectangle(memDC, +CAR_WIDTH / 2 - t, fy, +CAR_WIDTH / 2, fy + t);
  570.  
  571.             int ry = +CAR_HEIGHT / 2 - t - 5;
  572.             Rectangle(memDC, -CAR_WIDTH / 2, ry, -CAR_WIDTH / 2 + t, ry + t);
  573.             Rectangle(memDC, +CAR_WIDTH / 2 - t, ry, +CAR_WIDTH / 2, ry + t);
  574.             DeleteObject(tyB);
  575.  
  576.  
  577.             /*const float  frontFrac = 0.38f;
  578.             int    wsY = int(-CAR_HEIGHT / 2 + frontFrac * CAR_HEIGHT);
  579.             int    wsH = CAR_HEIGHT / 6;
  580.             int    wsW = int(CAR_WIDTH * 0.7f);
  581.             HBRUSH winBrush = CreateSolidBrush(RGB(0, 0, 0));
  582.             SelectObject(memDC, winBrush);
  583.  
  584.             Rectangle(memDC,
  585.                 -wsW / 2, wsY,
  586.                 wsW / 2, wsY + wsH
  587.             );
  588.  
  589.             int stripW = max(2, CAR_WIDTH / 20);
  590.             int stripH = wsH * 2;
  591.  
  592.             Rectangle(memDC,
  593.                 -wsW / 2 - stripW, wsY,
  594.                 -wsW / 2, wsY + stripH
  595.             );
  596.  
  597.             Rectangle(memDC,
  598.                 +wsW / 2, wsY,
  599.                 +wsW / 2 + stripW, wsY + stripH
  600.             );
  601.             DeleteObject(winBrush);
  602.  
  603.  
  604.             HBRUSH tyBrush = CreateSolidBrush(RGB(0, 0, 0));
  605.             SelectObject(memDC, tyBrush);
  606.             int t = TYRE_SIZE;
  607.  
  608.             int fy = -CAR_HEIGHT / 2 + 5;
  609.             Rectangle(memDC, -CAR_WIDTH / 2, fy, -CAR_WIDTH / 2 + t, fy + t);
  610.             Rectangle(memDC, +CAR_WIDTH / 2 - t, fy, CAR_WIDTH / 2, fy + t);
  611.  
  612.             int ry = +CAR_HEIGHT / 2 - t - 5;
  613.             Rectangle(memDC, -CAR_WIDTH / 2, ry, -CAR_WIDTH / 2 + t, ry + t);
  614.             Rectangle(memDC, +CAR_WIDTH / 2 - t, ry, CAR_WIDTH / 2, ry + t);
  615.             DeleteObject(tyBrush); */
  616.  
  617.  
  618.             /*
  619.             //start
  620.             int wsY = -CAR_HEIGHT / 2 + int(0.38f * CAR_HEIGHT);
  621.             int wsH = CAR_HEIGHT / 6;
  622.             int wsW = int(CAR_WIDTH * 0.7f);
  623.  
  624.             HBRUSH hWin = CreateSolidBrush(RGB(0, 0, 0));
  625.             SelectObject(memDC, hWin);
  626.  
  627.             Rectangle(memDC,
  628.                 -wsW / 2, wsY,
  629.                 wsW / 2, wsY + wsH
  630.             );
  631.  
  632.             //start sidewindow
  633.             int stripW = max(2, CAR_WIDTH / 20);
  634.             int stripH = wsH * 2;
  635.  
  636.             Rectangle(memDC,
  637.                 -wsW / 2 - stripW,
  638.                 wsY,
  639.                 -wsW / 2,
  640.                 wsY + stripH
  641.             );
  642.  
  643.             Rectangle(memDC,
  644.                 wsW / 2,
  645.                 wsY,
  646.                 wsW / 2 + stripW,
  647.                 wsY + stripH
  648.             );
  649.             //end sidewindow
  650.             */
  651.             /*
  652.             int sideW = CAR_WIDTH / 8;
  653.             Rectangle(memDC,
  654.                 -CAR_WIDTH / 2 + 5, wsY,
  655.                 -CAR_WIDTH / 2 + 5 + sideW, wsY + wsH
  656.             );
  657.             Rectangle(memDC,
  658.                 CAR_WIDTH / 2 - 5 - sideW, wsY,
  659.                 CAR_WIDTH / 2 - 5, wsY + wsH
  660.             );
  661. */
  662.             /*
  663.             DeleteObject(hWin);
  664.  
  665.             HBRUSH hTy = CreateSolidBrush(RGB(0, 0, 0));
  666.             SelectObject(memDC, hTy);
  667.             int t = TYRE_SIZE;
  668.  
  669.             int fy = -CAR_HEIGHT / 2 + 5;
  670.             Rectangle(memDC, -CAR_WIDTH / 2, fy, -CAR_WIDTH / 2 + t, fy + t);
  671.             Rectangle(memDC, CAR_WIDTH / 2 - t, fy, CAR_WIDTH / 2, fy + t);
  672.  
  673.             int ry = CAR_HEIGHT / 2 - t - 5;
  674.             Rectangle(memDC, -CAR_WIDTH / 2, ry, -CAR_WIDTH / 2 + t, ry + t);
  675.             Rectangle(memDC, CAR_WIDTH / 2 - t, ry, CAR_WIDTH / 2, ry + t);
  676.  
  677.             DeleteObject(hTy);
  678.             //ends */
  679.  
  680.             RestoreDC(memDC, savedDC2);
  681.             DeleteObject(blueBrush);
  682.         }
  683.  
  684.             /*{
  685.             HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
  686.             SelectObject(memDC, blueBrush);
  687.  
  688.             int savedDC2 = SaveDC(memDC);
  689.             SetGraphicsMode(memDC, GM_ADVANCED);
  690.  
  691.             XFORM xform2;
  692.             xform2.eM11 = (FLOAT)cos(aiAngle);
  693.             xform2.eM12 = (FLOAT)sin(aiAngle);
  694.             xform2.eM21 = (FLOAT)-sin(aiAngle);
  695.             xform2.eM22 = (FLOAT)cos(aiAngle);
  696.             xform2.eDx = (FLOAT)aiX + CAR_WIDTH / 2;
  697.             xform2.eDy = (FLOAT)aiY + CAR_HEIGHT / 2;
  698.             SetWorldTransform(memDC, &xform2);
  699.  
  700.             Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
  701.  
  702.             {
  703.                 HBRUSH hlBrush = CreateSolidBrush(RGB(255, 255, 255));
  704.                 SelectObject(memDC, hlBrush);
  705.                 int hlSize = 8;
  706.                 int hlOffset = -CAR_HEIGHT / 2 + 5;
  707.  
  708.                 Ellipse(memDC,
  709.                     -CAR_WIDTH / 4 - hlSize / 2, hlOffset,
  710.                     -CAR_WIDTH / 4 + hlSize / 2, hlOffset + hlSize
  711.                 );
  712.  
  713.                 Ellipse(memDC,
  714.                     +CAR_WIDTH / 4 - hlSize / 2, hlOffset,
  715.                     +CAR_WIDTH / 4 + hlSize / 2, hlOffset + hlSize
  716.                 );
  717.                 DeleteObject(hlBrush);
  718.             }
  719.  
  720.             {
  721.                 HBRUSH winBrush = CreateSolidBrush(RGB(0, 0, 0));
  722.                 SelectObject(memDC, winBrush);
  723.  
  724.                 int wsY = -CAR_HEIGHT / 2 + int(0.38f * CAR_HEIGHT);
  725.                 int wsH = CAR_HEIGHT / 6;
  726.                 int wsW = int(CAR_WIDTH * 0.7f);
  727.  
  728.                 Rectangle(memDC,
  729.                     -wsW / 2, wsY,
  730.                     wsW / 2, wsY + wsH
  731.                 );
  732.  
  733.                 int stripW = max(2, CAR_WIDTH / 20);
  734.                 int stripH = wsH * 2;
  735.  
  736.                 Rectangle(memDC,
  737.                     -wsW / 2 - stripW, wsY,
  738.                     -wsW / 2, wsY + stripH
  739.                 );
  740.  
  741.                 Rectangle(memDC,
  742.                     +wsW / 2, wsY,
  743.                     +wsW / 2 + stripW, wsY + stripH
  744.                 );
  745.  
  746.                 DeleteObject(winBrush);
  747.             }
  748.  
  749.             {
  750.                 HBRUSH tyBrush = CreateSolidBrush(RGB(0, 0, 0));
  751.                 SelectObject(memDC, tyBrush);
  752.  
  753.                 int t = TYRE_SIZE;
  754.  
  755.                 int fy = -CAR_HEIGHT / 2 + 5;
  756.                 Rectangle(memDC, -CAR_WIDTH / 2, fy, -CAR_WIDTH / 2 + t, fy + t);
  757.                 Rectangle(memDC, +CAR_WIDTH / 2 - t, fy, +CAR_WIDTH / 2, fy + t);
  758.  
  759.                 int ry = +CAR_HEIGHT / 2 - t - 5;
  760.                 Rectangle(memDC, -CAR_WIDTH / 2, ry, -CAR_WIDTH / 2 + t, ry + t);
  761.                 Rectangle(memDC, +CAR_WIDTH / 2 - t, ry, +CAR_WIDTH / 2, ry + t);
  762.  
  763.                 DeleteObject(tyBrush);
  764.             }
  765.  
  766.             RestoreDC(memDC, savedDC2);
  767.             DeleteObject(blueBrush);
  768.             }*/
  769.  
  770.  
  771.         // ----- Dynamically Compute and Draw AI Headlights -----
  772.         //
  773.         // This solution calculates the headlight positions based on the car�s center,
  774.         // a �front� vector (pointing toward the nose) and a perpendicular vector for lateral offset.
  775.         // The idea is that the headlights are placed at a fixed distance (headlightDistance)
  776.         // from the center along the front vector (which is always the nose direction)
  777.         // and then offset left/right by aiheadlightSeparation.
  778.         /*{ //revert to..
  779.             // Car center
  780.             float cx = aiX + CAR_WIDTH / 2.0f;
  781.             float cy = aiY + CAR_HEIGHT / 2.0f;
  782.  
  783.             // Parameters � adjust these to fine-tune the look:
  784.             // We use CAR_HEIGHT/2 as the full distance from center to nose when facing up.
  785.             // To mimic the player car�s appearance (headlights slightly inset from the very front),
  786.             // we subtract 15 pixels.
  787.             float headlightDistance = CAR_HEIGHT / 2.0f - 15.0f;
  788.             float aiheadlightSeparation = 10.0f;  // Lateral offset from the center of the nose
  789.             int aiheadlightSize = 8;              // Headlight circle size
  790.  
  791.             // Compute the "front" direction vector.
  792.             // Since the car�s default (unrotated) orientation has its nose at the top,
  793.             // the front vector in local coordinates is (0, -1). Rotating that by aiAngle:
  794.             float frontDirX = -sin(aiAngle);
  795.             float frontDirY = -cos(aiAngle);
  796.  
  797.             // Determine the headlight �center� position � a point along the nose,
  798.             // but moved slightly inward by headlightDistance:
  799.             float headlightCenterX = cx + frontDirX * headlightDistance;
  800.             float headlightCenterY = cy + frontDirY * headlightDistance;
  801.  
  802.             // Compute a perpendicular vector to the front.
  803.             // A vector perpendicular to (frontDirX, frontDirY) is given by (cos(aiAngle), -sin(aiAngle)).
  804.             float perpX = cos(aiAngle);
  805.             float perpY = -sin(aiAngle);
  806.  
  807.             // Compute left and right headlight positions by offsetting the headlight center along the perpendicular.
  808.             float leftHeadlightX = headlightCenterX - perpX * aiheadlightSeparation;
  809.             float leftHeadlightY = headlightCenterY - perpY * aiheadlightSeparation;
  810.             float rightHeadlightX = headlightCenterX + perpX * aiheadlightSeparation;
  811.             float rightHeadlightY = headlightCenterY + perpY * aiheadlightSeparation;
  812.  
  813.             // Draw the AI headlights using the computed world coordinates:
  814.             HBRUSH aiHeadlightBrush = CreateSolidBrush(RGB(255, 255, 255));
  815.             SelectObject(memDC, aiHeadlightBrush);
  816.             Ellipse(memDC, (int)leftHeadlightX, (int)leftHeadlightY,
  817.                 (int)(leftHeadlightX + aiheadlightSize), (int)(leftHeadlightY + aiheadlightSize));
  818.             Ellipse(memDC, (int)rightHeadlightX, (int)rightHeadlightY,
  819.                 (int)(rightHeadlightX + aiheadlightSize), (int)(rightHeadlightY + aiheadlightSize));
  820.             DeleteObject(aiHeadlightBrush);
  821.  
  822.         }*/
  823.  
  824.  
  825.             {
  826.             float cx = aiX + CAR_WIDTH / 2.0f;
  827.             float cy = aiY + CAR_HEIGHT / 2.0f;
  828.  
  829.             float frontDirX = -sin(aiAngle);
  830.             float frontDirY = -cos(aiAngle);
  831.  
  832.             float perpX = cos(aiAngle);
  833.             float perpY = -sin(aiAngle);
  834.  
  835.             float headlightDistance = CAR_HEIGHT / 2.0f - 15.0f;
  836.             float aiheadlightSeparation = 10.0f;
  837.             int   aiheadlightSize = 8;
  838.  
  839.             float leftHeadlightX = cx + frontDirX * headlightDistance - perpX * aiheadlightSeparation;
  840.             float leftHeadlightY = cy + frontDirY * headlightDistance - perpY * aiheadlightSeparation;
  841.             float rightHeadlightX = cx + frontDirX * headlightDistance + perpX * aiheadlightSeparation;
  842.             float rightHeadlightY = cy + frontDirY * headlightDistance + perpY * aiheadlightSeparation;
  843.  
  844.             HBRUSH aiHeadlightBrush = CreateSolidBrush(RGB(255, 255, 255));
  845.             SelectObject(memDC, aiHeadlightBrush);
  846.             Ellipse(memDC,
  847.                 (int)leftHeadlightX, (int)leftHeadlightY,
  848.                 (int)(leftHeadlightX + aiheadlightSize), (int)(leftHeadlightY + aiheadlightSize)
  849.             );
  850.             Ellipse(memDC,
  851.                 (int)rightHeadlightX, (int)rightHeadlightY,
  852.                 (int)(rightHeadlightX + aiheadlightSize), (int)(rightHeadlightY + aiheadlightSize)
  853.             );
  854.             DeleteObject(aiHeadlightBrush);
  855.  
  856.  
  857.             float windowDistance = headlightDistance + 10.0f;
  858.             float windowX = cx + frontDirX * windowDistance;
  859.             float windowY = cy + frontDirY * windowDistance;
  860.             int   wsW = int(CAR_WIDTH * 0.7f);
  861.             int   wsH = CAR_HEIGHT / 8;
  862.  
  863.             HBRUSH winBrush = CreateSolidBrush(RGB(0, 0, 0));
  864.             SelectObject(memDC, winBrush);
  865.  
  866.             //misbehaving chunk of rectangle protrusion commented-out
  867.             /*Rectangle(memDC,
  868.                 int(windowX - wsW / 2), int(windowY - wsH / 2),
  869.                 int(windowX + wsW / 2), int(windowY + wsH / 2)
  870.             );*/
  871.  
  872.             float sideOffset = wsW / 2 + 4.0f;  // push out from window edge
  873.             int   sideW = 3;             // ~3px thick
  874.             int   sideH = wsH;           // same height as windscreen
  875.  
  876.  
  877.             float lwX = windowX - perpX * sideOffset;
  878.             float lwY = windowY - perpY * sideOffset;
  879.             Rectangle(memDC,
  880.                 int(lwX - sideW / 2), int(lwY - sideH / 2),
  881.                 int(lwX + sideW / 2), int(lwY + sideH / 2)
  882.             );
  883.  
  884.             float rwX = windowX + perpX * sideOffset;
  885.             float rwY = windowY + perpY * sideOffset;
  886.             Rectangle(memDC,
  887.                 int(rwX - sideW / 2), int(rwY - sideH / 2),
  888.                 int(rwX + sideW / 2), int(rwY + sideH / 2)
  889.             );
  890.             DeleteObject(winBrush);
  891.             }
  892.  
  893.  
  894.  
  895.  
  896.  
  897.         //original AI code
  898.         /* HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
  899.         SelectObject(memDC, blueBrush);
  900.         savedDC = SaveDC(memDC);
  901.         SetGraphicsMode(memDC, GM_ADVANCED);
  902.         XFORM xform2;
  903.         xform2.eM11 = (FLOAT)cos(aiAngle);
  904.         xform2.eM12 = (FLOAT)sin(aiAngle);
  905.         xform2.eM21 = (FLOAT)-sin(aiAngle);
  906.         xform2.eM22 = (FLOAT)cos(aiAngle);
  907.         xform2.eDx = (FLOAT)aiX + CAR_WIDTH / 2;
  908.         xform2.eDy = (FLOAT)aiY + CAR_HEIGHT / 2;
  909.         SetWorldTransform(memDC, &xform2);
  910.         Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
  911.  
  912.         HBRUSH aiheadlightBrush = CreateSolidBrush(RGB(255, 255, 255));
  913.         SelectObject(memDC, aiheadlightBrush);
  914.         int aiheadlightSize = 8;
  915.  
  916.         // Define AI headlight positions based on calculated offsets
  917.         Ellipse(memDC, -CAR_WIDTH / 4 - aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5,
  918.             -CAR_WIDTH / 4 + aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5 + aiheadlightSize);
  919.         Ellipse(memDC, CAR_WIDTH / 4 - aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5,
  920.             CAR_WIDTH / 4 + aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5 + aiheadlightSize);
  921.  
  922.         DeleteObject(aiheadlightBrush);
  923.         RestoreDC(memDC, savedDC);
  924.         DeleteObject(blueBrush); */
  925.  
  926.         // Draw countdown timer if game hasn't started
  927.         if (!gameStarted)
  928.         {
  929.             char timerText[10];
  930.             sprintf_s(timerText, "%d", timer / 10);
  931.             SetTextColor(memDC, RGB(255, 0, 0));
  932.             SetBkMode(memDC, TRANSPARENT);
  933.             TextOutA(memDC, WIDTH / 2 - 10, HEIGHT / 2 - 10, timerText, strlen(timerText));
  934.         }
  935.  
  936.         // Draw God Mode text indicator
  937.         if (godMode)
  938.         {
  939.             SetTextColor(memDC, RGB(255, 0, 0));
  940.             SetBkMode(memDC, TRANSPARENT);
  941.             TextOutA(memDC, 10, 10, "God Mode ON", 11);
  942.         }
  943.  
  944.         // Copy from memory DC to screen
  945.         BitBlt(hdc, 0, 0, WIDTH, HEIGHT, memDC, 0, 0, SRCCOPY);
  946.  
  947.         // Clean up
  948.         SelectObject(memDC, oldBitmap);
  949.         DeleteObject(memBitmap);
  950.         DeleteDC(memDC);
  951.  
  952.         EndPaint(hWnd, &ps);
  953.         break;
  954.     }
  955.     case WM_DESTROY:
  956.         KillTimer(hWnd, 1);
  957.         PostQuitMessage(0);
  958.         break;
  959.     case WM_KEYDOWN:
  960.         if (wParam == VK_F1)
  961.         {
  962.             MessageBoxW(hWnd, L"2D Racing Game 3.0 Programmed in C++ Win32 API (491 lines of code) by Entisoft Software (c) Evans Thorpemorton", L"About", MB_OK | MB_ICONINFORMATION); // orig 395 lines
  963.         }
  964.         //break;
  965.         if (wParam == VK_ESCAPE)
  966.         {
  967.             PostQuitMessage(0);
  968.         }
  969.         break;
  970.     default:
  971.         return DefWindowProc(hWnd, message, wParam, lParam);
  972.     }
  973.     return 0;
  974. }
  975.  
  976. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  977. {
  978.     // Register window class
  979.     WNDCLASSEX wc = { 0 };
  980.     wc.cbSize = sizeof(WNDCLASSEX);
  981.     wc.style = CS_HREDRAW | CS_VREDRAW;
  982.     wc.lpfnWndProc = WndProc;
  983.     wc.cbClsExtra = 0;
  984.     wc.cbWndExtra = 0;
  985.     wc.hInstance = hInstance;
  986.     wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));        // Modified line
  987.     //wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  988.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  989.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  990.     wc.lpszMenuName = NULL;
  991.     wc.lpszClassName = L"RacingGame";
  992.     wc.hIconSm = (HICON)LoadImage(hInstance,                           // Modified line
  993.         MAKEINTRESOURCE(IDI_ICON1),           // Modified line
  994.         IMAGE_ICON,                           // Modified line
  995.         16,                                   // Modified line
  996.         16,                                   // Modified line
  997.         LR_DEFAULTCOLOR);                     // Modified line
  998.     //wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  999.     RegisterClassEx(&wc);
  1000.  
  1001.     // Calculate the position to center the window
  1002.     int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  1003.     int screenHeight = GetSystemMetrics(SM_CYSCREEN);
  1004.     int windowX = (screenWidth - WIDTH) / 2;
  1005.     int windowY = (screenHeight - HEIGHT) / 2;
  1006.  
  1007.     // Create window
  1008.     HWND hWnd = CreateWindowEx(0, L"RacingGame", L"Racing Game (ArrowKeys=Move G=GodMode)", WS_OVERLAPPEDWINDOW, windowX, windowY, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL);
  1009.  
  1010.     // Show window
  1011.     //ShowWindow(hWnd, nCmdShow);
  1012.     ShowWindow(hWnd, SW_SHOWMAXIMIZED);
  1013.  
  1014.     // Main loop
  1015.     MSG msg = { 0 };
  1016.     while (GetMessage(&msg, NULL, 0, 0))
  1017.     {
  1018.         TranslateMessage(&msg);
  1019.         DispatchMessage(&msg);
  1020.     }
  1021.  
  1022.     return 0;
  1023. }
  1024. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement