akhaliq HF staff commited on
Commit
bd4669e
·
verified ·
1 Parent(s): 54a9298

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +147 -114
app.py CHANGED
@@ -8,11 +8,11 @@ with demo:
8
  <head>
9
  <meta charset="UTF-8">
10
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
- <title>Hugging Face Game with Pinned Controls</title>
12
  <style>
13
  body { margin: 0; overflow: hidden; }
14
  canvas { display: block; }
15
- #win-message {
16
  position: absolute;
17
  top: 50%;
18
  left: 50%;
@@ -53,17 +53,14 @@ with demo:
53
  </style>
54
  </head>
55
  <body>
56
- <div id="win-message">You Win!</div>
57
- <div id="gpu-counter">GPUs Collected: 0 / 10</div>
58
  <div id="controls">
59
  <p><strong>Controls:</strong></p>
60
- <p>W / Up: Forward</p>
61
- <p>S / Down: Backward</p>
62
- <p>A / Left: Left</p>
63
- <p>D / Right: Right</p>
64
- <p>Space: Up</p>
65
- <p>Shift: Down</p>
66
- <p>Collect all GPUs to win!</p>
67
  </div>
68
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
69
  <script>
@@ -81,35 +78,19 @@ with demo:
81
  const ambientLight = new THREE.AmbientLight(0x87ceeb, 0.5);
82
  scene.add(ambientLight);
83
 
84
- // Morning background
85
  scene.background = new THREE.Color(0x87ceeb);
86
  scene.fog = new THREE.Fog(0x87ceeb, 10, 100);
87
 
88
- // Ground
89
- const groundGeometry = new THREE.PlaneGeometry(100, 100);
90
  const groundMaterial = new THREE.MeshLambertMaterial({ color: 0x8c8c8c });
91
  const ground = new THREE.Mesh(groundGeometry, groundMaterial);
92
  ground.rotation.x = -Math.PI / 2;
 
93
  scene.add(ground);
94
 
95
- // Realistic Buildings
96
- const buildings = [];
97
- const numBuildings = 50;
98
- for (let i = 0; i < numBuildings; i++) {
99
- const width = Math.random() * 5 + 2;
100
- const height = Math.random() * 20 + 10;
101
- const depth = Math.random() * 5 + 2;
102
- const buildingGeometry = new THREE.BoxGeometry(width, height, depth);
103
- const buildingMaterial = new THREE.MeshLambertMaterial({ color: 0xb0b0b0 });
104
- const building = new THREE.Mesh(buildingGeometry, buildingMaterial);
105
- building.position.x = Math.random() * 80 - 40;
106
- building.position.y = height / 2;
107
- building.position.z = Math.random() * 80 - 40;
108
- scene.add(building);
109
- buildings.push(building);
110
- }
111
-
112
- // Hugging Face Emoji
113
  const emojiCanvas = document.createElement('canvas');
114
  emojiCanvas.width = 256;
115
  emojiCanvas.height = 256;
@@ -122,96 +103,94 @@ with demo:
122
  const faceGeometry = new THREE.SphereGeometry(1, 32, 32);
123
  const faceMaterial = new THREE.MeshLambertMaterial({ map: emojiTexture });
124
  const face = new THREE.Mesh(faceGeometry, faceMaterial);
125
- face.position.set(0, 5, 0);
126
  scene.add(face);
127
- face.velocity = new THREE.Vector3(0, 0, 0);
128
- face.maxSpeed = 25;
129
- face.acceleration = new THREE.Vector3(0, 0, 0);
130
- face.friction = 0.95;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  // Audio setup
133
  const listener = new THREE.AudioListener();
134
  camera.add(listener);
135
-
136
- // Background music (ambient wind-like sound)
137
- const bgSound = new THREE.Audio(listener);
138
- const audioLoader = new THREE.AudioLoader();
139
- const bgAudioData = 'data:audio/mp3;base64,' + btoa(String.fromCharCode(...new Uint8Array([/* Simulated wind sound MP3 data would go here */])));
140
- audioLoader.load(bgAudioData || 'https://threejs.org/examples/sounds/358232_j_s_song.mp3', function(buffer) {
141
- bgSound.setBuffer(buffer);
142
- bgSound.setLoop(true);
143
- bgSound.setVolume(0.2);
144
- bgSound.play();
145
- });
146
-
147
- // GPU collect sound (positional, ping-like)
148
  const collectSound = new THREE.PositionalAudio(listener);
149
  face.add(collectSound);
 
150
  audioLoader.load('https://threejs.org/examples/sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3', function(buffer) {
151
  collectSound.setBuffer(buffer);
152
  collectSound.setRefDistance(10);
153
  collectSound.setVolume(0.5);
154
  });
