awacke1 commited on
Commit
cb20913
·
verified ·
1 Parent(s): 948c597

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -38
app.py CHANGED
@@ -31,10 +31,10 @@ game_html = """
31
  <script type="module">
32
  import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
33
 
34
- let scene, camera, renderer, snake, foodItems = [], lSysCreatures = [], messages = [];
35
  let clock = new THREE.Clock();
36
- let moveDir = new THREE.Vector3(1, 0, 0), moveSpeed = 0.2;
37
- let score = 0, gameTime = 0, lives = 3;
38
  let highScores = JSON.parse(localStorage.getItem('highScores')) || [];
39
  let gameOver = false;
40
 
@@ -45,21 +45,14 @@ game_html = """
45
  renderer.setSize(window.innerWidth, window.innerHeight);
46
  document.body.appendChild(renderer.domElement);
47
 
48
- camera.position.set(0, 20, 30);
49
  camera.lookAt(0, 0, 0);
50
 
51
  // Initialize 3D snake
52
- snake = [];
53
- const snakeMaterial = new THREE.MeshPhongMaterial({ color: 0x00ff00, shininess: 100 });
54
- for (let i = 0; i < 3; i++) {
55
- const segment = new THREE.Mesh(new THREE.SphereGeometry(0.5, 16, 16), snakeMaterial);
56
- segment.position.set(-i * 1.2, 0, 0);
57
- snake.push(segment);
58
- scene.add(segment);
59
- }
60
 
61
  spawnFood();
62
- spawnLSysCreatures();
63
 
64
  const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
65
  scene.add(ambientLight);
@@ -97,30 +90,34 @@ game_html = """
97
  }
98
  }
99
 
100
- function spawnLSysCreatures() {
101
  const lSys = {
102
  axiom: "F",
103
- rules: { "F": "F[+F]F[-F]F" },
104
- angle: 25,
105
- length: 2,
106
- iterations: 3
107
  };
108
- const material = new THREE.MeshPhongMaterial({ color: 0x0000ff });
109
- for (let i = 0; i < 3; i++) {
110
  let turtleString = lSys.axiom;
111
  for (let j = 0; j < lSys.iterations; j++) {
112
  turtleString = turtleString.split('').map(c => lSys.rules[c] || c).join('');
113
  }
114
- const creature = new THREE.Group();
115
  let stack = [], pos = new THREE.Vector3((Math.random() - 0.5) * 40, 0, (Math.random() - 0.5) * 40);
116
  let dir = new THREE.Vector3(0, lSys.length, 0);
117
 
118
  for (let char of turtleString) {
119
  if (char === 'F') {
120
- const segment = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, lSys.length, 8), material);
 
 
 
 
121
  segment.position.copy(pos).add(dir.clone().multiplyScalar(0.5));
122
  segment.quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir.clone().normalize());
123
- creature.add(segment);
124
  pos.add(dir);
125
  } else if (char === '+') {
126
  dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), lSys.angle * Math.PI / 180);
@@ -134,15 +131,56 @@ game_html = """
134
  dir = state.dir;
135
  }
136
  }
137
- creature.position.set(pos.x, 0, pos.z);
138
- lSysCreatures.push(creature);
139
- scene.add(creature);
140
- sendQuineMessage(creature);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
 
 
 
 
142
  }
143
 
144
  function sendQuineMessage(sender) {
145
- const quine = "function q(){alert('I am alive! '+q.toString())}q()";
146
  const messageDiv = document.createElement('div');
147
  messageDiv.className = 'message';
148
  messageDiv.innerText = 'Quine Msg';
@@ -170,18 +208,22 @@ game_html = """
170
  }
171
  if (gameOver) return;
172
  switch (event.code) {
173
- case 'ArrowLeft': case 'KeyA': moveDir.set(-1, 0, 0); break;
174
- case 'ArrowRight': case 'KeyD': moveDir.set(1, 0, 0); break;
175
- case 'ArrowUp': case 'KeyW': moveDir.set(0, 0, -1); break;
176
- case 'ArrowDown': case 'KeyS': moveDir.set(0, 0, 1); break;
177
  }
178
  }
179
 
180
  function updateSnake(delta) {
181
  if (gameOver) return;
 
 
 
 
182
  const head = snake[0];
183
  const newHead = new THREE.Mesh(head.geometry, head.material);
184
- newHead.position.copy(head.position).add(moveDir.clone().multiplyScalar(moveSpeed));
185
 
186
  // Boundary check
187
  if (Math.abs(newHead.position.x) > 20 || Math.abs(newHead.position.z) > 20) {
@@ -197,6 +239,14 @@ game_html = """
197
  }
