1+ from flask import Flask , render_template_string
2+
3+ # PLEASE INSTALL FLASK BEFORE RUNNING THIS CODE
4+ # pip install flask
5+
6+ app = Flask (__name__ )
7+
8+
9+ HTML_TEMPLATE = """
10+ <!DOCTYPE html>
11+ <html lang="en">
12+ <head>
13+ <meta charset="UTF-8">
14+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
15+ <title>Space Dodge Game</title>
16+ <style>
17+ body {
18+ margin: 0;
19+ padding: 0;
20+ display: flex;
21+ justify-content: center;
22+ align-items: center;
23+ min-height: 100vh;
24+ background: linear-gradient(to bottom, #0a0e27, #1a1a2e);
25+ font-family: 'Arial', sans-serif;
26+ color: white;
27+ }
28+ #gameContainer {
29+ text-align: center;
30+ }
31+ canvas {
32+ border: 3px solid #4a5568;
33+ box-shadow: 0 0 20px rgba(74, 85, 104, 0.5);
34+ background: #000;
35+ }
36+ h1 {
37+ margin-bottom: 10px;
38+ color: #fff;
39+ text-shadow: 0 0 10px #4299e1;
40+ }
41+ .info {
42+ margin-top: 10px;
43+ color: #a0aec0;
44+ }
45+ </style>
46+ </head>
47+ <body>
48+ <div id="gameContainer">
49+ <h1>🚀 Space Dodge 🚀</h1>
50+ <canvas id="gameCanvas" width="800" height="600"></canvas>
51+ <div class="info">
52+ Use Arrow Keys to move • Collect green power-ups for shields • Press SPACE to restart
53+ </div>
54+ </div>
55+
56+ <script>
57+ const canvas = document.getElementById('gameCanvas');
58+ const ctx = canvas.getContext('2d');
59+ const WIDTH = canvas.width;
60+ const HEIGHT = canvas.height;
61+
62+ class Player {
63+ constructor() {
64+ this.size = 30;
65+ this.x = WIDTH / 2;
66+ this.y = HEIGHT - 80;
67+ this.speed = 7;
68+ this.shield = false;
69+ this.shieldTime = 0;
70+ }
71+
72+ move(keys) {
73+ if (keys.ArrowLeft && this.x > this.size) this.x -= this.speed;
74+ if (keys.ArrowRight && this.x < WIDTH - this.size) this.x += this.speed;
75+ if (keys.ArrowUp && this.y > this.size) this.y -= this.speed;
76+ if (keys.ArrowDown && this.y < HEIGHT - this.size) this.y += this.speed;
77+ }
78+
79+ draw() {
80+ const color = this.shield ? '#ffff33' : '#3296ff';
81+
82+ // Draw spaceship
83+ ctx.fillStyle = color;
84+ ctx.beginPath();
85+ ctx.moveTo(this.x, this.y - this.size);
86+ ctx.lineTo(this.x - this.size, this.y + this.size);
87+ ctx.lineTo(this.x + this.size, this.y + this.size);
88+ ctx.closePath();
89+ ctx.fill();
90+
91+ // Draw shield
92+ if (this.shield) {
93+ ctx.strokeStyle = '#ffff33';
94+ ctx.lineWidth = 2;
95+ ctx.beginPath();
96+ ctx.arc(this.x, this.y, this.size + 10, 0, Math.PI * 2);
97+ ctx.stroke();
98+ }
99+ }
100+
101+ update() {
102+ if (this.shield) {
103+ this.shieldTime--;
104+ if (this.shieldTime <= 0) this.shield = false;
105+ }
106+ }
107+ }
108+
109+ class Asteroid {
110+ constructor() {
111+ this.size = Math.random() * 25 + 15;
112+ this.x = Math.random() * (WIDTH - this.size * 2) + this.size;
113+ this.y = -this.size;
114+ this.speed = Math.random() * 4 + 3;
115+ }
116+
117+ move() {
118+ this.y += this.speed;
119+ }
120+
121+ draw() {
122+ ctx.fillStyle = '#ff3232';
123+ ctx.beginPath();
124+ ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
125+ ctx.fill();
126+ }
127+
128+ offScreen() {
129+ return this.y > HEIGHT + this.size;
130+ }
131+ }
132+
133+ class PowerUp {
134+ constructor() {
135+ this.size = 20;
136+ this.x = Math.random() * (WIDTH - this.size * 2) + this.size;
137+ this.y = -this.size;
138+ this.speed = 3;
139+ }
140+
141+ move() {
142+ this.y += this.speed;
143+ }
144+
145+ draw() {
146+ ctx.fillStyle = '#32ff32';
147+ ctx.beginPath();
148+ ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
149+ ctx.fill();
150+
151+ ctx.fillStyle = '#ffffff';
152+ ctx.beginPath();
153+ ctx.arc(this.x, this.y, this.size / 2, 0, Math.PI * 2);
154+ ctx.fill();
155+ }
156+
157+ offScreen() {
158+ return this.y > HEIGHT + this.size;
159+ }
160+ }
161+
162+ function checkCollision(player, obj) {
163+ const dist = Math.sqrt((player.x - obj.x) ** 2 + (player.y - obj.y) ** 2);
164+ return dist < player.size + obj.size;
165+ }
166+
167+ function drawStars(time) {
168+ ctx.fillStyle = '#ffffff';
169+ for (let i = 0; i < 50; i++) {
170+ const x = (i * 123) % WIDTH;
171+ const y = (i * 456 + time / 20) % HEIGHT;
172+ ctx.beginPath();
173+ ctx.arc(x, y, 1, 0, Math.PI * 2);
174+ ctx.fill();
175+ }
176+ }
177+
178+ let player = new Player();
179+ let asteroids = [];
180+ let powerups = [];
181+ let score = 0;
182+ let gameOver = false;
183+ let spawnTimer = 0;
184+ let powerupTimer = 0;
185+ let keys = {};
186+ let startTime = Date.now();
187+
188+ document.addEventListener('keydown', (e) => {
189+ keys[e.key] = true;
190+ if (e.key === ' ' && gameOver) {
191+ // Restart game
192+ player = new Player();
193+ asteroids = [];
194+ powerups = [];
195+ score = 0;
196+ gameOver = false;
197+ spawnTimer = 0;
198+ powerupTimer = 0;
199+ startTime = Date.now();
200+ }
201+ e.preventDefault();
202+ });
203+
204+ document.addEventListener('keyup', (e) => {
205+ keys[e.key] = false;
206+ });
207+
208+ function gameLoop() {
209+ const currentTime = Date.now() - startTime;
210+
211+ // Clear canvas
212+ ctx.fillStyle = '#000000';
213+ ctx.fillRect(0, 0, WIDTH, HEIGHT);
214+
215+ // Draw stars
216+ drawStars(currentTime);
217+
218+ if (!gameOver) {
219+ player.move(keys);
220+ player.update();
221+
222+ // Spawn asteroids
223+ spawnTimer++;
224+ if (spawnTimer > Math.max(20, 60 - Math.floor(score / 10))) {
225+ asteroids.push(new Asteroid());
226+ spawnTimer = 0;
227+ }
228+
229+ // Spawn powerups
230+ powerupTimer++;
231+ if (powerupTimer > 300) {
232+ powerups.push(new PowerUp());
233+ powerupTimer = 0;
234+ }
235+
236+ // Update asteroids
237+ for (let i = asteroids.length - 1; i >= 0; i--) {
238+ asteroids[i].move();
239+ if (asteroids[i].offScreen()) {
240+ asteroids.splice(i, 1);
241+ score++;
242+ } else if (checkCollision(player, asteroids[i])) {
243+ if (!player.shield) {
244+ gameOver = true;
245+ } else {
246+ asteroids.splice(i, 1);
247+ }
248+ }
249+ }
250+
251+ // Update powerups
252+ for (let i = powerups.length - 1; i >= 0; i--) {
253+ powerups[i].move();
254+ if (powerups[i].offScreen()) {
255+ powerups.splice(i, 1);
256+ } else if (checkCollision(player, powerups[i])) {
257+ powerups.splice(i, 1);
258+ player.shield = true;
259+ player.shieldTime = 180;
260+ score += 5;
261+ }
262+ }
263+ }
264+
265+ // Draw everything
266+ player.draw();
267+ asteroids.forEach(a => a.draw());
268+ powerups.forEach(p => p.draw());
269+
270+ // Draw score
271+ ctx.fillStyle = '#ffffff';
272+ ctx.font = '32px Arial';
273+ ctx.fillText(`Score: ${score}`, 10, 40);
274+
275+ if (gameOver) {
276+ ctx.fillStyle = '#ff3232';
277+ ctx.font = '64px Arial';
278+ ctx.fillText('GAME OVER!', WIDTH / 2 - 200, HEIGHT / 2 - 50);
279+
280+ ctx.fillStyle = '#ffffff';
281+ ctx.font = '32px Arial';
282+ ctx.fillText(`Final Score: ${score}`, WIDTH / 2 - 110, HEIGHT / 2 + 20);
283+ ctx.fillText('Press SPACE to restart', WIDTH / 2 - 150, HEIGHT / 2 + 80);
284+ }
285+
286+ requestAnimationFrame(gameLoop);
287+ }
288+
289+ gameLoop();
290+ </script>
291+ </body>
292+ </html>
293+ """
294+
295+ @app .route ('/' )
296+ def index ():
297+ return render_template_string (HTML_TEMPLATE )
298+
299+ if __name__ == '__main__' :
300+ app .run (debug = True , host = '0.0.0.0' , port = 5001 )
0 commit comments