File size: 4,420 Bytes
9a7645b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Recursive Polygons in 3D with Continuous Snowflakes</title>
  <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
  <script src="https://unpkg.com/aframe-environment-component/dist/aframe-environment-component.min.js"></script>
  <style>
    #canvas {
      height: 500px;
      width: 800px;
    }
  </style>
</head>
<body>
  <a-scene>
    <a-entity environment="preset: forest"></a-entity>

    <!-- Existing Recursive Polygon Component -->
    <!-- ... Your existing entities ... -->

    <!-- Snowflakes Components -->
    <!-- Clouds will be added dynamically -->

    <a-entity camera position="0 1.6 0" look-controls wasd-controls></a-entity>
    <a-plane position="0 0 0" rotation="-90 0 0" width="100" height="100" color="#FFF"></a-plane>
  </a-scene>

  <script>
    AFRAME.registerComponent('snowflake', {
      schema: {
        size: { type: 'number', default: 0.1 },
        meltTime: { type: 'number', default: 15000 }
      },
      init: function() {
        let size = this.data.size;
        this.el.setAttribute('geometry', {
          primitive: 'sphere',
          radius: size
        });
        this.el.setAttribute('material', { color: '#FFF' });
        this.resetPosition();
        this.startMeltingLoop();
      },
      startMeltingLoop: function() {
        const resetAndStartAgain = () => {
          this.resetPosition();
          setTimeout(resetAndStartAgain, Math.random() * this.data.meltTime + 15000);
        };
        setTimeout(resetAndStartAgain, Math.random() * this.data.meltTime + 15000);
      },
      resetPosition: function() {
        this.el.object3D.position.set(
          Math.random() * 20 - 10,
          5 + Math.random() * 5,
          Math.random() * 20 - 10
        );
        this.velocity = new THREE.Vector3(
          (Math.random() - 0.5) * 0.01, // Random wind effect
          -0.02, // Falling speed
          (Math.random() - 0.5) * 0.01  // Random wind effect
        );
      },
      tick: function() {
        this.el.object3D.position.add(this.velocity);
        if (this.el.object3D.position.y <= -3.5) {
          this.el.object3D.position.y = -3.5; // Accumulate on the ground
          this.velocity.set(0, 0, 0); // Stop movement when it hits the ground
        }
      }
    });
    AFRAME.registerComponent('custom-controls', {
      init: function () {
        this.velocityY = 0;
        this.isMovingUp = false;
        window.addEventListener('keydown', (e) => {
          if (e.key === 'q' || e.key === 'Q') {
            this.isMovingUp = true;
          }
          if (e.key === 'e' || e.key === 'E') {
            this.velocityY = 0; // Stop upward movement
          }
        });
        window.addEventListener('keyup', (e) => {
          if (e.key === 'q' || e.key === 'Q') {
            this.isMovingUp = false;
          }
        });
      },
      tick: function () {
        let position = this.el.getAttribute('position');
        if (this.isMovingUp) {
          this.velocityY = 0.05; // Upward velocity
        } else {
          this.velocityY -= 0.01; // Gravity
        }
        position.y += this.velocityY;
        if (position.y < 1.6) { // Ground level
          position.y = 1.6;
          this.velocityY = 0;
        }
        this.el.setAttribute('position', position);
      }
    });
    
    function createSnowflakeCloud(x, y, z, numParticles) {
      let cloud = document.createElement('a-entity');
      cloud.object3D.position.set(x, y, z);
      for (let i = 0; i < numParticles; i++) {
        let size = Math.random() * 0.1 + 0.05; // Random size between 0.05 and 0.15
        let meltTime = Math.random() * 20000 + 5000; // Random time between 5 and 25 seconds
        setTimeout(() => {
          let snowflakeEl = document.createElement('a-entity');
          snowflakeEl.setAttribute('snowflake', {size: size, meltTime: meltTime});
          cloud.appendChild(snowflakeEl);
        }, i * 100);
      }
      document.querySelector('a-scene').appendChild(cloud);
    }
    // Create a grid of 9 snowflake clouds
    for (let x = -10; x <= 10; x += 10) {
      for (let z = -10; z <= 10; z += 10) {
        createSnowflakeCloud(x, 5, z, 50); // Increase the number of particles per cloud
      }
    }
    // Create a larger central cloud
    createSnowflakeCloud(0, 8, 0, 100);
  </script>
</body>
</html>