## Preparation of the environment – Global variables

Let’s start by creating some global variables :

```// Wave configuration
var wavespeed = 1;
var wavewidth = 200;
var waveheight = 100;
var objects_margin = 20;

//Array
var waveobjects = new Array();```
• `wavespeed` – Speed of the waves
• `wavewidth` – Width of the waves
• `waveheight` – Height of the waves
• `objects_margin` – Spacing between particles
• `waveobjects` – List of particles in the scene

## Preparation of the environment – Creation of the particles

Then, using a nesting of `for` loops, we create the particles composing our wave.
Our group of particles will be ordered in square via a simple increment on the X and Z axes.

Each particle is a Three.js `Sprite` instance.

```// ---------------- PARTICLES ----------------
var spriteMaterial = new THREE.SpriteMaterial( { map: particleTexture, transparent : true, opacity :1, color: 0x000000 } );

for ( var x = 0; x < 100; x ++ )
{
for ( var y = 0; y < 100; y ++ )
{
// Sprite creation
var mesh = new THREE.Sprite( spriteMaterial );

mesh.scale.set(10,10,10);                 // scale
mesh.position.x = x * objects_margin;    // POSITION X
mesh.position.y = 0;
mesh.position.z = y * objects_margin;    //POSITION Y
waveobjects.push(mesh);
}
}```

As explained, the position of each `Sprite` on the X and Z axes depends on its creation order in the `for` loops.

The Particles we create, instances of `Sprite`, are added to the scene and referenced in the `waveobjects` structure (JavaScript `Array`).

## Wave creation

The motion of each particle is calculated using the `Math.sin` function, its position in the group and the elapsed time.
Thus, the combination of these three parameters is used to calculate the position of each particle in the scene, and thus create a wave animation.

### Three.js Clock and Math.sin

So, to keep track of the elapsed time, we create a Three.js `Clock` class instance .

`clock = new THREE.Clock();`

Then, in our main loop :

```function animate()
{
var delta = clock.getDelta();
var elapsed = clock.elapsedTime;

[...]
}```

Note that the `elapsed` variable contains the total number of elapsed seconds since the launch of the application.

### Particle animation

Still in the main loop, we loop over the list of particles in order to modify the positions one by one :

```for(var i = 0 ; i < waveobjects.length ; i++)
{
waveobjects[i].position.y = Math.cos( (elapsed + (waveobjects[i].position.x /wavewidth) + (waveobjects[i].position.z /wavewidth) ) *wavespeed ) * waveheight;
}```

As explained, we determine the new position of each particle by its position on the X and Z axes, the elapsed time and the `Math.sin` method.

## Final code and result

```// Wave configuration
var wavespeed = 1;
var wavewidth = 200;
var waveheight = 100;
var objects_margin = 20;

//Array
var waveobjects = new Array();

[...]

clock = new THREE.Clock();

[...]

// ---------------- PARTICLES ----------------

var spriteMaterial = new THREE.SpriteMaterial( { map: particleTexture, transparent : true, opacity :1, color: 0x000000 } );

for ( var x = 0; x < 100; x ++ )
{
for ( var y = 0; y < 100; y ++ )
{
// Sprite creation
var mesh = new THREE.Sprite( spriteMaterial );

mesh.scale.set(10,10,10); 				// scale
mesh.position.x = x * objects_margin;	// POSITION X
mesh.position.y = 0;
mesh.position.z = y * objects_margin;	//POSITION Y

waveobjects.push(mesh);
}
}

[...]

function animate()
{
var delta = clock.getDelta();
var elapsed = clock.elapsedTime;

requestAnimationFrame( animate );

for(var i = 0 ; i < waveobjects.length ; i++)
{

waveobjects[i].position.y = Math.cos( (elapsed + (waveobjects[i].position.x /wavewidth) + (waveobjects[i].position.z /wavewidth) ) *wavespeed ) * waveheight;
}

renderer.render( scene, camera );
}```