awacke1 commited on
Commit
9c48b13
·
verified ·
1 Parent(s): 8cb8d52

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +24 -326
index.html CHANGED
@@ -2,9 +2,8 @@
2
  <html>
3
  <head>
4
  <meta charset="utf-8">
5
- <title>Enhanced A-Frame Space Shooter with 3D Editor</title>
6
  <script src="https://cdnjs.cloudflare.com/ajax/libs/aframe/1.2.0/aframe.min.js"></script>
7
- <script src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>
8
  <style>
9
  .ui-panel {
10
  position: fixed;
@@ -22,7 +21,7 @@
22
  margin: 5px 0;
23
  padding: 5px 10px;
24
  }
25
- .animation-panel {
26
  position: fixed;
27
  top: 20px;
28
  right: 20px;
@@ -33,7 +32,7 @@
33
  color: white;
34
  font-family: Arial, sans-serif;
35
  }
36
- .animation-panel input {
37
  width: 50px;
38
  margin-right: 5px;
39
  }
@@ -46,148 +45,51 @@
46
  <button onclick="addPrimitive('cylinder')">Add Cylinder</button>
47
  <button onclick="addPrimitive('cone')">Add Cone</button>
48
  <button onclick="addPrimitive('torus')">Add Torus</button>
49
- <button onclick="toggleGameMode()">Toggle Game Mode</button>
50
  </div>
51
 
52
- <div class="animation-panel">
53
  <h3>Object Controls</h3>
54
  <p>Position:</p>
55
- <input id="px" type="number" placeholder="X">
56
- <input id="py" type="number" placeholder="Y">
57
- <input id="pz" type="number" placeholder="Z">
58
  <p>Rotation (degrees):</p>
59
- <input id="rx" type="number" placeholder="X">
60
- <input id="ry" type="number" placeholder="Y">
61
- <input id="rz" type="number" placeholder="Z">
62
  <button onclick="applyTransform()">Apply Transform</button>
63
  <button onclick="placeInFrontOfCamera()">Place in Front of Camera</button>
64
  </div>
65
 
66
- <a-scene fog="type: linear; color: #87CEEB; near: 0; far: 50">
67
- <a-sky color="#87CEEB"></a-sky>
68
- <a-entity id="player" position="0 1.6 0">
69
- <a-entity camera look-controls wasd-controls>
70
- <a-entity id="cursor" cursor="fuse: false;" position="0 0 -1"
71
- geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
72
- material="color: white; shader: flat"
73
- raycaster="objects: .enemy, .spawner, .editable"></a-entity>
74
- </a-entity>
75
  </a-entity>
76
- <a-entity id="scoreBar" position="0 3 -5">
77
- <a-box width="1" height="0.1" depth="0.1" color="#444444"></a-box>
78
- <a-box id="scoreIndicator" width="1" height="0.1" depth="0.1" color="#FFA500" scale="0 1 1"></a-box>
79
- <a-text value="Score" position="0 0.1 0" align="center" color="white"></a-text>
80
- </a-entity>
81
- <a-entity id="healthDisplay" position="0 2.5 -5" scale="5 5 5"></a-entity>
82
- <a-entity id="unitCounters" position="-0.8 0.6 -1.5" scale="0.5 0.5 0.5"></a-entity>
83
  </a-scene>
84
 
85
  <script>
86
- // Game variables
87
- let score = 0;
88
- let health = 100;
89
- let enemyCount = 0;
90
- let spawnerCount = 0;
91
-
92
- // Editor variables
93
  let selectedObject = null;
