awacke1 commited on
Commit
06c1427
·
verified ·
1 Parent(s): 414d077

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -34
app.py CHANGED
@@ -1,25 +1,37 @@
1
  import streamlit as st
2
  from streamlit.components.v1 import html
 
 
3
 
4
- # Define the HTML content with the Three.js game
5
  game_html = """
6
  <!DOCTYPE html>
7
  <html lang="en">
8
  <head>
9
  <meta charset="UTF-8">
10
- <title>Galaxxon - Three.js Arcade Game</title>
11
  <style>
12
- body { margin: 0; overflow: hidden; background: #000; }
13
  canvas { display: block; width: 100%; height: 100%; }
 
 
14
  </style>
15
  </head>
16
  <body>
 
 
 
 
 
 
17
  <script type="module">
18
  import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
19
 
20
- let scene, camera, renderer, player, enemies = [], bullets = [], obstacles = [];
21
  let clock = new THREE.Clock();
22
  let moveLeft = false, moveRight = false, moveUp = false, moveDown = false, shoot = false;
 
 
23
 
24
  function init() {
25
  scene = new THREE.Scene();
@@ -37,8 +49,8 @@ game_html = """
37
  player.position.y = -10;
38
  scene.add(player);
39
 
40
- spawnEnemies();
41
- spawnObstacles();
42
 
43
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
44
  scene.add(ambientLight);
@@ -47,30 +59,41 @@ game_html = """
47
  window.addEventListener('keyup', onKeyUp);
48
  window.addEventListener('resize', onWindowResize);
49
 
 
50
  animate();
51
  }
52
 
53
- function spawnEnemies() {
54
  const enemyGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
55
  const enemyMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
56
- for (let i = 0; i < 5; i++) {
57
- for (let j = 0; j < 3; j++) {
58
- const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
59
- enemy.position.set(i * 2 - 4, j * 2 + 5, 0);
60
- enemies.push(enemy);
61
- scene.add(enemy);
62
- }
63
  }
64
  }
65
 
66
- function spawnObstacles() {
67
- const obstacleGeometry = new THREE.BoxGeometry(2, 2, 2);
68
- const obstacleMaterial = new THREE.MeshBasicMaterial({ color: 0x808080 });
69
- for (let i = 0; i < 3; i++) {
70
- const obstacle = new THREE.Mesh(obstacleGeometry, obstacleMaterial);
71
- obstacle.position.set(Math.random() * 20 - 10, Math.random() * 10, 0);
72
- obstacles.push(obstacle);
73
- scene.add(obstacle);
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
  }
76
 
@@ -137,27 +160,83 @@ game_html = """
137
  enemies.splice(i, 1);
138
  scene.remove(bullet);
139
  bullets.splice(bulletIndex, 1);
 
 
 
 
 
140
  break;
141
  }
142
  }
143
  }
144
 
145
- function updateEnemies(delta) {
146
- const enemySpeed = 2;
147
  enemies.forEach(enemy => {
148
- enemy.position.y -= enemySpeed * delta;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  if (enemy.position.y < -15) enemy.position.y = 15;
 
150
  });
151
  }
152
 
