· 6 months ago · Mar 31, 2025, 01:20 PM
1==++ Here's the full code 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
12const int WIDTH = 1366;
13const int HEIGHT = 768;
14const int ROAD_WIDTH = 200;
15const int CAR_WIDTH = 50;
16const int CAR_HEIGHT = 100;
17const int TYRE_SIZE = 10;
18const int FPS = 60;
19const int TIMER = 4;
20const int TURN_RADIUS = 5;
21const double PI = 3.14159265358979323846;
22const double M_PI = 3.14159265358979323846;
23
24int playerX = 100;
25int playerY = HEIGHT - CAR_HEIGHT - 50;
26int playerSpeedX = 0;
27int playerSpeedY = 0;
28int aiX = playerX + CAR_WIDTH + 20;
29int aiY = playerY;
30float aiAngle = -PI / 2; // Add this line
31int aiSpeedX = 0;
32int aiSpeedY = 0;
33int speed = 5;
34int aiSpeed = 5;
35int timer = TIMER;
36int playerTyre1X = playerX + 10;
37int playerTyre1Y = playerY + CAR_HEIGHT - TYRE_SIZE;
38int playerTyre2X = playerX + CAR_WIDTH - TYRE_SIZE - 10;
39int playerTyre2Y = playerY + CAR_HEIGHT - TYRE_SIZE;
40int aiTyre1X = aiX + 10;
41int aiTyre1Y = aiY + CAR_HEIGHT - TYRE_SIZE;
42int aiTyre2X = aiX + CAR_WIDTH - TYRE_SIZE - 10;
43int aiTyre2Y = aiY + CAR_HEIGHT - TYRE_SIZE;
44float playerAngle = -PI / 2; // Initialize to face North by default
45//float playerAngle = 0.0f;
46
47bool gameStarted = false;
48bool gameOver = false;
49bool playerWon = false;
50bool godMode = true;
51//int timer = 30 * 10; // 30 seconds * 10 (timer resolution)
52
53// Window Procedure
54LRESULT 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 HBRUSH headlightBrush = CreateSolidBrush(RGB(255, 255, 255));
336 SelectObject(memDC, headlightBrush);
337 // Consistent headlight offset, relative to the car's dimensions
338 int headlightSize = 10;
339 int playerheadlightOffsetX = 10;
340 int playerheadlightOffsetY = -CAR_HEIGHT / 2 + 15; // Adjusted vertical offset
341 Ellipse(memDC, -CAR_WIDTH / 2 + playerheadlightOffsetX, playerheadlightOffsetY,
342 -CAR_WIDTH / 2 + playerheadlightOffsetX + headlightSize, playerheadlightOffsetY + headlightSize);
343 Ellipse(memDC, CAR_WIDTH / 2 - playerheadlightOffsetX - headlightSize, playerheadlightOffsetY,
344 CAR_WIDTH / 2 - playerheadlightOffsetX, playerheadlightOffsetY + headlightSize);
345 DeleteObject(headlightBrush);
346 RestoreDC(memDC, savedDC);
347 DeleteObject(redBrush);
348
349 // Draw AI car (blue rectangle)
350 // AI Car Rendering
351 // Drawing AI's Car and Headlights
352 // Draw AI car (blue rectangle)
353 // AI Car Rendering
354 // AI Car Rendering
355 //O3's fix working best inconsistent padded positioning tho
356 // Draw AI car (blue rectangle)
357 /* // ----- Draw AI Car (blue rectangle) with rotated transform -----
358 HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
359 SelectObject(memDC, blueBrush);
360 int savedDC2 = SaveDC(memDC); // Save state using a unique variable name
361 SetGraphicsMode(memDC, GM_ADVANCED);
362 XFORM xform2;
363 xform2.eM11 = (FLOAT)cos(aiAngle);
364 xform2.eM12 = (FLOAT)sin(aiAngle);
365 xform2.eM21 = (FLOAT)-sin(aiAngle);
366 xform2.eM22 = (FLOAT)cos(aiAngle);
367 xform2.eDx = (FLOAT)aiX + CAR_WIDTH / 2;
368 xform2.eDy = (FLOAT)aiY + CAR_HEIGHT / 2;
369 SetWorldTransform(memDC, &xform2);
370 Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
371 RestoreDC(memDC, savedDC2);
372 DeleteObject(blueBrush);
373
374 // ----- Dynamic AI Headlight Positioning -----
375 //
376 // This solution computes the AI car's nose (front) using its center (cx,cy)
377 // and a front vector derived from aiAngle. Note that the "front distance" is
378 // CAR_HEIGHT/2 when facing up/down (aiAngle == 0 or PI) and CAR_WIDTH/2 when
379 // facing right/left (aiAngle == -PI/2 or PI/2). We then move slightly back from
380 // the extreme nose by frontMargin, and offset perpendicular (by aiheadlightSeparation)
381 // to get the left and right headlight positions.
382 //
383 // Define parameters (adjust as needed):
384 float cx = aiX + CAR_WIDTH / 2.0f;
385 float cy = aiY + CAR_HEIGHT / 2.0f;
386 float frontMargin = 5.0f; // Moves headlights slightly inward from the nose
387 float aiheadlightSeparation = 10.0f; // Lateral offset from the nose for each headlight
388 int aiheadlightSize = 8; // Size of the headlight circle
389
390 // Determine the front distance depending on orientation:
391 float frontDistance;
392 if (aiAngle == 0 || aiAngle == PI)
393 frontDistance = CAR_HEIGHT / 2.0f;
394 else // aiAngle == -PI/2 or PI/2
395 frontDistance = CAR_WIDTH / 2.0f;
396
397 // The default car drawing uses a local coordinate system where the car's nose is at (0, -1)
398 // i.e. at (0, -frontDistance). Thus the front vector (rotated) is:
399 float noseX = cx + (-sin(aiAngle)) * frontDistance;
400 float noseY = cy + (-cos(aiAngle)) * frontDistance;
401
402 // Pull the headlight positions slightly back from the extreme nose using frontMargin:
403 float effectiveX = cx + (-sin(aiAngle)) * (frontDistance - frontMargin);
404 float effectiveY = cy + (-cos(aiAngle)) * (frontDistance - frontMargin);
405
406 // Compute a perpendicular vector to the front. For a front vector f = (-sin(aiAngle), -cos(aiAngle)),
407 // a perpendicular is p = (cos(aiAngle), -sin(aiAngle)). (We use -p for the left headlight.)
408 float px = cos(aiAngle);
409 float py = -sin(aiAngle);
410
411 // Compute left and right headlight positions by offsetting perpendicular to the front:
412 float leftHeadlightX = effectiveX - px * aiheadlightSeparation;
413 float leftHeadlightY = effectiveY - py * aiheadlightSeparation;
414
415 float rightHeadlightX = effectiveX + px * aiheadlightSeparation;
416 float rightHeadlightY = effectiveY + py * aiheadlightSeparation;
417
418 // Draw the AI headlights using the computed world coordinates:
419 HBRUSH aiHeadlightBrush = CreateSolidBrush(RGB(255, 255, 255));
420 SelectObject(memDC, aiHeadlightBrush);
421 Ellipse(memDC, (int)leftHeadlightX, (int)leftHeadlightY,
422 (int)(leftHeadlightX + aiheadlightSize), (int)(leftHeadlightY + aiheadlightSize));
423 Ellipse(memDC, (int)rightHeadlightX, (int)rightHeadlightY,
424 (int)(rightHeadlightX + aiheadlightSize), (int)(rightHeadlightY + aiheadlightSize));
425 DeleteObject(aiHeadlightBrush); */
426
427 //voila! It's working perfectly /w the following dynamic code!!!
428 // ----- Draw AI Car (blue rectangle) with rotated transform -----
429 {
430 HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
431 SelectObject(memDC, blueBrush);
432 int savedDC2 = SaveDC(memDC); // Save current DC state
433 SetGraphicsMode(memDC, GM_ADVANCED);
434 XFORM xform2;
435 xform2.eM11 = (FLOAT)cos(aiAngle);
436 xform2.eM12 = (FLOAT)sin(aiAngle);
437 xform2.eM21 = (FLOAT)-sin(aiAngle);
438 xform2.eM22 = (FLOAT)cos(aiAngle);
439 xform2.eDx = (FLOAT)aiX + CAR_WIDTH / 2;
440 xform2.eDy = (FLOAT)aiY + CAR_HEIGHT / 2;
441 SetWorldTransform(memDC, &xform2);
442 Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
443 RestoreDC(memDC, savedDC2);
444 DeleteObject(blueBrush);
445 }
446
447 // ----- Dynamically Compute and Draw AI Headlights -----
448 //
449 // This solution calculates the headlight positions based on the car’s center,
450 // a “front” vector (pointing toward the nose) and a perpendicular vector for lateral offset.
451 // The idea is that the headlights are placed at a fixed distance (headlightDistance)
452 // from the center along the front vector (which is always the nose direction)
453 // and then offset left/right by aiheadlightSeparation.
454 {
455 // Car center
456 float cx = aiX + CAR_WIDTH / 2.0f;
457 float cy = aiY + CAR_HEIGHT / 2.0f;
458
459 // Parameters – adjust these to fine-tune the look:
460 // We use CAR_HEIGHT/2 as the full distance from center to nose when facing up.
461 // To mimic the player car’s appearance (headlights slightly inset from the very front),
462 // we subtract 15 pixels.
463 float headlightDistance = CAR_HEIGHT / 2.0f - 15.0f;
464 float aiheadlightSeparation = 10.0f; // Lateral offset from the center of the nose
465 int aiheadlightSize = 8; // Headlight circle size
466
467 // Compute the "front" direction vector.
468 // Since the car’s default (unrotated) orientation has its nose at the top,
469 // the front vector in local coordinates is (0, -1). Rotating that by aiAngle:
470 float frontDirX = -sin(aiAngle);
471 float frontDirY = -cos(aiAngle);
472
473 // Determine the headlight “center” position – a point along the nose,
474 // but moved slightly inward by headlightDistance:
475 float headlightCenterX = cx + frontDirX * headlightDistance;
476 float headlightCenterY = cy + frontDirY * headlightDistance;
477
478 // Compute a perpendicular vector to the front.
479 // A vector perpendicular to (frontDirX, frontDirY) is given by (cos(aiAngle), -sin(aiAngle)).
480 float perpX = cos(aiAngle);
481 float perpY = -sin(aiAngle);
482
483 // Compute left and right headlight positions by offsetting the headlight center along the perpendicular.
484 float leftHeadlightX = headlightCenterX - perpX * aiheadlightSeparation;
485 float leftHeadlightY = headlightCenterY - perpY * aiheadlightSeparation;
486 float rightHeadlightX = headlightCenterX + perpX * aiheadlightSeparation;
487 float rightHeadlightY = headlightCenterY + perpY * aiheadlightSeparation;
488
489 // Draw the AI headlights using the computed world coordinates:
490 HBRUSH aiHeadlightBrush = CreateSolidBrush(RGB(255, 255, 255));
491 SelectObject(memDC, aiHeadlightBrush);
492 Ellipse(memDC, (int)leftHeadlightX, (int)leftHeadlightY,
493 (int)(leftHeadlightX + aiheadlightSize), (int)(leftHeadlightY + aiheadlightSize));
494 Ellipse(memDC, (int)rightHeadlightX, (int)rightHeadlightY,
495 (int)(rightHeadlightX + aiheadlightSize), (int)(rightHeadlightY + aiheadlightSize));
496 DeleteObject(aiHeadlightBrush);
497 }
498
499
500
501
502
503 //original AI code
504 /* HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
505 SelectObject(memDC, blueBrush);
506 savedDC = SaveDC(memDC);
507 SetGraphicsMode(memDC, GM_ADVANCED);
508 XFORM xform2;
509 xform2.eM11 = (FLOAT)cos(aiAngle);
510 xform2.eM12 = (FLOAT)sin(aiAngle);
511 xform2.eM21 = (FLOAT)-sin(aiAngle);
512 xform2.eM22 = (FLOAT)cos(aiAngle);
513 xform2.eDx = (FLOAT)aiX + CAR_WIDTH / 2;
514 xform2.eDy = (FLOAT)aiY + CAR_HEIGHT / 2;
515 SetWorldTransform(memDC, &xform2);
516 Rectangle(memDC, -CAR_WIDTH / 2, -CAR_HEIGHT / 2, CAR_WIDTH / 2, CAR_HEIGHT / 2);
517
518 HBRUSH aiheadlightBrush = CreateSolidBrush(RGB(255, 255, 255));
519 SelectObject(memDC, aiheadlightBrush);
520 int aiheadlightSize = 8;
521
522 // Define AI headlight positions based on calculated offsets
523 Ellipse(memDC, -CAR_WIDTH / 4 - aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5,
524 -CAR_WIDTH / 4 + aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5 + aiheadlightSize);
525 Ellipse(memDC, CAR_WIDTH / 4 - aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5,
526 CAR_WIDTH / 4 + aiheadlightSize / 2, -CAR_HEIGHT / 2 + 5 + aiheadlightSize);
527
528 DeleteObject(aiheadlightBrush);
529 RestoreDC(memDC, savedDC);
530 DeleteObject(blueBrush); */
531
532 // Draw countdown timer if game hasn't started
533 if (!gameStarted)
534 {
535 char timerText[10];
536 sprintf_s(timerText, "%d", timer / 10);
537 SetTextColor(memDC, RGB(255, 0, 0));
538 SetBkMode(memDC, TRANSPARENT);
539 TextOutA(memDC, WIDTH / 2 - 10, HEIGHT / 2 - 10, timerText, strlen(timerText));
540 }
541
542 // Draw God Mode text indicator
543 if (godMode)
544 {
545 SetTextColor(memDC, RGB(255, 0, 0));
546 SetBkMode(memDC, TRANSPARENT);
547 TextOutA(memDC, 10, 10, "God Mode ON", 11);
548 }
549
550 // Copy from memory DC to screen
551 BitBlt(hdc, 0, 0, WIDTH, HEIGHT, memDC, 0, 0, SRCCOPY);
552
553 // Clean up
554 SelectObject(memDC, oldBitmap);
555 DeleteObject(memBitmap);
556 DeleteDC(memDC);
557
558 EndPaint(hWnd, &ps);
559 break;
560 }
561 case WM_DESTROY:
562 KillTimer(hWnd, 1);
563 PostQuitMessage(0);
564 break;
565 case WM_KEYDOWN:
566 if (wParam == VK_F1)
567 {
568 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
569 }
570 //break;
571 if (wParam == VK_ESCAPE)
572 {
573 PostQuitMessage(0);
574 }
575 break;
576 default:
577 return DefWindowProc(hWnd, message, wParam, lParam);
578 }
579 return 0;
580}
581
582int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
583{
584 // Register window class
585 WNDCLASSEX wc = { 0 };
586 wc.cbSize = sizeof(WNDCLASSEX);
587 wc.style = CS_HREDRAW | CS_VREDRAW;
588 wc.lpfnWndProc = WndProc;
589 wc.cbClsExtra = 0;
590 wc.cbWndExtra = 0;
591 wc.hInstance = hInstance;
592 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); // Modified line
593 //wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
594 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
595 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
596 wc.lpszMenuName = NULL;
597 wc.lpszClassName = L"RacingGame";
598 wc.hIconSm = (HICON)LoadImage(hInstance, // Modified line
599 MAKEINTRESOURCE(IDI_ICON1), // Modified line
600 IMAGE_ICON, // Modified line
601 16, // Modified line
602 16, // Modified line
603 LR_DEFAULTCOLOR); // Modified line
604 //wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
605 RegisterClassEx(&wc);
606
607 // Calculate the position to center the window
608 int screenWidth = GetSystemMetrics(SM_CXSCREEN);
609 int screenHeight = GetSystemMetrics(SM_CYSCREEN);
610 int windowX = (screenWidth - WIDTH) / 2;
611 int windowY = (screenHeight - HEIGHT) / 2;
612
613 // Create window
614 HWND hWnd = CreateWindowEx(0, L"RacingGame", L"Racing Game (ArrowKeys=Move G=GodMode)", WS_OVERLAPPEDWINDOW, windowX, windowY, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL);
615
616 // Show window
617 //ShowWindow(hWnd, nCmdShow);
618 ShowWindow(hWnd, SW_SHOWMAXIMIZED);
619
620 // Main loop
621 MSG msg = { 0 };
622 while (GetMessage(&msg, NULL, 0, 0))
623 {
624 TranslateMessage(&msg);
625 DispatchMessage(&msg);
626 }
627
628 return 0;
629}
630```