Matemáticas, física y animación con Canvas html5 – parte 2

canvas
Estimados! Disculpen por dejar tanto tiempo el blog botado, ahora continuaré con los ejercicios de canvas. Este post es la continuación de Matemáticas, física y animación con Canvas html5 – parte 1. Para esta ocación no profundizaré tanto en puntos matemáticos como lo hice en la primera parte, por lo que recomiendo que si no la han leído lo hagan y luego continuen con esta.
Para este ejercicio vamos a crear muchas pelotas chocando con las paredes (no entre si) y moviendose a diferentes velocidades según el tamaño de cada una.
Si quieren ver el resultado bajen al final de este post
Al igual que el post anterior, comenzaré pegando todo el código para que lo vean y luego explicando cada uno de los puntos relevantes.
Comenzamos importando nuestra librería modernizr entre las etiquetas “head” de nuestro HTML para garantizar la compatibilidad de nuestro canvas con todos los navegadores.

<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.1/modernizr.min.js"></script>

y dentro de nuestras etiquetas body creamos el canvas donde se dibujará nuestro script.

<div>
	<canvas id="canvasTwo" width="600" height="300"> 
		Cambiate de navegador!
	</canvas>
</div>

Ahora el código completo de nuestro javascript

[javascript]
window.addEventListener(‘load’, eventWindowLoaded, false);
function eventWindowLoaded(){
canvasAppPartTwo();
}
function canvasSupport(){
return Modernizr.canvas;
}
function canvasAppPartTwo(){
if(!canvasSupport()){
return;
}

function drawScreen(){
context.fillStyle = ‘#EEEEEE’;
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
context.strokeStyle = ‘#000000’;
context.strokeRect(1, 1, theCanvas.width-2, theCanvas.height-2);

var ball;
for(var i = 0; i < balls.length; i++){
ball = balls[i];
context.fillStyle = ball.color;
ball.x += ball.xunits;
ball.y += ball.yunits;

context.beginPath();
context.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, true);
context.closePath();
context.fill();

if((ball.x+ball.radius) > theCanvas.width || ball.x < 0){
ball.angle = 180 – ball.angle;
updateBall(ball);
}else if((ball.y+ball.radius) > theCanvas.height || ball.y < 0){
ball.angle = 360 – ball.angle;
updateBall(ball);
}
}
}
function updateBall(ball){
ball.radians = ball.angle * Math.PI/ 180;
ball.xunits = Math.cos(ball.radians) * ball.speed;
ball.yunits = Math.sin(ball.radians) * ball.speed;
}

var numBalls = 1000;
var maxSize = 8;
var minSize = 5;
var maxSpeed = maxSize + 5;
var balls = new Array();
var tempBall;
var tempX;
var tempY;
var tempSpeed;
var tempAngle;
var tempRadius;
var tempRadians;
var tempXunits;
var tempYunits;
var tempColor;

theCanvas = document.getElementById(‘canvasTwo’);
context = theCanvas.getContext(‘2d’);

for(var i = 0; i < numBalls; i++){
tempRadius = Math.floor(Math.random()*maxSize)+minSize;
tempX = tempRadius*2 + (Math.floor(Math.random()*theCanvas.width)-tempRadius*2);
tempY = tempRadius*2 + (Math.floor(Math.random()*theCanvas.height)-tempRadius*2);
tempSpeed = maxSpeed-tempRadius;
tempAngle = Math.floor(Math.random()*360);
tempRadians = tempAngle * Math.PI/ 180;
tempXunits = Math.cos(tempRadians) * tempSpeed;
tempYunits = Math.sin(tempRadians) * tempSpeed;
tempColor = ‘#’+Math.floor(Math.random()*16777215).toString(16);
tempBall = {
x: tempX,
y: tempY,
radius: tempRadius,
speed: tempSpeed,
angle: tempAngle,
xunits: tempXunits,
yunits: tempYunits,
color: tempColor
}
balls.push(tempBall);
}
setInterval(drawScreen, 33);
}

[/javascript]

Ahora explicaré las cambios. Los primero es determinar la función que se ejecutará al momento que se cargue el javascript.

[javascript]
window.addEventListener(‘load’, eventWindowLoaded, false);
function eventWindowLoaded(){
canvasAppPartTwo();
}
[/javascript]

Definimos un intervalo para ir ejecutando el canvas.

[javascript]
setInterval(drawScreen, 33);
[/javascript]

Entonces en orden de ejecución debemos definir las variables que utilizares. Solo comentaré las nuevas que agregé a este ejemplo. Las demás son variables que utilizaremos de forma temporal.

[javascript]
var numBalls = 1000; // Numero de bolas
var maxSize = 8; // Tamaño máximo que pueden tener
var minSize = 5; // Tamaño minimo
var maxSpeed = maxSize + 5; // Velocidad máxima
var balls = new Array(); // Arreglo que contendrá las bolas que creemos.
[/javascript]