153
- function updateObstacles(delta) {
154
- const obstacleSpeed = 1;
155
- obstacles.forEach(obstacle => {
156
- obstacle.position.y -= obstacleSpeed * delta;
157
- if (obstacle.position.y < -15) obstacle.position.y = 15;
158
  });
159
  }
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  function onWindowResize() {
162
  camera.aspect = window.innerWidth / window.innerHeight;
163
  camera.updateProjectionMatrix();
@@ -167,11 +246,13 @@ game_html = """
167
  function animate() {
168
  requestAnimationFrame(animate);
169
  const delta = clock.getDelta();
 
170
 
171
  updatePlayer(delta);
172
  updateBullets(delta);
173
- updateEnemies(delta);
174
- updateObstacles(delta);
 
175
 
176
  renderer.render(scene, camera);
177
  }
@@ -183,8 +264,8 @@ game_html = """
183
  """
184
 
185
  # Streamlit app
186
- st.title("Galaxxon - A Three.js Arcade Game")
187
- st.write("Use WASD or Arrow Keys to move, Spacebar to shoot. Destroy red enemies and avoid gray obstacles!")
188
 
189
  # Render the HTML game
190
  html(game_html, height=600, scrolling=False)
 
1
  import streamlit as st
2
  from streamlit.components.v1 import html
3
+ import random
4
+ import string
5
 
6
+ # Define the enhanced HTML content with Three.js game
7
  game_html = """
8
  <!DOCTYPE html>
9
  <html lang="en">
10
  <head>
11
  <meta charset="UTF-8">
12
+ <title>Galaxxon - Enhanced Arcade Game</title>
13
  <style>
14
+ body { margin: 0; overflow: hidden; background: #000; font-family: Arial; }
15
  canvas { display: block; width: 100%; height: 100%; }
16
+ #ui { position: absolute; top: 10px; left: 10px; color: white; }
17
+ #sidebar { position: absolute; top: 10px; right: 10px; color: white; width: 200px; background: rgba(0,0,0,0.7); padding: 10px; }
18
  </style>
19
  </head>
20
  <body>
21
+ <div id="ui">Score: <span id="score">0</span> | Multiplier: <span id="multiplier">1</span>x | Time: <span id="timer">0</span>s</div>
22
+ <div id="sidebar">
23
+ <h3>High Scores</h3>
24
+ <div id="highScores"></div>
25
+ <button onclick="saveScore()">Save Score</button>
26
+ </div>
27
  <script type="module">
28
  import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
29
 
30
+ let scene, camera, renderer, player, enemies = [], bullets = [], buildings = [];
31
  let clock = new THREE.Clock();
32
  let moveLeft = false, moveRight = false, moveUp = false, moveDown = false, shoot = false;
33
+ let score = 0, multiplier = 1, gameTime = 0, lastHitTime = 0;
34
+ let highScores = JSON.parse(localStorage.getItem('highScores')) || [];
35
 
36
  function init() {
37
  scene = new THREE.Scene();
 
49
  player.position.y = -10;
50
  scene.add(player);
51
 
52
+ spawnFlockingEnemies();
53
+ spawnBuildings();
54
 
55
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
56
  scene.add(ambientLight);
 
59
  window.addEventListener('keyup', onKeyUp);
60
  window.addEventListener('resize', onWindowResize);
61
 
62
+ updateHighScoresUI();
63
  animate();
64
  }
65
 
66
+ function spawnFlockingEnemies() {
67
  const enemyGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
68
  const enemyMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
69
+ for (let i = 0; i < 10; i++) {
70
+ const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
71
+ enemy.position.set(Math.random() * 20 - 10, Math.random() * 10 + 5, 0);
72
+ enemy.velocity = new THREE.Vector3(Math.random() - 0.5, Math.random() - 0.5, 0);
73
+ enemies.push(enemy);
74
+ scene.add(enemy);
 
75
  }
76
  }
77
 
78
+ function spawnBuildings() {
79
+ const primitives = [
80
+ new THREE.BoxGeometry(2, 2, 2),
81
+ new THREE.CylinderGeometry(1, 1, 3, 8),
82
+ new THREE.ConeGeometry(1.5, 2, 8)
83
+ ];
84
+ const material = new THREE.MeshBasicMaterial({ color: 0x808080 });
85
+ for (let i = 0; i < 5; i++) {
86
+ const building = new THREE.Group();
87
+ const height = Math.random() * 3 + 1;
88
+ for (let j = 0; j < height; j++) {
89
+ const primitive = primitives[Math.floor(Math.random() * primitives.length)].clone();
90
+ const segment = new THREE.Mesh(primitive, material);
91
+ segment.position.y = j * 2;
92
+ building.add(segment);
93
+ }
94
+ building.position.set(Math.random() * 30 - 15, -15 + height, 0);
95
+ buildings.push(building);
96
+ scene.add(building);
97
  }
98
  }
99
 
 
160
  enemies.splice(i, 1);
161
  scene.remove(bullet);
162
  bullets.splice(bulletIndex, 1);
163
+ score += 10 * multiplier;
164
+ if (clock.getElapsedTime() - lastHitTime < 2) multiplier += 0.5;
165
+ lastHitTime = clock.getElapsedTime();
166
+ updateUI();
167
+ if (enemies.length < 5) spawnFlockingEnemies();
168
  break;
169
  }
170
  }
