KEXEL commited on
Commit
2b16689
·
verified ·
1 Parent(s): 188972a
Files changed (1) hide show
  1. gtaumretro.html +582 -0
gtaumretro.html ADDED
@@ -0,0 +1,582 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Retro GTA 1-Style Game</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <style>
10
+ body {
11
+ margin: 0;
12
+ padding: 0;
13
+ overflow: hidden;
14
+ background-color: #222;
15
+ font-family: 'Courier New', monospace;
16
+ }
17
+
18
+ #game-container {
19
+ position: relative;
20
+ width: 100vw;
21
+ height: 100vh;
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ }
26
+
27
+ #game-canvas {
28
+ background-color: #333;
29
+ border: 4px solid #555;
30
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
31
+ image-rendering: pixelated;
32
+ }
33
+
34
+ #hud {
35
+ position: absolute;
36
+ top: 10px;
37
+ left: 10px;
38
+ color: white;
39
+ background-color: rgba(0, 0, 0, 0.7);
40
+ padding: 10px;
41
+ border: 2px solid #555;
42
+ font-size: 14px;
43
+ }
44
+
45
+ #menu {
46
+ position: absolute;
47
+ top: 50%;
48
+ left: 50%;
49
+ transform: translate(-50%, -50%);
50
+ background-color: rgba(0, 0, 0, 0.8);
51
+ border: 4px solid #555;
52
+ padding: 20px;
53
+ color: white;
54
+ text-align: center;
55
+ z-index: 100;
56
+ }
57
+
58
+ .pixel-button {
59
+ background-color: #444;
60
+ color: white;
61
+ border: 2px solid #666;
62
+ padding: 10px 20px;
63
+ margin: 5px;
64
+ font-family: 'Courier New', monospace;
65
+ cursor: pointer;
66
+ transition: all 0.2s;
67
+ }
68
+
69
+ .pixel-button:hover {
70
+ background-color: #666;
71
+ border-color: #888;
72
+ }
73
+
74
+ .mission-marker {
75
+ position: absolute;
76
+ width: 16px;
77
+ height: 16px;
78
+ background-color: red;
79
+ border: 2px solid white;
80
+ border-radius: 50%;
81
+ transform: translate(-50%, -50%);
82
+ }
83
+
84
+ .car {
85
+ position: absolute;
86
+ width: 32px;
87
+ height: 32px;
88
+ background-color: blue;
89
+ transform-origin: center;
90
+ }
91
+
92
+ .pedestrian {
93
+ position: absolute;
94
+ width: 12px;
95
+ height: 12px;
96
+ background-color: green;
97
+ border-radius: 50%;
98
+ }
99
+
100
+ .building {
101
+ position: absolute;
102
+ background-color: #555;
103
+ border: 2px solid #333;
104
+ }
105
+
106
+ .road {
107
+ position: absolute;
108
+ background-color: #444;
109
+ }
110
+ </style>
111
+ </head>
112
+
113
+ <body>
114
+ <div id="game-container">
115
+ <canvas id="game-canvas"></canvas>
116
+
117
+ <div id="hud">
118
+ <div>Time: <span id="time">12:00</span></div>
119
+ <div>Score: <span id="score">0</span></div>
120
+ <div>Wanted: <span id="wanted">★</span></div>
121
+ <div>Health: <span id="health">100%</span></div>
122
+ <div>Money: $<span id="money">1000</span></div>
123
+ </div>
124
+
125
+ <div id="menu" style="display: none;">
126
+ <h1 class="text-2xl mb-4">RETRO GTA</h1>
127
+ <div class="mb-6">
128
+ <button id="start-game" class="pixel-button">START GAME</button>
129
+ <button id="controls" class="pixel-button">CONTROLS</button>
130
+ </div>
131
+ <div id="controls-info" style="display: none;">
132
+ <p class="mb-2">WASD or Arrow Keys - Move</p>
133
+ <p class="mb-2">Space - Handbrake</p>
134
+ <p class="mb-2">E - Enter/Exit Vehicle</p>
135
+ <p class="mb-2">M - Mission Start</p>
136
+ <button id="back-to-menu" class="pixel-button mt-4">BACK</button>
137
+ </div>
138
+ </div>
139
+ </div>
140
+
141
+ <script>
142
+ // Game state
143
+ const gameState = {
144
+ player: {
145
+ x: 400,
146
+ y: 300,
147
+ speed: 0,
148
+ angle: 0,
149
+ maxSpeed: 5,
150
+ acceleration: 0.1,
151
+ rotationSpeed: 3,
152
+ inVehicle: true,
153
+ health: 100,
154
+ money: 1000,
155
+ score: 0,
156
+ wantedLevel: 0
157
+ },
158
+ time: {
159
+ hours: 12,
160
+ minutes: 0
161
+ },
162
+ vehicles: [],
163
+ pedestrians: [],
164
+ buildings: [],
165
+ roads: [],
166
+ mission: {
167
+ active: false,
168
+ marker: { x: 600, y: 200 }
169
+ },
170
+ keys: {}
171
+ };
172
+
173
+ // DOM elements
174
+ const canvas = document.getElementById('game-canvas');
175
+ const ctx = canvas.getContext('2d');
176
+ const menu = document.getElementById('menu');
177
+ const startButton = document.getElementById('start-game');
178
+ const controlsButton = document.getElementById('controls');
179
+ const controlsInfo = document.getElementById('controls-info');
180
+ const backButton = document.getElementById('back-to-menu');
181
+ const timeDisplay = document.getElementById('time');
182
+ const scoreDisplay = document.getElementById('score');
183
+ const wantedDisplay = document.getElementById('wanted');
184
+ const healthDisplay = document.getElementById('health');
185
+ const moneyDisplay = document.getElementById('money');
186
+
187
+ // Set canvas size
188
+ function resizeCanvas() {
189
+ canvas.width = window.innerWidth * 0.9;
190
+ canvas.height = window.innerHeight * 0.9;
191
+ }
192
+
193
+ // Initialize game
194
+ function initGame() {
195
+ resizeCanvas();
196
+ showMenu();
197
+ generateCity();
198
+ window.addEventListener('resize', resizeCanvas);
199
+ window.addEventListener('keydown', handleKeyDown);
200
+ window.addEventListener('keyup', handleKeyUp);
201
+
202
+ startButton.addEventListener('click', startGame);
203
+ controlsButton.addEventListener('click', showControls);
204
+ backButton.addEventListener('click', showMenu);
205
+ }
206
+
207
+ // Show main menu
208
+ function showMenu() {
209
+ menu.style.display = 'block';
210
+ controlsInfo.style.display = 'none';
211
+ }
212
+
213
+ // Show controls
214
+ function showControls() {
215
+ menu.style.display = 'block';
216
+ controlsInfo.style.display = 'block';
217
+ }
218
+
219
+ // Start game
220
+ function startGame() {
221
+ menu.style.display = 'none';
222
+ gameLoop();
223
+ setInterval(updateTime, 60000); // Update time every minute (game time)
224
+ }
225
+
226
+ // Generate city elements
227
+ function generateCity() {
228
+ // Generate roads
229
+ for (let i = 0; i < 10; i++) {
230
+ gameState.roads.push({
231
+ x: i * 100,
232
+ y: 200,
233
+ width: 80,
234
+ height: 20
235
+ });
236
+
237
+ gameState.roads.push({
238
+ x: 400,
239
+ y: i * 80,
240
+ width: 20,
241
+ height: 60
242
+ });
243
+ }
244
+
245
+ // Generate buildings
246
+ for (let i = 0; i < 15; i++) {
247
+ gameState.buildings.push({
248
+ x: Math.random() * canvas.width,
249
+ y: Math.random() * canvas.height,
250
+ width: 60 + Math.random() * 100,
251
+ height: 80 + Math.random() * 120
252
+ });
253
+ }
254
+
255
+ // Generate pedestrians
256
+ for (let i = 0; i < 20; i++) {
257
+ gameState.pedestrians.push({
258
+ x: Math.random() * canvas.width,
259
+ y: Math.random() * canvas.height,
260
+ speed: 0.5 + Math.random() * 1.5,
261
+ direction: Math.random() * 360
262
+ });
263
+ }
264
+
265
+ // Generate other vehicles
266
+ for (let i = 0; i < 5; i++) {
267
+ gameState.vehicles.push({
268
+ x: Math.random() * canvas.width,
269
+ y: Math.random() * canvas.height,
270
+ speed: 1 + Math.random() * 3,
271
+ angle: Math.random() * 360,
272
+ color: `hsl(${Math.random() * 360}, 70%, 50%)`
273
+ });
274
+ }
275
+ }
276
+
277
+ // Handle key down
278
+ function handleKeyDown(e) {
279
+ gameState.keys[e.key] = true;
280
+
281
+ // Toggle menu with ESC
282
+ if (e.key === 'Escape') {
283
+ if (menu.style.display === 'none') {
284
+ menu.style.display = 'block';
285
+ } else {
286
+ menu.style.display = 'none';
287
+ }
288
+ }
289
+
290
+ // Start mission with M
291
+ if (e.key === 'm' && !gameState.mission.active) {
292
+ gameState.mission.active = true;
293
+ gameState.mission.marker = {
294
+ x: Math.random() * canvas.width,
295
+ y: Math.random() * canvas.height
296
+ };
297
+ }
298
+ }
299
+
300
+ // Handle key up
301
+ function handleKeyUp(e) {
302
+ gameState.keys[e.key] = false;
303
+ }
304
+
305
+ // Update game time
306
+ function updateTime() {
307
+ gameState.time.minutes += 10;
308
+ if (gameState.time.minutes >= 60) {
309
+ gameState.time.minutes = 0;
310
+ gameState.time.hours = (gameState.time.hours + 1) % 24;
311
+ }
312
+
313
+ const hoursStr = gameState.time.hours.toString().padStart(2, '0');
314
+ const minsStr = gameState.time.minutes.toString().padStart(2, '0');
315
+ timeDisplay.textContent = `${hoursStr}:${minsStr}`;
316
+ }
317
+
318
+ // Update game state
319
+ function update() {
320
+ const player = gameState.player;
321
+
322
+ // Player movement
323
+ if (player.inVehicle) {
324
+ // Acceleration
325
+ if (gameState.keys['ArrowUp'] || gameState.keys['w']) {
326
+ player.speed = Math.min(player.speed + player.acceleration, player.maxSpeed);
327
+ } else if (gameState.keys['ArrowDown'] || gameState.keys['s']) {
328
+ player.speed = Math.max(player.speed - player.acceleration, -player.maxSpeed / 2);
329
+ } else {
330
+ // Slow down
331
+ player.speed *= 0.95;
332
+ if (Math.abs(player.speed) < 0.1) player.speed = 0;
333
+ }
334
+
335
+ // Steering
336
+ if (player.speed !== 0) {
337
+ if (gameState.keys['ArrowLeft'] || gameState.keys['a']) {
338
+ player.angle -= player.rotationSpeed * (player.speed / player.maxSpeed);
339
+ }
340
+ if (gameState.keys['ArrowRight'] || gameState.keys['d']) {
341
+ player.angle += player.rotationSpeed * (player.speed / player.maxSpeed);
342
+ }
343
+ }
344
+
345
+ // Handbrake
346
+ if (gameState.keys[' ']) {
347
+ player.speed *= 0.8;
348
+ }
349
+
350
+ // Update position
351
+ const rad = player.angle * Math.PI / 180;
352
+ player.x += Math.sin(rad) * player.speed;
353
+ player.y -= Math.cos(rad) * player.speed;
354
+
355
+ // Check for collisions with buildings
356
+ for (const building of gameState.buildings) {
357
+ if (checkCollision(
358
+ player.x, player.y, 32, 32,
359
+ building.x, building.y, building.width, building.height
360
+ )) {
361
+ // Bounce off
362
+ player.speed = -player.speed * 0.5;
363
+ player.health -= 5;
364
+ healthDisplay.textContent = `${player.health}%`;
365
+
366
+ // Increase wanted level
367
+ if (gameState.player.wantedLevel < 5) {
368
+ gameState.player.wantedLevel++;
369
+ wantedDisplay.textContent = '★'.repeat(gameState.player.wantedLevel);
370
+ }
371
+ }
372
+ }
373
+ }
374
+
375
+ // Update other vehicles
376
+ for (const vehicle of gameState.vehicles) {
377
+ const rad = vehicle.angle * Math.PI / 180;
378
+ vehicle.x += Math.sin(rad) * vehicle.speed;
379
+ vehicle.y -= Math.cos(rad) * vehicle.speed;
380
+
381
+ // Simple AI - change direction occasionally
382
+ if (Math.random() < 0.01) {
383
+ vehicle.angle += (Math.random() - 0.5) * 30;
384
+ }
385
+
386
+ // Wrap around screen
387
+ if (vehicle.x < 0) vehicle.x = canvas.width;
388
+ if (vehicle.x > canvas.width) vehicle.x = 0;
389
+ if (vehicle.y < 0) vehicle.y = canvas.height;
390
+ if (vehicle.y > canvas.height) vehicle.y = 0;
391
+ }
392
+
393
+ // Update pedestrians
394
+ for (const ped of gameState.pedestrians) {
395
+ const rad = ped.direction * Math.PI / 180;
396
+ ped.x += Math.sin(rad) * ped.speed;
397
+ ped.y -= Math.cos(rad) * ped.speed;
398
+
399
+ // Change direction occasionally
400
+ if (Math.random() < 0.02) {
401
+ ped.direction += (Math.random() - 0.5) * 90;
402
+ }
403
+
404
+ // Avoid going off screen
405
+ if (ped.x < 0 || ped.x > canvas.width || ped.y < 0 || ped.y > canvas.height) {
406
+ ped.direction = Math.atan2(canvas.width / 2 - ped.x, canvas.height / 2 - ped.y) * 180 / Math.PI;
407
+ }
408
+ }
409
+
410
+ // Check mission completion
411
+ if (gameState.mission.active) {
412
+ const marker = gameState.mission.marker;
413
+ if (Math.sqrt((player.x - marker.x) ** 2 + (player.y - marker.y) ** 2) < 30) {
414
+ gameState.mission.active = false;
415
+ player.money += 500;
416
+ player.score += 1000;
417
+ moneyDisplay.textContent = player.money;
418
+ scoreDisplay.textContent = player.score;
419
+ }
420
+ }
421
+ }
422
+
423
+ // Check collision between two rectangles
424
+ function checkCollision(x1, y1, w1, h1, x2, y2, w2, h2) {
425
+ return x1 < x2 + w2 &&
426
+ x1 + w1 > x2 &&
427
+ y1 < y2 + h2 &&
428
+ y1 + h1 > y2;
429
+ }
430
+
431
+ // Render game
432
+ function render() {
433
+ // Clear canvas
434
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
435
+
436
+ // Draw roads
437
+ ctx.fillStyle = '#444';
438
+ for (const road of gameState.roads) {
439
+ ctx.fillRect(road.x, road.y, road.width, road.height);
440
+ }
441
+
442
+ // Draw buildings
443
+ ctx.fillStyle = '#555';
444
+ ctx.strokeStyle = '#333';
445
+ ctx.lineWidth = 2;
446
+ for (const building of gameState.buildings) {
447
+ ctx.fillRect(building.x, building.y, building.width, building.height);
448
+ ctx.strokeRect(building.x, building.y, building.width, building.height);
449
+
450
+ // Simple windows
451
+ ctx.fillStyle = '#777';
452
+ for (let i = 0; i < 3; i++) {
453
+ for (let j = 0; j < 3; j++) {
454
+ ctx.fillRect(
455
+ building.x + 10 + i * 15,
456
+ building.y + 10 + j * 15,
457
+ 8, 8
458
+ );
459
+ }
460
+ }
461
+ ctx.fillStyle = '#555';
462
+ }
463
+
464
+ // Draw pedestrians
465
+ ctx.fillStyle = 'green';
466
+ for (const ped of gameState.pedestrians) {
467
+ ctx.beginPath();
468
+ ctx.arc(ped.x, ped.y, 6, 0, Math.PI * 2);
469
+ ctx.fill();
470
+ }
471
+
472
+ // Draw other vehicles
473
+ for (const vehicle of gameState.vehicles) {
474
+ ctx.save();
475
+ ctx.translate(vehicle.x, vehicle.y);
476
+ ctx.rotate(vehicle.angle * Math.PI / 180);
477
+ ctx.fillStyle = vehicle.color;
478
+ ctx.fillRect(-16, -16, 32, 32);
479
+
480
+ // Simple car details
481
+ ctx.fillStyle = '#333';
482
+ ctx.fillRect(-12, -12, 24, 8);
483
+ ctx.fillRect(-12, 4, 24, 8);
484
+ ctx.restore();
485
+ }
486
+
487
+ // Draw player vehicle
488
+ const player = gameState.player;
489
+ ctx.save();
490
+ ctx.translate(player.x, player.y);
491
+ ctx.rotate(player.angle * Math.PI / 180);
492
+ ctx.fillStyle = 'blue';
493
+ ctx.fillRect(-16, -16, 32, 32);
494
+
495
+ // Car details
496
+ ctx.fillStyle = '#333';
497
+ ctx.fillRect(-12, -12, 24, 8); // Windshield
498
+ ctx.fillRect(-12, 4, 24, 8); // Rear window
499
+ ctx.fillStyle = 'red';
500
+ ctx.fillRect(12, -8, 4, 4); // Tail lights
501
+ ctx.fillRect(12, 4, 4, 4);
502
+ ctx.fillStyle = 'yellow';
503
+ ctx.fillRect(-16, -8, 4, 4); // Headlights
504
+ ctx.fillRect(-16, 4, 4, 4);
505
+ ctx.restore();
506
+
507
+ // Draw mission marker if active
508
+ if (gameState.mission.active) {
509
+ ctx.fillStyle = 'red';
510
+ ctx.beginPath();
511
+ ctx.arc(
512
+ gameState.mission.marker.x,
513
+ gameState.mission.marker.y,
514
+ 10, 0, Math.PI * 2
515
+ );
516
+ ctx.fill();
517
+ ctx.strokeStyle = 'white';
518
+ ctx.lineWidth = 2;
519
+ ctx.stroke();
520
+
521
+ // Draw line to marker
522
+ ctx.beginPath();
523
+ ctx.moveTo(player.x, player.y);
524
+ ctx.lineTo(gameState.mission.marker.x, gameState.mission.marker.y);
525
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
526
+ ctx.lineWidth = 1;
527
+ ctx.stroke();
528
+ }
529
+
530
+ // Draw minimap
531
+ const minimapSize = 150;
532
+ const minimapX = canvas.width - minimapSize - 20;
533
+ const minimapY = 20;
534
+
535
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
536
+ ctx.fillRect(minimapX, minimapY, minimapSize, minimapSize);
537
+ ctx.strokeStyle = '#555';
538
+ ctx.lineWidth = 2;
539
+ ctx.strokeRect(minimapX, minimapY, minimapSize, minimapSize);
540
+
541
+ // Draw roads on minimap
542
+ ctx.fillStyle = '#666';
543
+ for (const road of gameState.roads) {
544
+ const mx = minimapX + (road.x / canvas.width) * minimapSize;
545
+ const my = minimapY + (road.y / canvas.height) * minimapSize;
546
+ const mw = (road.width / canvas.width) * minimapSize;
547
+ const mh = (road.height / canvas.height) * minimapSize;
548
+ ctx.fillRect(mx, my, mw, mh);
549
+ }
550
+
551
+ // Draw player on minimap
552
+ ctx.fillStyle = 'blue';
553
+ const px = minimapX + (player.x / canvas.width) * minimapSize;
554
+ const py = minimapY + (player.y / canvas.height) * minimapSize;
555
+ ctx.beginPath();
556
+ ctx.arc(px, py, 3, 0, Math.PI * 2);
557
+ ctx.fill();
558
+
559
+ // Draw mission marker on minimap
560
+ if (gameState.mission.active) {
561
+ ctx.fillStyle = 'red';
562
+ const mx = minimapX + (gameState.mission.marker.x / canvas.width) * minimapSize;
563
+ const my = minimapY + (gameState.mission.marker.y / canvas.height) * minimapSize;
564
+ ctx.beginPath();
565
+ ctx.arc(mx, my, 3, 0, Math.PI * 2);
566
+ ctx.fill();
567
+ }
568
+ }
569
+
570
+ // Main game loop
571
+ function gameLoop() {
572
+ update();
573
+ render();
574
+ requestAnimationFrame(gameLoop);
575
+ }
576
+
577
+ // Initialize the game
578
+ window.onload = initGame;
579
+ </script>
580
+ </body>
581
+
582
+ </html>