155
 
156
- // "GPU" Texts
157
- const canvas = document.createElement('canvas');
158
- canvas.width = 128;
159
- canvas.height = 128;
160
- const ctx = canvas.getContext('2d');
161
- ctx.font = '48px Arial';
162
- ctx.fillStyle = 'white';
163
- ctx.textAlign = 'center';
164
- ctx.textBaseline = 'middle';
165
- ctx.fillText('GPU', 64, 64);
166
- const texture = new THREE.CanvasTexture(canvas);
167
- const gpuSprites = [];
168
- const totalGPUs = 10;
169
- let collectedGPUs = 0;
170
- for (let i = 0; i < totalGPUs; i++) {
171
- const spriteMaterial = new THREE.SpriteMaterial({ map: texture });
172
- const sprite = new THREE.Sprite(spriteMaterial);
173
- sprite.scale.set(2, 2, 1);
174
- sprite.position.set(Math.random() * 80 - 40, Math.random() * 20 + 10, Math.random() * 80 - 40);
175
- scene.add(sprite);
176
- gpuSprites.push(sprite);
177
- }
178
-
179
- // Clock for smooth animation
180
  const clock = new THREE.Clock();
181
-
182
- // Win condition and counter
183
- const winMessage = document.getElementById('win-message');
184
  const gpuCounter = document.getElementById('gpu-counter');
185
- let gameWon = false;
 
186
 
187
- // Keyboard controls
188
  const keys = {};
189
- window.addEventListener('keydown', (e) => { keys[e.key] = true; });
190
  window.addEventListener('keyup', (e) => { keys[e.key] = false; });
191
 
192
- function handleControls(deltaTime) {
193
- const accel = 50;
194
- face.acceleration.set(0, 0, 0);
195
-
196
- if (keys['w'] || keys['ArrowUp']) face.acceleration.z = -accel;
197
- if (keys['s'] || keys['ArrowDown']) face.acceleration.z = accel;
198
- if (keys['a'] || keys['ArrowLeft']) face.acceleration.x = -accel;
199
- if (keys['d'] || keys['ArrowRight']) face.acceleration.x = accel;
200
- if (keys[' ']) face.acceleration.y = accel;
201
- if (keys['Shift']) face.acceleration.y = -accel;
202
-
203
- face.velocity.add(face.acceleration.clone().multiplyScalar(deltaTime));
204
- face.velocity.multiplyScalar(face.friction);
205
- face.velocity.clampLength(0, face.maxSpeed);
206
- face.position.add(face.velocity.clone().multiplyScalar(deltaTime));
207
-
208
- if (face.velocity.length() > 0.1) {
209
- face.lookAt(face.position.clone().add(face.velocity));
 
210
  }
 
211
 
212
- face.position.x = Math.max(-50, Math.min(50, face.position.x));
213
- face.position.z = Math.max(-50, Math.min(50, face.position.z));
214
- face.position.y = Math.max(1, Math.min(50, face.position.y));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  }
216
 
217
  // Animation loop
@@ -219,31 +198,85 @@ with demo:
219
  requestAnimationFrame(animate);
220
  const deltaTime = clock.getDelta();
221
 
222
- if (!gameWon) {
223
- handleControls(deltaTime);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
 
225
  gpuSprites.forEach((gpu, index) => {
226
- if (face.position.distanceTo(gpu.position) < 1) {
 
227
  scene.remove(gpu);
228
  gpuSprites.splice(index, 1);
229
  collectedGPUs++;
230
- gpuCounter.textContent = `GPUs Collected: ${collectedGPUs} / ${totalGPUs}`;
231
- collectSound.play(); // Play positional sound
232
- if (collectedGPUs === totalGPUs) {
233
- gameWon = true;
234
- winMessage.style.display = 'block';
235
- face.velocity.set(0, 0, 0);
236
- bgSound.stop();
237
- }
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
239
  });
 
 
 
 
240
  }
241
 
242
- camera.position.set(face.position.x, face.position.y + 5, face.position.z - 10);
243
- camera.lookAt(face.position);
244
  renderer.render(scene, camera);
245
  }
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  animate();
248
 
249
  // Handle window resize
 
8
  <head>
9
  <meta charset="UTF-8">
10
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
+ <title>Hugging Face Temple Run</title>
12
  <style>
13
  body { margin: 0; overflow: hidden; }
14
  canvas { display: block; }
15
+ #game-over-message {
16
  position: absolute;
17
  top: 50%;
18
  left: 50%;
 
53
  </style>
54
  </head>
55
  <body>
56
+ <div id="game-over-message">Game Over!<br>Click to Restart</div>
57
+ <div id="gpu-counter">GPUs Collected: 0</div>
58
  <div id="controls">