94
- let isGameMode = true;
95
- const simplex = new SimplexNoise();
96
-
97
- function generateProceduralTexture(size = 256) {
98
- const canvas = document.createElement('canvas');
99
- canvas.width = canvas.height = size;
100
- const ctx = canvas.getContext('2d');
101
- const imageData = ctx.createImageData(size, size);
102
- const data = imageData.data;
103
-
104
- for (let x = 0; x < size; x++) {
105
- for (let y = 0; y < size; y++) {
106
- const i = (x + y * size) * 4;
107
- const value = (simplex.noise2D(x / 20, y / 20) + 1) / 2;
108
- const hue = Math.floor(value * 360);
109
- const [r, g, b] = HSVtoRGB(hue / 360, 0.7, 0.9);
110
- data[i] = r;
111
- data[i + 1] = g;
112
- data[i + 2] = b;
113
- data[i + 3] = 255;
114
- }
115
- }
116
-
117
- ctx.putImageData(imageData, 0, 0);
118
- return canvas.toDataURL();
119
- }
120
-
121
- function generateBumpMap(size = 256) {
122
- const canvas = document.createElement('canvas');
123
- canvas.width = canvas.height = size;
124
- const ctx = canvas.getContext('2d');
125
- const imageData = ctx.createImageData(size, size);
126
- const data = imageData.data;
127
-
128
- for (let x = 0; x < size; x++) {
129
- for (let y = 0; y < size; y++) {
130
- const i = (x + y * size) * 4;
131
- const value = (simplex.noise2D(x / 10, y / 10) + 1) / 2;
132
- const intensity = Math.floor(value * 255);
133
- data[i] = data[i + 1] = data[i + 2] = intensity;
134
- data[i + 3] = 255;
135
- }
136
- }
137
-
138
- ctx.putImageData(imageData, 0, 0);
139
- return canvas.toDataURL();
140
- }
141
-
142
- function HSVtoRGB(h, s, v) {
143
- let r, g, b, i, f, p, q, t;
144
- i = Math.floor(h * 6);
145
- f = h * 6 - i;
146
- p = v * (1 - s);
147
- q = v * (1 - f * s);
148
- t = v * (1 - (1 - f) * s);
149
- switch (i % 6) {
150
- case 0: r = v, g = t, b = p; break;
151
- case 1: r = q, g = v, b = p; break;
152
- case 2: r = p, g = v, b = t; break;
153
- case 3: r = p, g = q, b = v; break;
154
- case 4: r = t, g = p, b = v; break;
155
- case 5: r = v, g = p, b = q; break;
156
- }
157
- return [
158
- Math.round(r * 255),
159
- Math.round(g * 255),
160
- Math.round(b * 255)
161
- ];
162
- }
163
 
164
  function addPrimitive(type) {
165
  const scene = document.querySelector('a-scene');
166
  const newEntity = document.createElement('a-entity');
167
  newEntity.setAttribute('geometry', `primitive: ${type}`);
168
-
169
- const textureUrl = generateProceduralTexture();
170
- const bumpMapUrl = generateBumpMap();
171
-
172
- newEntity.setAttribute('material', `src: ${textureUrl}; normalMap: ${bumpMapUrl}`);
173
  newEntity.setAttribute('class', 'editable');
174
  newEntity.addEventListener('click', function() { selectObject(this); });
175
  scene.appendChild(newEntity);
176
-
177
- // Place the new object in front of the camera
178
  placeInFrontOfCamera(newEntity);
179
-
180
- // Select the newly added object
181
- selectObject(newEntity);
182
  }
183
 
184
  function selectObject(obj) {
185
  if (selectedObject) {
186
- selectedObject.setAttribute('material', 'emissive', '#000000');
187
  }
188
  selectedObject = obj;
189
- selectedObject.setAttribute('material', 'emissive', '#FF0000');
190
-
191
  updateTransformInputs(selectedObject);
192
  }
193
 
@@ -235,8 +137,8 @@
235
  const direction = new THREE.Vector3(0, 0, -1);
236
  direction.applyQuaternion(camera.object3D.quaternion);
237
 
238
- // Set the distance to be similar to where the Score is (5 units away)
239
- const distance = 5;
240
 
241
  // Calculate the new position
242
  const newPosition = new THREE.Vector3(
@@ -253,213 +155,9 @@
253
  }
254
  }
255
 
