akhaliq HF staff commited on
Commit
bb13fe7
·
verified ·
1 Parent(s): c5346bc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +223 -218
app.py CHANGED
@@ -1,230 +1,235 @@
1
  import gradio as gr
2
 
3
- gr.HTML("""<!DOCTYPE html>
4
- <html>
5
- <head>
6
- <title>Maze Game Demo</title>
7
- <style>
8
- body { margin: 0; overflow: hidden; }
9
- #debug {
10
- position: absolute;
11
- top: 10px;
12
- left: 10px;
13
- color: white;
14
- background: rgba(0, 0, 0, 0.7);
15
- padding: 5px;
16
- font-family: monospace;
17
- }
18
- </style>
19
- </head>
20
- <body>
21
- <div id="debug"></div>
22
- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
23
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
24
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
25
- <script>
26
- // Scene setup
27
- const scene = new THREE.Scene();
28
- const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
29
- const renderer = new THREE.WebGLRenderer();
30
- renderer.setSize(window.innerWidth, window.innerHeight);
31
- document.body.appendChild(renderer.domElement);
32
-
33
- // Lighting
34
- const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.6);
35
- scene.add(hemiLight);
36
- const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
37
- dirLight.position.set(0, 20, 10);
38
- scene.add(dirLight);
39
-
40
- // OrbitControls
41
- const controls = new THREE.OrbitControls(camera, renderer.domElement);
42
- controls.enableDamping = true;
43
-
44
- // Maze generation
45
- const gridSize = 16;
46
- const cellSize = 4;
47
- const maze = [];
48
- const walls = [];
49
-
50
- function createTexture(width, height, type) {
51
- const canvas = document.createElement('canvas');
52
- canvas.width = width;
53
- canvas.height = height;
54
- const ctx = canvas.getContext('2d');
55
-
56
- if (type === 'floor') {
57
- ctx.fillStyle = '#8B4513';
58
- ctx.fillRect(0, 0, width, height);
59
- ctx.strokeStyle = '#654321';
60
- ctx.lineWidth = 2;
61
- ctx.strokeRect(0, 0, width, height);
62
- } else {
63
- ctx.fillStyle = '#666666';
64
- ctx.fillRect(0, 0, width, height);
65
- for (let i = 0; i < 10; i++) {
66
- ctx.fillStyle = `rgba(0, 0, 0, ${Math.random() * 0.3})`;
67
- ctx.fillRect(
68
- Math.random() * width,
69
- Math.random() * height,
70
- Math.random() * width/4,
71
- Math.random() * height/4
72
- );
73
- }
74
- }
75
- return new THREE.CanvasTexture(canvas);
76
- }
77
-
78
- const floorTexture = createTexture(256, 256, 'floor');
79
- const wallTexture = createTexture(256, 256, 'wall');
80
-
81
- // Generate maze
82
- for (let x = 0; x < gridSize; x++) {
83
- maze[x] = [];
84
- for (let z = 0; z < gridSize; z++) {
85
- const isBoundary = x === 0 || x === gridSize - 1 || z === 0 || z === gridSize - 1;
86
- const isCenter = x >= 6 && x <= 9 && z >= 6 && z <= 9;
87
- const isWall = isBoundary || (!isCenter && Math.random() < 0.15);
88
- maze[x][z] = isWall ? 1 : 0;
89
-
90
- if (isWall) {
91
- const wallGeometry = new THREE.BoxGeometry(cellSize, cellSize, cellSize);
92
- const wallMaterial = new THREE.MeshPhongMaterial({ map: wallTexture });
93
- const wall = new THREE.Mesh(wallGeometry, wallMaterial);
94
- wall.position.set(x * cellSize, cellSize/2, z * cellSize);
95
- scene.add(wall);
96
- wall.boundingBox = new THREE.Box3().setFromObject(wall);
97
- walls.push(wall);
98
- }
99
  }
100
- }
101
-
102
- // Floor
103
- const floorGeometry = new THREE.PlaneGeometry(gridSize * cellSize, gridSize * cellSize);
104
- const floorMaterial = new THREE.MeshPhongMaterial({ map: floorTexture });
105
- const floor = new THREE.Mesh(floorGeometry, floorMaterial);
106
- floor.rotation.x = -Math.PI / 2;
107
- scene.add(floor);
108
-
109
- // Soldier setup
110
- const loader = new THREE.GLTFLoader();
111
- const soldiers = [];
112
- const mixers = [];
113
-
114
- function createSoldier(team, startX, startZ) {
115
- loader.load('https://threejs.org/examples/models/gltf/Soldier.glb', (gltf) => {
116
- const soldier = gltf.scene;
117
- soldier.scale.set(2, 2, 2);
118
- soldier.position.set(startX, 0, startZ);
119
- soldier.team = team;
120
- soldier.collisionRadius = 1;
121
- soldier.speed = 0.1;
122
- scene.add(soldier);
123
- soldiers.push(soldier);
124
-
125
- const mixer = new THREE.AnimationMixer(soldier);
126
- mixers.push(mixer);
127
-
128
- const idleAction = mixer.clipAction(gltf.animations[0]);
129
- const runAction = mixer.clipAction(gltf.animations[3]);
 
 
 
 
 
 
 
130
 
131
- soldier.actions = { idle: idleAction, run: runAction };
132
- idleAction.play();
133
- });
134
- }
135
-
136
- // Create two teams
137
- createSoldier(1, 28, 28); // Team 1
138
- createSoldier(2, 36, 36); // Team 2
139
-
140
- camera.position.set(32, 20, 32);
141
-
142
- // Movement controls
143
- const keys = { w: false, a: false, s: false, d: false };
144
- document.addEventListener('keydown', (e) => {
145
- if (e.key in keys) keys[e.key] = true;
146
- });
147
- document.addEventListener('keyup', (e) => {
148
- if (e.key in keys) keys[e.key] = false;
149
- });
150
-
151
- function checkCollision(newPosition, soldier) {
152
- const soldierBox = new THREE.Sphere(newPosition, soldier.collisionRadius);
153
- for (const wall of walls) {
154
- if (soldierBox.intersectsBox(wall.boundingBox)) {
155
- return true;
156
  }
 
157
  }
158
- return false;
159
- }
160
-
161
- // Animation loop
162
- const clock = new THREE.Clock();
163
- function animate() {
164
- requestAnimationFrame(animate);
165
- const delta = clock.getDelta();
166
-
167
- soldiers.forEach((soldier, index) => {
168
- if (!soldier) return;
169
-
170
- const moveDirection = new THREE.Vector3();
171
- if (index === 0) { // Only control first soldier for demo
172
- const camForward = new THREE.Vector3();
173
- camera.getWorldDirection(camForward);
174
- camForward.y = 0;
175
- camForward.normalize();
176
- const camLeft = new THREE.Vector3(-camForward.z, 0, camForward.x);
177
-
178
- if (keys.w) moveDirection.add(camForward);
179
- if (keys.s) moveDirection.sub(camForward);
180
- if (keys.a) moveDirection.add(camLeft);
181
- if (keys.d) moveDirection.sub(camLeft);
182
  }
183
-
184
- if (moveDirection.length() > 0) {
185
- moveDirection.normalize();
186
- const newPosition = soldier.position.clone()
187
- .add(moveDirection.multiplyScalar(soldier.speed));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
 
189
- if (!checkCollision(newPosition, soldier)) {
190
- soldier.position.copy(newPosition);
191
- const angle = Math.atan2(moveDirection.x, moveDirection.z);
192
- soldier.rotation.y = angle + Math.PI;
193
-
194
- soldier.actions.idle.fadeOut(0.2);
195
- soldier.actions.run.fadeIn(0.2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
197
- } else {
198
- soldier.actions.run.fadeOut(0.2);
199
- soldier.actions.idle.fadeIn(0.2);
200
- }
201
-
202
- if (index === 0) {
203
- controls.target.copy(soldier.position);
204
- controls.update();
205
-
206
- // Update debug overlay
207
- document.getElementById('debug').innerHTML = `
208
- Position: ${soldier.position.x.toFixed(2)},
209
- ${soldier.position.y.toFixed(2)},
210
- ${soldier.position.z.toFixed(2)}<br>
211
- Rotation: ${(soldier.rotation.y * 180 / Math.PI).toFixed(2)}°
212
- `;
213
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  });
 
 
 
 
 
215
 
216
- mixers.forEach(mixer => mixer.update(delta));
217
- renderer.render(scene, camera);
218
- }
219
-
220
- // Responsive design
221
- window.addEventListener('resize', () => {
222
- camera.aspect = window.innerWidth / window.innerHeight;
223
- camera.updateProjectionMatrix();
224
- renderer.setSize(window.innerWidth, window.innerHeight);
225
- });
226
-
227
- animate();
228
- </script>
229
- </body>
230
- </html>""").launch()
 