171
  }
172
 
173
+ function updateFlockingEnemies(delta) {
174
+ const cohesion = 0.05, separation = 0.1, alignment = 0.05, speed = 2;
175
  enemies.forEach(enemy => {
176
+ let avgPos = new THREE.Vector3(), avgVel = new THREE.Vector3(), separationForce = new THREE.Vector3();
177
+ let neighbors = 0;
178
+
179
+ enemies.forEach(other => {
180
+ if (enemy !== other) {
181
+ const dist = enemy.position.distanceTo(other.position);
182
+ if (dist < 5) {
183
+ avgPos.add(other.position);
184
+ avgVel.add(other.velocity);
185
+ if (dist < 2) separationForce.sub(other.position.clone().sub(enemy.position).normalize().divideScalar(dist));
186
+ neighbors++;
187
+ }
188
+ }
189
+ });
190
+
191
+ if (neighbors > 0) {
192
+ avgPos.divideScalar(neighbors).sub(enemy.position).multiplyScalar(cohesion);
193
+ avgVel.divideScalar(neighbors).sub(enemy.velocity).multiplyScalar(alignment);
194
+ separationForce.multiplyScalar(separation);
195
+ enemy.velocity.add(avgPos).add(avgVel).add(separationForce).clampLength(0, speed);
196
+ }
197
+
198
+ enemy.position.add(enemy.velocity.clone().multiplyScalar(delta));
199
  if (enemy.position.y < -15) enemy.position.y = 15;
200
+ if (enemy.position.x < -15 || enemy.position.x > 15) enemy.velocity.x *= -1;
201
  });
202
  }
203
 
204
+ function updateBuildings(delta) {
205
+ const buildingSpeed = 1;
206
+ buildings.forEach(building => {
207
+ building.position.y += buildingSpeed * delta;
208
+ if (building.position.y > 15) building.position.y = -15;
209
  });
210
  }
211
 
212
+ function updateUI() {
213
+ document.getElementById('score').innerText = score;
214
+ document.getElementById('multiplier').innerText = multiplier.toFixed(1);
215
+ document.getElementById('timer').innerText = Math.floor(gameTime);
216
+ if (clock.getElapsedTime() - lastHitTime > 5) multiplier = 1;
217
+ }
218
+
219
+ function updateHighScoresUI() {
220
+ const scoresDiv = document.getElementById('highScores');
221
+ scoresDiv.innerHTML = highScores.map(s => `${s.name}: ${s.score} (${s.time}s)`).join('<br>');
222
+ }
223
+
224
+ window.saveScore = function() {
225
+ const name = prompt("Enter 3-letter name:", generateRandomName());
226
+ if (name && name.length === 3) {
227
+ highScores.push({ name, score, time: Math.floor(gameTime) });
228
+ highScores.sort((a, b) => b.score - a.score);
229
+ highScores = highScores.slice(0, 5);
230
+ localStorage.setItem('highScores', JSON.stringify(highScores));
231
+ updateHighScoresUI();
232
+ }
233
+ }
234
+
235
+ function generateRandomName() {
236
+ const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
237
+ return Array(3).fill().map(() => letters[Math.floor(Math.random() * letters.length)]).join('');
238
+ }
239
+
240
  function onWindowResize() {
241
  camera.aspect = window.innerWidth / window.innerHeight;
242
  camera.updateProjectionMatrix();
 
246
  function animate() {
247
  requestAnimationFrame(animate);
248
  const delta = clock.getDelta();
249
+ gameTime += delta;
250
 
251
  updatePlayer(delta);
252
  updateBullets(delta);
253
+ updateFlockingEnemies(delta);
254
+ updateBuildings(delta);
255
+ updateUI();
256
 
257
  renderer.render(scene, camera);
258
  }
 
264
  """
265
 
266
  # Streamlit app
267
+ st.title("Galaxxon - Enhanced Arcade Game")
268
+ st.write("Use WASD or Arrow Keys to move, Spacebar to shoot. Destroy red enemies for points! Chain hits for multiplier bonuses.")
269
 
270
  # Render the HTML game
271
  html(game_html, height=600, scrolling=False)