Rerefenciamos el canvas en el contexto de nuestro script

[javascript]
theCanvas = document.getElementById(‘canvasTwo’);
context = theCanvas.getContext(‘2d’);
[/javascript]

Lo siguiente es hacer un “for” que recorrerá para crear cada una de las pelotas, para este ejemplo serán 1000 (pueden poner el número que quieran, solo sean considerados con su máquina).

[javascript]
for(var i = 0; i < numBalls; i++){

}
[/javascript]

Con esto vamos creando lo valores temprales de nuestras bolas. No me detendré en este punto porque ya está explicado en el primero post como voy sacando los cálculos, la única diferencia es que voy jugando con valores random.
Así encontes calculamos el radio entre el tamaño minimo que determinamos y el máximo.

[javascript]
tempRadius = Math.floor(Math.random()*maxSize)+minSize;
[/javascript]

Luego calculamos la posición de la bola dentro del canvas, el valor random es el tamaño del canvas menos su radio al cuadrado.

[javascript]
tempX = tempRadius*2 + (Math.floor(Math.random()*theCanvas.width)-tempRadius*2);
tempY = tempRadius*2 + (Math.floor(Math.random()*theCanvas.height)-tempRadius*2);
[/javascript]

La velocidad que está directamente relacionada con el tamaño de la bola, ya que mientras más grande sea, más lento debe moverse.

[javascript]
tempSpeed = maxSpeed-tempRadius;
[/javascript]

Y los cambios de angulos en la dirección de nuestra bola.

[javascript]
tempAngle = Math.floor(Math.random()*360);
tempRadians = tempAngle * Math.PI/ 180;
tempXunits = Math.cos(tempRadians) * tempSpeed;
tempYunits = Math.sin(tempRadians) * tempSpeed;
[/javascript]

FinaLmente le damos un color random a la pelota para poder diferenciarlas unas de otras.

[javascript]
tempColor = ‘#’+Math.floor(Math.random()*16777215).toString(16);
[/javascript]

Ya teniendo todos los valores, agregamos la pelota a nuestro arreglo de bolas.

[javascript]
tempBall = {
x: tempX,
y: tempY,
radius: tempRadius,
speed: tempSpeed,
angle: tempAngle,
xunits: tempXunits,
yunits: tempYunits,
color: tempColor
}
balls.push(tempBall);
[/javascript]

Ya dentro de la función drawScreen dibujamos el contenedor de nuestro canvas.

[javascript]
context.fillStyle = ‘#EEEEEE’;
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
context.strokeStyle = ‘#000000’;
context.strokeRect(1, 1, theCanvas.width-2, theCanvas.height-2);
[/javascript]

Y volvemos a recorrer el arreglo de bolas para id dibujandolas dentro de nuestro canvas. Utilizaré la variable auxiliar ball donde iré referenciando cada bola.

[javascript]
var ball;
for(var i = 0; i < balls.length; i++){

}
[/javascript]

Referenciamos los valores.

[javascript]
ball = balls[i];
ball.x += ball.xunits;
ball.y += ball.yunits;
[/javascript]

Y dibujamos la bola con su respectivo color y tamaño.

[javascript]
context.fillStyle = ball.color;
context.beginPath();
context.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, true);
context.closePath();
context.fill();
[/javascript]

Ahora capturo el momento en donde la bola debe cambiar su dirección para no salir del canvas. Llamando a la función updateBall.

[javascript]
if((ball.x+ball.radius) > theCanvas.width || ball.x < 0){
ball.angle = 180 – ball.angle;
updateBall(ball);
}else if((ball.y+ball.radius) > theCanvas.height || ball.y < 0){
ball.angle = 360 – ball.angle;
updateBall(ball);
}
[/javascript]

Al comienzo del for definimos una variable auxiliar que ahora utilizamos para poder actualizar la bola fuera del for.

[javascript]
function updateBall(ball){
ball.radians = ball.angle * Math.PI/ 180;
ball.xunits = Math.cos(ball.radians) * ball.speed;
ball.yunits = Math.sin(ball.radians) * ball.speed;
}
[/javascript]

Y por fin el resultado final! Hay varias cosas que podemos mejorar, como por ejemplo que las pelotas choquen entre ellas. Haré una tercera parte para eso.
Gracias por su tiempo y por espero que el tutorial les haya gustado.

Actualiza tu browser por la chucha!

Un comentario en “Matemáticas, física y animación con Canvas html5 – parte 2

  1. Andrew

    Ahora que sabemos por que debemos aprender HTML5 canvas, echemos un vistazo a los elementos basicos y como empezar a usarlo.

    Responder

Agregar un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *