Skip to content

L10:Practica 3_3

Juan Gonzalez-Gomez edited this page Apr 27, 2021 · 1 revision

Sesión Laboratorio 10: Práctica 3-3

  • Tiempo: 2h
  • Fecha: Martes, 27 de Abril de 2021
  • Objetivos de la sesión:
    • Añadir la destrucción de ladrillos

Contenido

Introducción

Es el momento de añadir los ladrillos y completar nuestro juego. En esta animación puedes ver una versión de este juego, con todos sus ladrillos y cómo se van destruyendo

Los ladrillos

Para implementar los ladrillos debemos hacer las siguentes cosas:

  • Definir su estructura y sus valores iniciales
  • Crear la estructura inicial, inicializada correctamente
  • Función para dibujar los ladrillos en función de su estado
  • Función para detectar la colisiones entre la bola y los ladrillos

Estructura de los ladrillos

Los ladrillos son objetos que tienen las siguientes propiedades:

  • Posición x,y: Dónde están colocados en la pantalla
  • Dimensiones: w,h: Tamaño del ladrillo (anchura y altura)
  • Relleno: Los ladrillos no están pegados unos a otros, sino que tienen espacio vacío alrededor (como la propiedad padding de los elementos html)
  • Visible: Los ladrillos tiene dos estados: Visible y no visible. Así es como controlamos que se destruyan. Los ladrillos visibles están activos (comprobamos la física, se dibuja, etc). Los ladrillos NO visibles están inactivos

Además, estos ladrillos los disponemos en una organización rectangular de F filas y C columnas

En el objeto constante LADRILLO colocamos todas estas propiedades y constantes. Se podrían definir como constantes separadas, pero es mucho mejor agruparlas para que el código nos quede más legible

Este es un ejemplo. En tu juego tendrás que seleccionar los valores adecuados (esta estructura es de prueba para los ejemplos)

const LADRILLO = {
  F: 2,   //-- Filas
  C: 3,   //-- Columnas
  w: 30,  //-- Anchura
  h: 20,  //-- Altura
  padding: 10,  //-- Espacio alrededor del ladrillo
  visible: true //-- Estado del ladrillo: activo o no
}

Construcción de la estructura inicial

La estructura para almacenar ladrillos es un Array bidimensional, formado por las F filas y C columnas

La construimos mediante bucles for anidados, que recorran todas las columnas y para cada columna las F filas. A cada ladrillo habrá que asignarle sus valores constantes (definidos en LADRILLO) y sus posiciones x,y en la pantalla, que habrá que calcularlas en función de su fila y su columna

Esta sería una forma de crearla:

//-- Creación de los ladrillos. La estructura se almacena 
//-- en el objeto ladrillos, que inicialmente está vacío
const ladrillos = [];

//-- Recorrer todas las filas. La variable i toma valores de 0 hasta F-1 (número de filas)
for (let i = 0; i < LADRILLO.F; i++) {
  ladrillo[i] = [];  //-- Inicializar la fila. Las filas son a su vez Arrays que inicialmente están vacíos

  //-- Recorrer las C columnas de la fila i. La variable j toma valores de 0 hasta C-1 (numero de columnas)
  for (let j = 0; j < LADRILLO.C; j++) {

    //-- Calcular valores para el ladrillo de la fila i y la columna j
    //-- Algunos valores son constates. Otros depeden de i y j
    ladrillos[i][j] = {
      x: (LADRILLO.w + LADRILLO.padding) * j,
      y: (LADRILLO.h + LADRILLO.padding) * i,
      w: LADRILLO.w,
      h: LADRILLO.h,
      padding: LADRILLO.padding,
      visible: LADRILLO.visible
    };
  }
}

Dibujo de los ladrillos

Para dibujar los ladrillos habrá que recorrer esta estructura y si el ladrillo situado en (i,j) es visible, entonces se dibujará

//-- Dibujar ladrillos
for (let i = 0; i < LADRILLO.F; i++) {
    for (let j = 0; j < LADRILLO.C; j++) {

      //-- Si el ladrillo es visible se pinta
      if (ladrillos[i][j].visible) {
        ctx.beginPath();
        ctx.rect(ladrillos[i][j].x, ladrillos[i][j].y, LADRILLO.w, LADRILLO.h);
        ctx.fillStyle = 'blue';
        ctx.fill();
        ctx.closePath();
      }
    }
}

Detección de la colisión

Para detectar si la bola ha colisionado con algún ladrillo habrá que construir una función que por cada nueva posición de la bola copruebe si ha contactado con algún ladrillo. Si es así, el ladrillo tendrá que pasar al estado *no visible

La comprobación de la colisión sólo se realiza para los ladrillos visibles

El esquema de esta función es el siguiente:

