Sesion Laboratorio 9 Practica 3 2 - jesusgpa/2023-2024-CSAAI GitHub Wiki

Sesión Laboratorio 9: Práctica 3-2

  • Tiempo: 2h
  • Fecha: Jueves 4 de Abril de 2024
  • Objetivos de la sesión:
    • Posicionar el proyectil
    • Posicionar el objetivo
    • Añadir un botón de lanzar y de inicio
    • Obtener las ecuaciones de movimiento en el canvas.

Contenido

Introducción

Como si fuese una receta de cocina, vamos a recordar los elementos básicos que vamos a necesitar y dónde encontrarlos.

Empezamos por el esqueleto del programa de animación, debe seguir esta estructura:

//-- Declaración de variables y objetos

//-- Obtención del canvas y de los elementos HTML a usar

//-- Función principal de actualización
function update() 
{
  //-- Implementación del algoritmo de animación:

  //-- 1) Actualizar posición de los elementos

  //-- 2) Borrar el canvas

  //-- 3) Pintar los elementos en el canvas

  //-- 4) Repetir
  requestAnimationFrame(update);
}

//-- Otras funciones....

//-- Hay que llamar a update la primera vez
update();

Vamos a necesitar un canvas donde empezar colocar los elementos, y para eso necesitamos un documento html.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tiro parabólico</title>

    <!-- Hoja de estilo -->
    <link rel="stylesheet" href="tp1.css">

    <!-- Código javascript -->
    <script src="tp1.js" defer></script>

</head>
<body>


    <h1>Tiro parabólico</h1>
    <canvas id="ctiro"></canvas>

    <input type="button" id="btnLanzar" value="Lanzar">
    <input type="button" id="btnIniciar" value="Iniciar">

</body>
</html>

Y algo de CSS.

/* 
Estilos para el campo de tiro
*/  

#ctiro {
  background-color: lightblue;
  border-style: solid;
  border-width: 1px;
  border-color: black;
  border-radius: 5px;
}

Con lo que tenemos lo más básico para empezar.

Empezamos por el proyectil

Te recomiendo que utilices diferentes funciones para cada una de las acciones que vamos a necesitar.

Por ejemplo, esta podría ser tu función para dibujar el proyectil.

//-- función para pintar el proyectil
function dibujarP(x,y,lx,ly,color) {

    //-- Pintando el proyectil
    ctx.beginPath();

    //-- Definir un rectángulo de dimensiones lx x ly,
    ctx.rect(x, y, lx, ly);

    //-- Color de relleno del rectángulo
    ctx.fillStyle = color;

    //-- Mostrar el relleno
    ctx.fill();

    //-- Mostrar el trazo del rectángulo
    ctx.stroke();

    ctx.closePath();
}

Porque así tendrás funciones especializadas para cada trabajo que podrás llamar desde diferentes puntos de tu animación.

Además tenemos que colocar el proyectil en una posición determinada al principio.

También te recomiendo utilizar variables que puedes actualizar durante la animación.

//-- Coordenadas iniciales del proyectil
let xop = 5;
let yop = 345;
let xp = xop;
let yp = yop;

Y por supuesto no olvides llamar a la función de posición del proyectil dentro de tu función de animación.

//-- Dibujar el proyectil
dibujarP(xop, yop, 50, 50, "green"); // Pintar el proyectil


//-- Función principal de actualización
function lanzar() 
{
  //-- Implementación del algoritmo de animación:

  //-- 1) Actualizar posición de los elementos

  //-- 2) Borrar el canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  //-- 3) Pintar los elementos en el canvas
  dibujarP(xp, yp, 50, 50, "blue"); // Pintar el proyectil

  //-- 4) Repetir
  requestAnimationFrame(lanzar);
}

Con esto tendremos posicionado el proyectil:

Pero no se moverá, porque nos falta un detalle.

Añadir la función de callback para botón de lanzamiento.

Algo que ya hemos visto en las sesiones anteriores y que tiene esta pinta.

Primero localizamos el elemento en nuestro documento html.

//-- Acceder al botón de disparo
const btnLanzar = document.getElementById("btnLanzar");

Y después le asociamos la función de retrollamada.

//-- Función de retrollamada del botón de disparo
btnLanzar.onclick = () => {
    lanzar();
}

Esto no se mueve...

Claro, es porque no hemos añadido la física de nuestro movimiento para el proyectil.

Como estamos empezando, vamos darle un movimiento rectilíneo sobre el eje X.

Si te acuerdas, esto ya lo vimos en una sesión anterior para desplazar un rectángulo de color rojo por el canvas.

Tenemos que definir la velocidad del proyectil, y actualizar la posición dentro de la función de animación.

//-- Dibujar el proyectil
dibujarP(xop, yop, 50, 50, "green"); // Pintar el proyectil