59
  <p><strong>Controls:</strong></p>
60
+ <p>A / Left / Swipe Left: Move Left</p>
61
+ <p>D / Right / Swipe Right: Move Right</p>
62
+ <p>Space / Swipe Up: Jump</p>
63
+ <p>Avoid obstacles, collect GPUs!</p>
 
 
 
64
  </div>
65
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
66
  <script>
 
78
  const ambientLight = new THREE.AmbientLight(0x87ceeb, 0.5);
79
  scene.add(ambientLight);
80
 
81
+ // Background
82
  scene.background = new THREE.Color(0x87ceeb);
83
  scene.fog = new THREE.Fog(0x87ceeb, 10, 100);
84
 
85
+ // Ground (endless path)
86
+ const groundGeometry = new THREE.PlaneGeometry(20, 1000);
87
  const groundMaterial = new THREE.MeshLambertMaterial({ color: 0x8c8c8c });
88
  const ground = new THREE.Mesh(groundGeometry, groundMaterial);
89
  ground.rotation.x = -Math.PI / 2;
90
+ ground.position.z = -500; // Extend far into distance
91
  scene.add(ground);
92
 
93
+ // Player (Hugging Face Emoji)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  const emojiCanvas = document.createElement('canvas');
95
  emojiCanvas.width = 256;
96
  emojiCanvas.height = 256;
 
103
  const faceGeometry = new THREE.SphereGeometry(1, 32, 32);
104
  const faceMaterial = new THREE.MeshLambertMaterial({ map: emojiTexture });
105
  const face = new THREE.Mesh(faceGeometry, faceMaterial);
106
+ face.position.set(0, 1, 0);
107
  scene.add(face);
108
+ face.velocity = new THREE.Vector3(0, 0, -10); // Constant forward speed
109
+ face.lane = 0; // -1 (left), 0 (center), 1 (right)
110
+ face.jumping = false;
111
+
112
+ // Collectibles (GPUs)
113
+ const gpuCanvas = document.createElement('canvas');
114
+ gpuCanvas.width = 128;
115
+ gpuCanvas.height = 128;
116
+ const gpuCtx = gpuCanvas.getContext('2d');
117
+ gpuCtx.font = '48px Arial';
118
+ gpuCtx.fillStyle = 'white';
119
+ gpuCtx.textAlign = 'center';
120
+ gpuCtx.textBaseline = 'middle';
121
+ gpuCtx.fillText('GPU', 64, 64);
122
+ const gpuTexture = new THREE.CanvasTexture(gpuCanvas);
123
+ const gpuSprites = [];
124
+ let collectedGPUs = 0;
125
+
126
+ // Obstacles
127
+ const obstacles = [];
128
+ const obstacleGeometry = new THREE.BoxGeometry(2, 2, 2);
129
+ const obstacleMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 });
130
 
131
  // Audio setup
132
  const listener = new THREE.AudioListener();
133
  camera.add(listener);
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  const collectSound = new THREE.PositionalAudio(listener);
135
  face.add(collectSound);
136
+ const audioLoader = new THREE.AudioLoader();
137
  audioLoader.load('https://threejs.org/examples/sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3', function(buffer) {
138
  collectSound.setBuffer(buffer);
139
  collectSound.setRefDistance(10);
140
  collectSound.setVolume(0.5);
141
  });
142
 
143
+ // Clock and game state
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  const clock = new THREE.Clock();
 
 
 
145
  const gpuCounter = document.getElementById('gpu-counter');
146
+ const gameOverMessage = document.getElementById('game-over-message');
147
+ let gameOver = false;
148
 
149
+ // Keyboard and touch controls
150
  const keys = {};
151
+ window.addEventListener('keydown', (e) => { if (!gameOver) keys[e.key] = true; });
152
  window.addEventListener('keyup', (e) => { keys[e.key] = false; });
153
 
154
+ let touchStartX = 0;
155
+ let touchStartY = 0;
156
+ window.addEventListener('touchstart', (e) => {
157
+ touchStartX = e.touches[0].clientX;
158
+ touchStartY = e.touches[0].clientY;
159
+ });
160
+ window.addEventListener('touchmove', (e) => {
161
+ if (gameOver) return;
162
+ const deltaX = e.touches[0].clientX - touchStartX;
163
+ const deltaY = e.touches[0].clientY - touchStartY;
164
+ if (Math.abs(deltaX) > 50) {
165
+ if (deltaX > 0 && face.lane < 1) face.lane++;
166
+ else if (deltaX < 0 && face.lane > -1) face.lane--;
167
+ touchStartX = e.touches[0].clientX;
168
+ }
169
+ if (deltaY < -50 && !face.jumping) {
170
+ face.jumping = true;
171
+ face.velocity.y = 15;
172
+ touchStartY = e.touches[0].clientY;
173
  }
174
+ });
175
 