256
- function toggleGameMode() {
257
- isGameMode = !isGameMode;
258
- const cursor = document.querySelector('#cursor');
259
- if (isGameMode) {
260
- cursor.setAttribute('raycaster', 'objects', '.enemy, .spawner');
261
- } else {
262
- cursor.setAttribute('raycaster', 'objects', '.editable');
263
- }
264
- }
265
-
266
- // Game logic functions
267
- function fireLaser(shooter, color) {
268
- const laser = document.createElement('a-entity');
269
- const start = new THREE.Vector3();
270
- const direction = new THREE.Vector3();
271
- shooter.object3D.getWorldPosition(start);
272
- shooter.object3D.getWorldDirection(direction);
273
- laser.setAttribute('position', start);
274
- laser.setAttribute('geometry', 'primitive: sphere; radius: 0.1');
275
- laser.setAttribute('material', `color: ${color}; shader: flat`);
276
- document.querySelector('a-scene').appendChild(laser);
277
-
278
- const animateShot = () => {
279
- const position = laser.getAttribute('position');
280
- const newPosition = {
281
- x: position.x + direction.x * 0.5,
282
- y: position.y + direction.y * 0.5,
283
- z: position.z + direction.z * 0.5
284
- };
285
- laser.setAttribute('position', newPosition);
286
-
287
- // Check for collisions
288
- const enemies = document.querySelectorAll('.enemy');
289
- enemies.forEach(enemy => {
290
- const enemyPos = enemy.getAttribute('position');
291
- const distance = calculateDistance(newPosition, enemyPos);
292
- if (distance < 1) {
293
- enemy.parentNode.removeChild(enemy);
294
- laser.parentNode.removeChild(laser);
295
- enemyCount--;
296
- score += 10;
297
- updateScoreDisplay();
298
- updateUnitCounters();
299
- return;
300
- }
301
- });
302
-
303
- const spawners = document.querySelectorAll('.spawner');
304
- spawners.forEach(spawner => {
305
- const spawnerPos = spawner.getAttribute('position');
306
- const distance = calculateDistance(newPosition, spawnerPos);
307
- if (distance < 1.5) {
308
- spawner.parentNode.removeChild(spawner);
309
- laser.parentNode.removeChild(laser);
310
- spawnerCount--;
311
- score += 50;
312
- updateScoreDisplay();
313
- updateUnitCounters();
314
- return;
315
- }
316
- });
317
-
318
- if (laser.parentNode) {
319
- requestAnimationFrame(animateShot);
320
- }
321
- };
322
-
323
- requestAnimationFrame(animateShot);
324
- }
325
-
326
- function calculateDistance(pos1, pos2) {
327
- const dx = pos1.x - pos2.x;
328
- const dy = pos1.y - pos2.y;
329
- const dz = pos1.z - pos2.z;
330
- return Math.sqrt(dx * dx + dy * dy + dz * dz);
331
- }
332
-
333
- function spawnEnemy() {
334
- const enemy = document.createElement('a-entity');
335
- enemy.setAttribute('geometry', 'primitive: box');
336
- enemy.setAttribute('material', 'color: red');
337
- enemy.setAttribute('class', 'enemy');
338
- const angle = Math.random() * Math.PI * 2;
339
- const radius = 10 + Math.random() * 10;
340
- const x = Math.cos(angle) * radius;
341
- const z = Math.sin(angle) * radius;
342
- enemy.setAttribute('position', `${x} 1.6 ${z}`);
343
- document.querySelector('a-scene').appendChild(enemy);
344
- enemyCount++;
345
- updateUnitCounters();
346
- }
347
-
348
- function spawnSpawner() {
349
- const spawner = document.createElement('a-entityfunction spawnSpawner() {
350
- const spawner = document.createElement('a-entity');
351
- spawner.setAttribute('geometry', 'primitive: box; width: 2; height: 2; depth: 2');
352
- spawner.setAttribute('material', 'color: purple');
353
- spawner.setAttribute('class', 'spawner');
354
- const angle = Math.random() * Math.PI * 2;
355
- const radius = 15 + Math.random() * 10;
356
- const x = Math.cos(angle) * radius;
357
- const z = Math.sin(angle) * radius;
358
- spawner.setAttribute('position', `${x} 1.6 ${z}`);
359
- document.querySelector('a-scene').appendChild(spawner);
360
- spawnerCount++;
361
- updateUnitCounters();
362
- }
363
-
364
- function updateGame() {
365
- // Spawn enemies from spawners
366
- const spawners = document.querySelectorAll('.spawner');
367
- spawners.forEach(spawner => {
368
- if (Math.random() < 0.1) {
369
- const enemy = document.createElement('a-entity');
370
- enemy.setAttribute('geometry', 'primitive: box');
371
- enemy.setAttribute('material', 'color: red');
372
- enemy.setAttribute('class', 'enemy');
373
- const spawnerPos = spawner.getAttribute('position');
374
- enemy.setAttribute('position', `${spawnerPos.x} ${spawnerPos.y} ${spawnerPos.z}`);
375
- document.querySelector('a-scene').appendChild(enemy);
376
- enemyCount++;
377
- }
378
- });
379
-
380
- // Move enemies towards player
381
- const player = document.querySelector('#player');
382
- const playerPos = player.getAttribute('position');
383
- const enemies = document.querySelectorAll('.enemy');
384
- enemies.forEach(enemy => {
385
- const enemyPos = enemy.getAttribute('position');
386
- const direction = {
387
- x: playerPos.x - enemyPos.x,
388
- y: 0,
389
- z: playerPos.z - enemyPos.z
390
- };
391
- const length = Math.sqrt(direction.x * direction.x + direction.z * direction.z);
392
- direction.x /= length;
393
- direction.z /= length;
394
- enemy.setAttribute('position', {
395
- x: enemyPos.x + direction.x * 0.05,
396
- y: enemyPos.y,
397
- z: enemyPos.z + direction.z * 0.05
398
- });
399
-
400
- // Check for collision with player
401
- if (calculateDistance(playerPos, enemy.getAttribute('position')) < 1) {
402
- enemy.parentNode.removeChild(enemy);
403
- enemyCount--;
404
- health -= 10;
405
- updateHealthDisplay();
406
- updateUnitCounters();
407
- }
408
- });
409
-
410
- // Randomly spawn new enemies and spawners
411
- if (Math.random() < 0.02) spawnEnemy();
412
- if (Math.random() < 0.005) spawnSpawner();
413
- }
414
-
415
- function updateScoreDisplay() {
416
- const scoreIndicator = document.querySelector('#scoreIndicator');
417
- scoreIndicator.setAttribute('scale', `${score / 1000} 1 1`);
418
- }
419
-
420
- function updateHealthDisplay() {
421
- const healthDisplay = document.querySelector('#healthDisplay');
422
- healthDisplay.innerHTML = '';
423
- for (let i = 0; i < health / 10; i++) {
424
- const heart = document.createElement('a-text');
425
- heart.setAttribute('value', '❤');
426
- heart.setAttribute('position', `${i * 0.2} 0 0`);
427
- heart.setAttribute('color', 'red');
428
- healthDisplay.appendChild(heart);
429
- }
430
- }
431
-
432
- function updateUnitCounters() {
433
- const unitCounters = document.querySelector('#unitCounters');
434
- unitCounters.innerHTML = '';
435
- const enemyCounter = document.createElement('a-text');
436
- enemyCounter.setAttribute('value', `Enemies: ${enemyCount}`);
437
- enemyCounter.setAttribute('position', '0 0 0');
438
- unitCounters.appendChild(enemyCounter);
439
- const spawnerCounter = document.createElement('a-text');
440
- spawnerCounter.setAttribute('value', `Spawners: ${spawnerCount}`);
441
- spawnerCounter.setAttribute('position', '0 -0.3 0');
442
- unitCounters.appendChild(spawnerCounter);
443
- }
444
-
445
- // Initialize the game
446
- updateHealthDisplay();
447
- updateUnitCounters();
448
-
449
- // Main game loop
450
- setInterval(() => {
451
- updateGame();
452
- score++;
453
- updateScoreDisplay();
454
- }, 1000 / 60); // 60 FPS
455
-
456
- // Event listeners
457
- const scene = document.querySelector('a-scene');
458
- scene.addEventListener('click', (event) => {
459
- if (isGameMode) {
460
- const player = document.querySelector('#player');
461
- fireLaser(player, '#00FF00');
462
- } else if (event.detail.intersectedEl && event.detail.intersectedEl.classList.contains('editable')) {
463
  selectObject(event.detail.intersectedEl);
464
  }
465
  });
 
2
  <html>
3
  <head>
4
  <meta charset="utf-8">
5
+ <title>Simplified A-Frame 3D Editor</title>
6
  <script src="https://cdnjs.cloudflare.com/ajax/libs/aframe/1.2.0/aframe.min.js"></script>
 
7
  <style>
8
  .ui-panel {
9
  position: fixed;
 
21
  margin: 5px 0;
22
  padding: 5px 10px;
23
  }
24
+ .control-panel {
25
  position: fixed;
26
  top: 20px;
27
  right: 20px;
 
32
  color: white;
33
  font-family: Arial, sans-serif;
34
  }
35
+ .control-panel input {
36
  width: 50px;
37
  margin-right: 5px;
38
  }
 
45
  <button onclick="addPrimitive('cylinder')">Add Cylinder</button>
46
  <button onclick="addPrimitive('cone')">Add Cone</button>
47
  <button onclick="addPrimitive('torus')">Add Torus</button>
 
48
  </div>
49
 
50
+ <div class="control-panel">
51
  <h3>Object Controls</h3>
52
  <p>Position:</p>
53
+ <input id="px" type="number" step="0.1" placeholder="X">
54
+ <input id="py" type="number" step="0.1" placeholder="Y">
55
+ <input id="pz" type="number" step="0.1" placeholder="Z">
56
  <p>Rotation (degrees):</p>
57
+ <input id="rx" type="number" step="1" placeholder="X">
58
+ <input id="ry" type="number" step="1" placeholder="Y">
59
+ <input id="rz" type="number" step="1" placeholder="Z">
60
  <button onclick="applyTransform()">Apply Transform</button>
61
  <button onclick="placeInFrontOfCamera()">Place in Front of Camera</button>
62
  </div>
63
 
64
+ <a-scene>
65
+ <a-sky color="#ECECEC"></a-sky>
66
+ <a-entity id="rig" position="0 1.6 0">
67
+ <a-camera look-controls wasd-controls>
68
+ <a-cursor></a-cursor>
69
+ </a-camera>
 
 
 
70
  </a-entity>
 
 
 
 
 
 
 
71
  </a-scene>
72
 
73
  <script>
 
 
 
 
 
 
 
74
  let selectedObject = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  function addPrimitive(type) {
77
  const scene = document.querySelector('a-scene');
78
  const newEntity = document.createElement('a-entity');
79
  newEntity.setAttribute('geometry', `primitive: ${type}`);
80
+ newEntity.setAttribute('material', 'color: #4CC3D9');
 
 
 
 
81
  newEntity.setAttribute('class', 'editable');
82
  newEntity.addEventListener('click', function() { selectObject(this); });
83
  scene.appendChild(newEntity);
 
 
84
  placeInFrontOfCamera(newEntity);
 
 
 
85
  }
86
 
87
  function selectObject(obj) {
88
  if (selectedObject) {
89
+ selectedObject.setAttribute('material', 'color', '#4CC3D9');
90
  }
91
  selectedObject = obj;
92
+ selectedObject.setAttribute('material', 'color', '#FF0000');
 
93
  updateTransformInputs(selectedObject);
94
  }
95
 
 
137
  const direction = new THREE.Vector3(0, 0, -1);
138
  direction.applyQuaternion(camera.object3D.quaternion);
139
 
140
+ // Set the distance to be 3 units away from the camera
141
+ const distance = 3;
142
 
143
  // Calculate the new position
144
  const newPosition = new THREE.Vector3(
 
155
  }
156
  }
157
 
158
+ // Event listener for object selection
159
+ document.querySelector('a-scene').addEventListener('click', (event) => {
160
+ if (event.detail.intersectedEl && event.detail.intersectedEl.classList.contains('editable')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  selectObject(event.detail.intersectedEl);
162
  }
163
  });