198
  }
199
 
 
 
 
 
 
 
 
 
200
  snake.unshift(newHead);
201
  scene.add(newHead);
202
 
@@ -207,11 +257,11 @@ game_html = """
207
  foodItems.splice(i, 1);
208
  score += 10;
209
  spawnFood(); // Add new food
210
- spawnLSysCreatures(); // Add new creature
211
  break;
212
  } else {
213
- snake.pop(); // Remove tail if no food eaten
214
- scene.remove(snake[snake.length - 1]);
215
  }
216
  }
217
 
@@ -266,13 +316,16 @@ game_html = """
266
  resetSnake();
267
  foodItems.forEach(f => scene.remove(f));
268
  lSysCreatures.forEach(c => scene.remove(c));
 
269
  foodItems = [];
270
  lSysCreatures = [];
 
271
  spawnFood();
272
- spawnLSysCreatures();
273
  score = 0;
274
  lives = 3;
275
  gameOver = false;
 
276
  updateUI();
277
  }
278
 
@@ -338,7 +391,7 @@ with st.sidebar:
338
  st.write("- R to reset after game over")
339
  st.write("**Objective:**")
340
  st.write("- Eat alien food (pink dodecahedrons) to grow")
341
- st.write("- Avoid L-system creatures (blue structures)")
342
  st.write("- Watch creatures exchange quine messages")
343
 
344
  # Render the HTML game
 
31
  <script type="module">
32
  import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
33
 
34
+ let scene, camera, renderer, snake, foodItems = [], lSysCreatures = [], messages = [], cityscape = [];
35
  let clock = new THREE.Clock();
36
+ let moveDir = new THREE.Vector3(1, 0, 0), moveSpeed = 2; // Adjusted speed for visibility
37
+ let score = 0, gameTime = 0, lives = 3, moveCounter = 0, moveInterval = 0.1; // Ticker interval in seconds
38
  let highScores = JSON.parse(localStorage.getItem('highScores')) || [];
39
  let gameOver = false;
40
 
 
45
  renderer.setSize(window.innerWidth, window.innerHeight);
46
  document.body.appendChild(renderer.domElement);
47
 
48
+ camera.position.set(0, 30, 40);
49
  camera.lookAt(0, 0, 0);
50
 
51
  // Initialize 3D snake
52
+ resetSnake();
 
 
 
 
 
 
 
53
 
54
  spawnFood();
55
+ spawnCityscape();
56
 
57
  const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
58
  scene.add(ambientLight);
 
90
  }
91
  }
92
 
93
+ function spawnCityscape() {
94
  const lSys = {
95
  axiom: "F",
96
+ rules: { "F": "F[+F]F[-F][F]" },
97
+ angle: 30,
98
+ length: 3,
99
+ iterations: 2
100
  };
101
+ const material = new THREE.MeshPhongMaterial({ color: 0x808080 });
102
+ for (let i = 0; i < 10; i++) {
103
  let turtleString = lSys.axiom;
104
  for (let j = 0; j < lSys.iterations; j++) {
105
  turtleString = turtleString.split('').map(c => lSys.rules[c] || c).join('');
106
  }
107
+ const building = new THREE.Group();
108
  let stack = [], pos = new THREE.Vector3((Math.random() - 0.5) * 40, 0, (Math.random() - 0.5) * 40);
109
  let dir = new THREE.Vector3(0, lSys.length, 0);
110
 
111
  for (let char of turtleString) {
112
  if (char === 'F') {
113
+ const height = Math.random() * 2 + 1;
114
+ const segment = new THREE.Mesh(
115
+ Math.random() > 0.5 ? new THREE.BoxGeometry(1, height, 1) : new THREE.CylinderGeometry(0.5, 0.5, height, 8),
116
+ material
117
+ );
118
  segment.position.copy(pos).add(dir.clone().multiplyScalar(0.5));
119
  segment.quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir.clone().normalize());
120
+ building.add(segment);
121
  pos.add(dir);
122
  } else if (char === '+') {
123
  dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), lSys.angle * Math.PI / 180);
 
131
  dir = state.dir;
132
  }
133
  }
134
+ building.position.set(pos.x, 0, pos.z);
135
+ cityscape.push(building);
136
+ scene.add(building);
137
+ if (Math.random() > 0.7) spawnLSysCreature(building.position);
138
+ }
139
+ }
140
+
141
+ function spawnLSysCreature(position) {
142
+ const lSys = {
143
+ axiom: "F",
144
+ rules: { "F": "F[+F]F[-F]F" },
145
+ angle: 25,
146
+ length: 2,
147
+ iterations: 2
148
+ };
149
+ const material = new THREE.MeshPhongMaterial({ color: 0x0000ff });
150
+ let turtleString = lSys.axiom;
151
+ for (let j = 0; j < lSys.iterations; j++) {
152
+ turtleString = turtleString.split('').map(c => lSys.rules[c] || c).join('');
153
+ }
154
+ const creature = new THREE.Group();
155
+ let stack = [], pos = position.clone(), dir = new THREE.Vector3(0, lSys.length, 0);
156
+
157
+ for (let char of turtleString) {
158
+ if (char === 'F') {
159
+ const segment = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, lSys.length, 8), material);
160
+ segment.position.copy(pos).add(dir.clone().multiplyScalar(0.5));
161
+ segment.quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir.clone().normalize());
162
+ creature.add(segment);
163
+ pos.add(dir);
164
+ } else if (char === '+') {
165
+ dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), lSys.angle * Math.PI / 180);
166
+ } else if (char === '-') {
167
+ dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), -lSys.angle * Math.PI / 180);
168
+ } else if (char === '[') {
169
+ stack.push({ pos: pos.clone(), dir: dir.clone() });
170
+ } else if (char === ']') {
171
+ const state = stack.pop();
172
+ pos = state.pos;
173
+ dir = state.dir;
174
+ }
175
  }
176
+ creature.position.copy(position);
177
+ lSysCreatures.push(creature);
178
+ scene.add(creature);
179
+ sendQuineMessage(creature);
180
  }
181
 
182
  function sendQuineMessage(sender) {
183
+ const quine = "function q(){console.log('Alive! '+q.toString())}q()";
184
  const messageDiv = document.createElement('div');
185
  messageDiv.className = 'message';
186
  messageDiv.innerText = 'Quine Msg';
 
208
  }
209
  if (gameOver) return;
210
  switch (event.code) {
211
+ case 'ArrowLeft': case 'KeyA': if (moveDir.x !== 1) moveDir.set(-1, 0, 0); break;
212
+ case 'ArrowRight': case 'KeyD': if (moveDir.x !== -1) moveDir.set(1, 0, 0); break;
213
+ case 'ArrowUp': case 'KeyW': if (moveDir.z !== 1) moveDir.set(0, 0, -1); break;
214
+ case 'ArrowDown': case 'KeyS': if (moveDir.z !== -1) moveDir.set(0, 0, 1); break;
215
  }
216
  }
217
 
218
  function updateSnake(delta) {
219
  if (gameOver) return;
220
+ moveCounter += delta;
221
+ if (moveCounter < moveInterval) return;
222
+ moveCounter = 0;
223
+
224
  const head = snake[0];
225
  const newHead = new THREE.Mesh(head.geometry, head.material);
226
+ newHead.position.copy(head.position).add(moveDir.clone().multiplyScalar(1)); // Move by 1 unit
227
 
228
  // Boundary check
229
  if (Math.abs(newHead.position.x) > 20 || Math.abs(newHead.position.z) > 20) {
 
239
  }
240
  }
241
 
242
+ // Cityscape collision
243
+ for (let building of cityscape) {
244
+ if (newHead.position.distanceTo(building.position) < 2) {
245
+ loseLife();
246
+ return;
247
+ }
248
+ }
249
+
250
  snake.unshift(newHead);
251
  scene.add(newHead);
252
 
 
257
  foodItems.splice(i, 1);
258
  score += 10;
259
  spawnFood(); // Add new food
260
+ if (Math.random() > 0.8) spawnLSysCreature(newHead.position.clone());
261
  break;
262
  } else {
263
+ const tail = snake.pop();
264
+ scene.remove(tail);
265
  }
266
  }
267
 
 
316
  resetSnake();
317
  foodItems.forEach(f => scene.remove(f));
318
  lSysCreatures.forEach(c => scene.remove(c));
319
+ cityscape.forEach(b => scene.remove(b));
320
  foodItems = [];
321
  lSysCreatures = [];
322
+ cityscape = [];
323
  spawnFood();
324
+ spawnCityscape();
325
  score = 0;
326
  lives = 3;
327
  gameOver = false;
328
+ moveCounter = 0;
329
  updateUI();
330
  }
331
 
 
391
  st.write("- R to reset after game over")
392
  st.write("**Objective:**")
393
  st.write("- Eat alien food (pink dodecahedrons) to grow")
394
+ st.write("- Avoid cityscape buildings and L-system creatures")
395
  st.write("- Watch creatures exchange quine messages")
396
 
397
  # Render the HTML game