1
  import gradio as gr
2
 
3
+ demo = gr.Blocks()
4
+
5
+ with demo:
6
+ gr.HTML("""<!DOCTYPE html>
7
+ <html>
8
+ <head>
9
+ <title>Maze Game Demo</title>
10
+ <style>
11
+ body { margin: 0; overflow: hidden; }
12
+ #debug {
13
+ position: absolute;
14
+ top: 10px;
15
+ left: 10px;
16
+ color: white;
17
+ background: rgba(0, 0, 0, 0.7);
18
+ padding: 5px;
19
+ font-family: monospace;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
+ </style>
22
+ </head>
23
+ <body>
24
+ <div id="debug"></div>
25
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
26
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
27
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
28
+ <script>
29
+ // Scene setup
30
+ const scene = new THREE.Scene();
31
+ const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
32
+ const renderer = new THREE.WebGLRenderer();
33
+ renderer.setSize(window.innerWidth, window.innerHeight);
34
+ document.body.appendChild(renderer.domElement);
35
+
36
+ // Lighting
37
+ const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.6);
38
+ scene.add(hemiLight);
39
+ const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
40
+ dirLight.position.set(0, 20, 10);
41
+ scene.add(dirLight);
42
+
43
+ // OrbitControls
44
+ const controls = new THREE.OrbitControls(camera, renderer.domElement);
45
+ controls.enableDamping = true;
46
+
47
+ // Maze generation
48
+ const gridSize = 16;
49
+ const cellSize = 4;
50
+ const maze = [];
51
+ const walls = [];
52
+
53
+ function createTexture(width, height, type) {
54
+ const canvas = document.createElement('canvas');
55
+ canvas.width = width;
56
+ canvas.height = height;
57
+ const ctx = canvas.getContext('2d');
58
 
59
+ if (type === 'floor') {
60
+ ctx.fillStyle = '#8B4513';
61
+ ctx.fillRect(0, 0, width, height);
62
+ ctx.strokeStyle = '#654321';
63
+ ctx.lineWidth = 2;
64
+ ctx.strokeRect(0, 0, width, height);
65
+ } else {
66
+ ctx.fillStyle = '#666666';
67
+ ctx.fillRect(0, 0, width, height);
68
+ for (let i = 0; i < 10; i++) {
69
+ ctx.fillStyle = `rgba(0, 0, 0, ${Math.random() * 0.3})`;
70
+ ctx.fillRect(
71
+ Math.random() * width,
72
+ Math.random() * height,
73
+ Math.random() * width/4,
74
+ Math.random() * height/4
75
+ );
76
+ }
 
 
 
 
 
 
 
77
  }
78
+ return new THREE.CanvasTexture(canvas);
79
  }
80
+
81
+ const floorTexture = createTexture(256, 256, 'floor');
82
+ const wallTexture = createTexture(256, 256, 'wall');
83
+
84
+ // Generate maze
85
+ for (let x = 0; x < gridSize; x++) {
86
+ maze[x] = [];
87
+ for (let z = 0; z < gridSize; z++) {
88
+ const isBoundary = x === 0 || x === gridSize - 1 || z === 0 || z === gridSize - 1;
89
+ const isCenter = x >= 6 && x <= 9 && z >= 6 && z <= 9;
90
+ const isWall = isBoundary || (!isCenter && Math.random() < 0.15);
91
+ maze[x][z] = isWall ? 1 : 0;
92
+
93
+ if (isWall) {
94
+ const wallGeometry = new THREE.BoxGeometry(cellSize, cellSize, cellSize);
95
+ const wallMaterial = new THREE.MeshPhongMaterial({ map: wallTexture });
96
+ const wall = new THREE.Mesh(wallGeometry, wallMaterial);
97
+ wall.position.set(x * cellSize, cellSize/2, z * cellSize);
98
+ scene.add(wall);
99
+ wall.boundingBox = new THREE.Box3().setFromObject(wall);
100
+ walls.push(wall);
101
+ }
 
 
102
  }
103
+ }
104
+
105
+ // Floor
106
+ const floorGeometry = new THREE.PlaneGeometry(gridSize * cellSize, gridSize * cellSize);
107
+ const floorMaterial = new THREE.MeshPhongMaterial({ map: floorTexture });
108
+ const floor = new THREE.Mesh(floorGeometry, floorMaterial);
109
+ floor.rotation.x = -Math.PI / 2;
110
+ scene.add(floor);
111
+
112
+ // Soldier setup
113
+ const loader = new THREE.GLTFLoader();
114
+ const soldiers = [];
115
+ const mixers = [];
116
+
117
+ function createSoldier(team, startX, startZ) {
118
+ loader.load('https://threejs.org/examples/models/gltf/Soldier.glb', (gltf) => {
119
+ const soldier = gltf.scene;
120
+ soldier.scale.set(2, 2, 2);
121
+ soldier.position.set(startX, 0, startZ);
122
+ soldier.team = team;
123
+ soldier.collisionRadius = 1;
124
+ soldier.speed = 0.1;
125
+ scene.add(soldier);
126
+ soldiers.push(soldier);
127
+
128
+ const mixer = new THREE.AnimationMixer(soldier);
129
+ mixers.push(mixer);
130
 
131
+ const idleAction = mixer.clipAction(gltf.animations[0]);
132
+ const runAction = mixer.clipAction(gltf.animations[3]);
133
+
134
+ soldier.actions = { idle: idleAction, run: runAction };
135
+ idleAction.play();
136
+ });
137
+ }
138
+
139
+ // Create two teams
140
+ createSoldier(1, 28, 28); // Team 1
141
+ createSoldier(2, 36, 36); // Team 2
142
+
143
+ camera.position.set(32, 20, 32);
144
+
145
+ // Movement controls
146
+ const keys = { w: false, a: false, s: false, d: false };
147
+ document.addEventListener('keydown', (e) => {
148
+ if (e.key in keys) keys[e.key] = true;
149
+ });
150
+ document.addEventListener('keyup', (e) => {
151
+ if (e.key in keys) keys[e.key] = false;
152
+ });
153
+
154
+ function checkCollision(newPosition, soldier) {
155
+ const soldierBox = new THREE.Sphere(newPosition, soldier.collisionRadius);
156
+ for (const wall of walls) {
157
+ if (soldierBox.intersectsBox(wall.boundingBox)) {
158
+ return true;
159
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  }
161
+ return false;
162
+ }
163
+
164
+ // Animation loop
165
+ const clock = new THREE.Clock();
166
+ function animate() {
167
+ requestAnimationFrame(animate);
168
+ const delta = clock.getDelta();
169
+
170
+ soldiers.forEach((soldier, index) => {
171
+ if (!soldier) return;
172
+
173
+ const moveDirection = new THREE.Vector3();
174
+ if (index === 0) { // Only control first soldier for demo
175
+ const camForward = new THREE.Vector3();
176
+ camera.getWorldDirection(camForward);
177
+ camForward.y = 0;
178
+ camForward.normalize();
179
+ const camLeft = new THREE.Vector3(-camForward.z, 0, camForward.x);
180
+
181
+ if (keys.w) moveDirection.add(camForward);
182
+ if (keys.s) moveDirection.sub(camForward);
183
+ if (keys.a) moveDirection.add(camLeft);
184
+ if (keys.d) moveDirection.sub(camLeft);
185
+ }
186
+
187
+ if (moveDirection.length() > 0) {
188
+ moveDirection.normalize();
189
+ const newPosition = soldier.position.clone()
190
+ .add(moveDirection.multiplyScalar(soldier.speed));
191
+
192
+ if (!checkCollision(newPosition, soldier)) {
193
+ soldier.position.copy(newPosition);
194
+ const angle = Math.atan2(moveDirection.x, moveDirection.z);
195
+ soldier.rotation.y = angle + Math.PI;
196
+
197
+ soldier.actions.idle.fadeOut(0.2);
198
+ soldier.actions.run.fadeIn(0.2);
199
+ }
200
+ } else {
201
+ soldier.actions.run.fadeOut(0.2);
202
+ soldier.actions.idle.fadeIn(0.2);
203
+ }
204
+
205
+ if (index === 0) {
206
+ controls.target.copy(soldier.position);
207
+ controls.update();
208
+
209
+ // Update debug overlay
210
+ document.getElementById('debug').innerHTML = `
211
+ Position: ${soldier.position.x.toFixed(2)},
212
+ ${soldier.position.y.toFixed(2)},
213
+ ${soldier.position.z.toFixed(2)}<br>
214
+ Rotation: ${(soldier.rotation.y * 180 / Math.PI).toFixed(2)}°
215
+ `;
216
+ }
217
+ });
218
+
219
+ mixers.forEach(mixer => mixer.update(delta));
220
+ renderer.render(scene, camera);
221
+ }
222
+
223
+ // Responsive design
224
+ window.addEventListener('resize', () => {
225
+ camera.aspect = window.innerWidth / window.innerHeight;
226
+ camera.updateProjectionMatrix();
227
+ renderer.setSize(window.innerWidth, window.innerHeight);
228
  });
229
+
230
+ animate();
231
+ </script>
232
+ </body>
233
+ </html>""")
234
 
235
+ demo.launch()