* Recorrer todas las filas y columnas de ladrillos
  * Si el ladrillo (i,j) es visible:
    * Si la bola está en contacto con el ladrillo (i,j):
      * Hacer que el ladrillo (i,j) pase a no visible
      * Cambiar la velocidad de la bola según el choque (rebote)

Ejemplo 1: Creación y dibujo de los ladrillos

En este ejemplo se muestra cómo dibujar una formación de F filas de ladrillos situados en C columnas. Inicialmente F=2 y C=3

Para comprobar que funciona la propiedad de visibilidad, una vez creada la estructura de ladrillos el ladrillo situado en la fila 0 y columna 1 se hace invisible:

ladrillos[0][1].visible = false;

Al dibujar a formación este ladrillo NO aparecerá

  • Fichero Ej-01.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">
    <script src="Ej-01.js" defer></script>
    <title>Ejemplo 1</title>
</head>
<body>
    <canvas id="canvas"></canvas>
</body>
</html>
  • Fichero Ej-01js:
const canvas = document.getElementById("canvas");

canvas.width = 300;
canvas.height = 100;

const ctx = canvas.getContext("2d");

//-- Constantes de los ladrillos
const LADRILLO = {
    F: 2,  // Filas
    C: 3,  // Columnas
    w: 30,
    h: 20,
    origen_x: 0,
    origen_y: 0,
    padding: 5,
    visible: true
};

//-- Estructura de los ladrillos
const ladrillos = [];

for (let i = 0; i < LADRILLO.F; i++) {
    ladrillos[i] = [];
    for (let j = 0; j < LADRILLO.C; j++) {
      ladrillos[i][j] = {
          x: (LADRILLO.w + LADRILLO.padding) * j,
          y: (LADRILLO.h + LADRILLO.padding) * i,
          w: LADRILLO.w,
          h: LADRILLO.h,
          padding: LADRILLO.padding,
          visible: LADRILLO.visible
        };
    }
}

ladrillos[0][1].visible = false;


//-- Dibujar ladrillos
for (let i = 0; i < LADRILLO.F; i++) {
    for (let j = 0; j < LADRILLO.C; j++) {

      //-- Si el ladrillo es visible se pinta
      if (ladrillos[i][j].visible) {
        ctx.beginPath();
        ctx.rect(ladrillos[i][j].x, ladrillos[i][j].y, LADRILLO.w, LADRILLO.h);
        ctx.fillStyle = 'blue';
        ctx.fill();
        ctx.closePath();
      }
    }
}

Esto es lo que obtenemos:

Vemos que el ladrillo (0,1) no aparece

¡A practicar!

Para implementar los ladrillos en tu juego se proponen los siguientes ejercicios

Ejercicio 1: Dibujo de los ladrillos

Estudia el ejemplo 1 de esta sesión para entender cómo funciona. Adáptalo para dibujar mayor cantidad de ladrillos y en una posición diferente (ya que estos ladrillos se dibuja a partir de la posición (0,0))

Integralo en tu juego para que se dibujen (aunque no haya colisiones todavía)

Ejercicio 2: Función de colisión con los ladrillos

En este momento tendrás una bola que rebota en las paredes y la raqueta, pero que pasa por encima de los ladrillos. Deberás implementar la funcioń de detección de colisión con la bola con los ladrillos e integrarla en tu juego

Para que la detección de colisiones sea más fácil, parte primero de una bola pequeña y realiza las comprobaciones sólo con las coordenadas de su centro. Cuando ya te funcione, modifícalo para que la comprobación se haga tendiendo en cuenta el radio de la bola (aunque la bola sea redonda, supón para las colisiones que es un cuadrado)

Ejercicio 3: Retoques finales

Una vez que ya tengas la colisión hecha, ya casi tendrás el juego listo. Sólo te faltarán los toques finales: incrementar el número de puntos al romper un ladrillo, detectar cuándo has terminado la partida (cuando ya no haya más ladrillos visibles), etc. Repasa las especificaciones del práctica para implementar todo lo pedido

Ejercicio 4: Mejoras

Cuando ya tengas el juego funcionando según las especificacioens, es el momento de que hagas mejoras si te apetece y quieres subir nota. ¡La creatividad al poder!

Resumen de tareas a realizar

  • Haz los ejercicios propuestos en esta sesión. No olvides subir todas las pruebas que hagas al repo, en la carpeta P3. Aunque sean pruebas temporales que luego no formen parte del juego, súbelas. Son una prueba objetiva de tu trabajo y de tus "horas de vuelo"

Conclusiones

Con lo que se ha indicado en esta sesión ya deberías ser capaz de terminar tu juego

Autor

Creditos

Licencia

Enlaces

Clone this wiki locally