//-- Velocidad del proyectil
let velp = 5;

//-- Función principal de actualización
function lanzar() 
{
  //-- Implementación del algoritmo de animación:

  //-- 1) Actualizar posición de los elementos
  xp = xp + velp;

  //-- 2) Borrar el canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  //-- 3) Pintar los elementos en el canvas
  dibujarP(xp, yp, 50, 50, "blue"); // Pintar el proyectil

  //-- 4) Repetir
  requestAnimationFrame(lanzar);
}

Y ahora sí, cuando pulses lanzar verás el proyectil moverse hacia la derecha.

Para resaltar que ha comenzado el movimiento, puedes cambiar el proyectil de color.

Mejor si tenemos un objetivo

Si has llegado hasta aquí, te resultará sencillo hacer algo parecido para situar el objetivo dentro del canvas.

Por un lado tendrás que definir sus coordenadas iniciales.

//-- Coordenadas iniciales del objetivo
let xomin = 200;
let xomax = 770;
let xo = 500; //getRandomXO(xomin,xomax);
let yo = 370;

Recuerda que en la práctica, la posición del objetivo debe ser diferente cada vez.

Por eso te recomiendo utilizar una función que devuelva una posición aleatoria sobre el eje X entre un mínimo y un máximo.

Si no recuerdas cómo utilizar la biblioteca matemática para obtener un número aleatorio tienes un buen ejemplo en esta sesión.

Sesión Laboratorio 7: Práctica 2-3

Una vez resuelto eso.

Necesitarás una función para pintar el objetivo.

//-- función para pintar el objetivo
function dibujarO(x,y) {

    //-- Pintando el objetivo
    ctx.beginPath();

    //-- Dibujar un circulo: coordenadas x,y del centro
    //-- Radio, Angulo inicial y angulo final
    ctx.arc(x, y, 25, 0, 2 * Math.PI);
    ctx.strokeStyle = 'blue';
    ctx.lineWidth = 2;
    ctx.fillStyle = 'red';

    //-- Dibujar el relleno
    ctx.fill()    

    //-- Dibujar el trazo
    ctx.stroke();

    ctx.closePath();
}

Sin olvidar actualizar la función de animación.

//-- Dibujar el objetivo
dibujarO(xo,yo); // Pintar el objetivo

//-- Dibujar el proyectil
dibujarP(xop, yop, 50, 50, "green"); // Pintar el proyectil

//-- Velocidad del proyectil
let velp = 1;

//-- Función principal de actualización
function lanzar() 
{
  //-- Implementación del algoritmo de animación:

  //-- 1) Actualizar posición de los elementos
  xp = xp + velp;

  //-- 2) Borrar el canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  //-- 3) Pintar los elementos en el canvas
  dibujarO(xo,yo); // Pintar el objetivo

  dibujarP(xp, yp, 50, 50, "blue"); // Pintar el proyectil

  //-- 4) Repetir
  requestAnimationFrame(lanzar);
}

Y ahora ya tendrás todos los elementos para empezar.

Vuelta a empezar

Un último detalles antes de dejarte trabajar.

Seguro que te has dado cuenta que lanzamos el proyectil y sigue hasta el infinito.

No vuelve.

Solo para cuando actualizamos el navegador.

Pero hay otra forma de poner todo como al principio sin tener que refrescar.

Para eso tenemos el botón de iniciar.

Hasta ahora no hacía nada, pero vamos a añadir la función de callback que trae de vuelta el proyectil viajero.

Lo primero es encontrarlo dentro de nuestro documento.

//-- Acceder al botón de inicio
const btnIniciar = document.getElementById("btnIniciar");

Y después le asociaremos la siguiente función de callback.

//-- Función de retrollamada del botón iniciar
btnIniciar.onclick = () => {
    location.reload();
}

Ahora al pulsar Iniciar todo volverá al punto de partida.

Recuerda, el objetivo debe estar en una nueva posición al volver a empezar. ;)

Introducción a las animaciones.

Sesión 6 Animaciones

Si has pensado en añadir sonidos

Estos son algunos sonidos del rebote de una pelota en la raqueta y en las paredes en el juego original del PONG por si los quieres utilizar para hacer pruebas:

Encontrarás como utilizar los sonidos en esta sesión.

Sesión 7: HTML II

Es hora de practicar

  • Plantea el canvas inicial.
  • Añade los primeros elementos.
  • Implementa una física de movimiento básica.
  • Posiciona el objetivo de manera aleatoria en el campo de tiro.
  • ¿Has pensado en añadir sonidos?

Conclusiones

Con esta sesión puedes empezar a posicionar los elementos en el canvas y añadir un movimiento básico.

Autor

Jesús Parrado Alameda (jesusgpa)

Creditos

Licencia

Enlaces

⚠️ **GitHub.com Fallback** ⚠️