176
+ // Spawn collectibles and obstacles
177
+ function spawnItems() {
178
+ if (Math.random() < 0.05) { // Spawn GPU
179
+ const spriteMaterial = new THREE.SpriteMaterial({ map: gpuTexture });
180
+ const sprite = new THREE.Sprite(spriteMaterial);
181
+ sprite.scale.set(2, 2, 1);
182
+ const lane = Math.floor(Math.random() * 3) - 1;
183
+ sprite.position.set(lane * 4, 1, face.position.z - 50);
184
+ scene.add(sprite);
185
+ gpuSprites.push(sprite);
186
+ }
187
+ if (Math.random() < 0.03) { // Spawn obstacle
188
+ const obstacle = new THREE.Mesh(obstacleGeometry, obstacleMaterial);
189
+ const lane = Math.floor(Math.random() * 3) - 1;
190
+ obstacle.position.set(lane * 4, 1, face.position.z - 50);
191
+ scene.add(obstacle);
192
+ obstacles.push(obstacle);
193
+ }
194
  }
195
 
196
  // Animation loop
 
198
  requestAnimationFrame(animate);
199
  const deltaTime = clock.getDelta();
200
 
201
+ if (!gameOver) {
202
+ // Move player
203
+ face.position.z += face.velocity.z * deltaTime;
204
+ face.position.x = face.lane * 4; // Snap to lane
205
+ if (face.jumping) {
206
+ face.position.y += face.velocity.y * deltaTime;
207
+ face.velocity.y -= 30 * deltaTime; // Gravity
208
+ if (face.position.y <= 1) {
209
+ face.position.y = 1;
210
+ face.jumping = false;
211
+ face.velocity.y = 0;
212
+ }
213
+ }
214
+
215
+ // Handle controls
216
+ if (keys['a'] || keys['ArrowLeft']) if (face.lane > -1) face.lane--;
217
+ if (keys['d'] || keys['ArrowRight']) if (face.lane < 1) face.lane++;
218
+ if ((keys[' '] || keys['ArrowUp']) && !face.jumping) {
219
+ face.jumping = true;
220
+ face.velocity.y = 15;
221
+ }
222
+
223
+ // Spawn items
224
+ spawnItems();
225
 
226
+ // Update collectibles
227
  gpuSprites.forEach((gpu, index) => {
228
+ gpu.position.z += 10 * deltaTime; // Move toward player
229
+ if (face.position.distanceTo(gpu.position) < 2) {
230
  scene.remove(gpu);
231
  gpuSprites.splice(index, 1);
232
  collectedGPUs++;
233
+ gpuCounter.textContent = `GPUs Collected: ${collectedGPUs}`;
234
+ collectSound.play();
235
+ }
236
+ if (gpu.position.z > face.position.z + 10) {
237
+ scene.remove(gpu);
238
+ gpuSprites.splice(index, 1);
239
+ }
240
+ });
241
+
242
+ // Update obstacles
243
+ obstacles.forEach((obstacle, index) => {
244
+ obstacle.position.z += 10 * deltaTime;
245
+ if (face.position.distanceTo(obstacle.position) < 2) {
246
+ gameOver = true;
247
+ gameOverMessage.style.display = 'block';
248
+ face.velocity.z = 0;
249
+ }
250
+ if (obstacle.position.z > face.position.z + 10) {
251
+ scene.remove(obstacle);
252
+ obstacles.splice(index, 1);
253
  }
254
  });
255
+
256
+ // Update camera
257
+ camera.position.set(face.position.x, face.position.y + 5, face.position.z + 10);
258
+ camera.lookAt(face.position);
259
  }
260
 
 
 
261
  renderer.render(scene, camera);
262
  }
263
 
264
+ // Restart game
265
+ gameOverMessage.addEventListener('click', () => {
266
+ if (gameOver) {
267
+ gameOver = false;
268
+ gameOverMessage.style.display = 'none';
269
+ face.position.set(0, 1, 0);
270
+ face.velocity.z = -10;
271
+ collectedGPUs = 0;
272
+ gpuCounter.textContent = `GPUs Collected: 0`;
273
+ gpuSprites.forEach(gpu => scene.remove(gpu));
274
+ obstacles.forEach(obstacle => scene.remove(obstacle));
275
+ gpuSprites.length = 0;
276
+ obstacles.length = 0;
277
+ }
278
+ });
279
+
280
  animate();
281
 
282
  // Handle window resize