G RADO EN D ISEÑO Y D ESARROLLO DE V IDEOJUEGOS
VJ1217: D ISEÑO Y D ESARROLLO DE J UEGOS W EB
Prueba de programación
2 de junio de 2023
Usuario examen: usuario-de-examen
Contraseña: la-del-examen
Nombre y apellidos:
DNI: dni-de-examen
Previo. Descarga en el Escritorio el archivo [Link] de Aula Virtual (sección Exams). Desempa-
quétalo. Obtendrás la carpeta ExamenJunio: tiene tres subcarpetas para cada una de las siguientes secciones.
MUY IMPORTANTE: Ejecuta VS Code de la siguiente manera: haz clic en el botón Inicio de Win-
dows, despliega el grupo Programació y allí ejecuta la opción Visual Studio Code (está abajo del
todo). Debes proceder de esta manera, ya que, en caso contrario, no se cargarán las extensiones.
ATENCIÓN: A la hora de probar el resultado de los diferentes ejercicios en el navegador debes emplear
la opción Open with Live Server de VS Code tal como hemos visto en las clases de prácticas.
HTML5/CSS3 (2,5 ptos.)
Abre en VS Code la carpeta Bloque I - HTML-CSS. A continuación, abre los ficheros [Link]
y [Link]. Antes de proceder a resolver las siguientes cuestiones, estudia el código de in-
[Link] y asegúrate de comprender su propósito y efecto:
1. Explica, en un párrafo de texto a escribir en [Link] (usa el propio VS Code para ello), cuál
es el propósito de la siguiente propiedad CSS: transform: translate(-50%, -50%);
2. Modifica el HTML y/o el CSS del ejercicio anterior de modo que se centre (horizontal y verticalmente) el
recuadro azul en la ventana del navegador sin emplear etiquetas obsoletas como <center>.
3. Extrae el código CSS del fichero HTML y haz que cargue los estilos de un fichero externo que se llame
[Link]. Debes crear este fichero dentro de la carpeta css.
4. Ahora, añade al pie del recuadro el texto Pie de texto, también centrado horizontal y verticalmente. Crea
para ello una clase que se llame piedetexto en [Link]. Escribe el texto en un <div> dentro
del <div> de la clase container pero debajo del de la clase box. Por encima del recuadro añade el texto
Cabecera (en su propio <div>) en cuerpo de letra h1, también centrado y encima del <div> de la clase
box, en una clase que se llame encabezado (también en [Link]).
5. Pon el pie de texto en la tipografía Arial y enlázalo a la web de la UJI. Haz que cuando el ratón pase por
encima del enlace la tipografía se vuelva negrita y con un color de fondo amarillo. El resultado final de
este ejercicio debería ser similar al que se muestra en la Figura 1.
JavaScript (4,0 ptos.)
Abre en VS Code la carpeta Bloque II - JavaScript. Al abrirla, encontrarás un fichero HTML, denomi-
nado [Link] y tres carpetas: css, imgs y js. Dentro de cada carpeta encontrarás, respectivamente,
el fichero [Link], tres imágenes en formato PNG y el fichero [Link]. Este juego
VJ1217: Diseño y Desarrollo de Juegos Web Prueba de programación
Figura 1: Aspecto final de la página en el bloque de HTML5/CSS3
incluye gran parte del código del juego de la práctica 3. Antes de empezar examina el contenido de los fi-
cheros [Link] y [Link]. También examina el contenido del fichero [Link],
concretamente el código de las clases SpaceItem y GameArea, y el de las funciones startGame, updateGame,
updateChrono y endGame. Intenta hacerte una idea somera de su funcionamiento.
Debes modificar los ficheros HTML y JavaScript para resolver las cuestiones siguientes. Todas las cons-
tantes y variables que se pide usar están ya declaradas y debidamente inicializadas. Consulta el vídeo
que hay disponible en Aula Virtual, que muestra el funcionamiento tras las modificaciones pedidas.
1. Si intentas ejecutar el juego verás que solo se observa un canvas con fondo azul. Para que el juego comience
a funcionar tienes que completar el código de las funciones makeShuttle y makeAsteroids.
En la primera, debes crear una instancia de la clase SpaceItem y almacenarla en la variable global shuttle
para crear la nave espacial. Observa los argumentos del constructor. La nave se situará inicialmente en la
posición GAME_AREA_WIDTH/2 en X, en la posición GAME_AREA_HEIGHT - SPACE_SHIP_SIZE
en Y , el ancho y el alto serán ambos SPACE_SHIP_SIZE, el elemento imagen que debe pasarse al cons-
tructor se creará usando el fichero [Link] y el valor del argumento active será true.
En la segunda, crearás exactamente MAX_ASTEROIDS instancias de la misma clase, SpaceItem, y las
almacenarás en el vector asteroidsGroup, ya declarado e inicializado. Ahí estarán los asteroides que apa-
recen en el juego. Todas estas instancias estarán en la posición -ASTEROID_SIZE tanto en X como en
Y , tendrán el mismo ancho y alto, ASTEROID_SIZE, emplearán el fichero [Link] para crear
su elemento imagen y el valor de su argumento active será false.
NOTA: Si no sabes cómo crear un elemento imagen y pasarlo al constructor, y con el fin de que puedas
continuar y probar el resto de apartados, dibuja un cuadrado rojo para la nave y cuadrados de color negro
para los asteroides. En este caso, además, tendrás que reescribir el código del método render de la clase
SpaceItem. Obviamente, esto se valorará mucho menos.
2. Escribe el código del método drawChrono de la clase GameArea. Esta función dibujará en el canvas el
texto que se la pasa como parámetro (se actualiza en updateChrono: no debes modificar esta función). El
texto se dibujará en color blanco, con letra Arial de 12 pt y con valor “start” para la propiedad textAlign.
El texto se dibujará en las posiciones CHRONO_X y CHRONO_Y en X e Y , respectivamente.
3. Si ejecutas el juego, observarás que aparece la nave (o un cuadrado rojo) y la puedes mover con los
cursores (izquierda, derecha, adelante, atrás) y que van cayendo asteroides (o cuadrados negros) desde la
2
VJ1217: Diseño y Desarrollo de Juegos Web Prueba de programación
parte superior del canvas. A la tercera colisión de la nave con un asteroide el juego terminará, quedando
el canvas vacío. Lo que queremos ahora es que el juego no comience abruptamente: queremos añadir un
botón “Play” que dé inicio al juego al hacer clic sobre él. La imagen de dicho botón es la del fichero
[Link]. Te pedimos que:
a) Añadas dicha imagen al fichero [Link], concretamente dentro del bloque <div> identificado
con la etiqueta “playbutton”.
b) Añadas el correspondiente atributo en la imagen para que ejecute la función que da inicio al juego al
hacer clic en ella y solo en ese momento (también tendrás que modificar el fichero [Link]).
c) Finalmente, añadas las instrucciones necesarias al principio de la función startGame del fichero
[Link] para almacenar en la variable global playButtonDiv el elemento <div> “play-
button” y ocultarlo (no se ha de mostrar en la ventana del navegador).
4. En el fichero [Link] hay un <div> identificado mediante la etiqueta “livesleft” (y reglas CSS en
[Link] para darle formato: no las toques). Debes usar este elemento <div> para gestionar el
indicador de las “vidas” (naves) del juego. Modifica solo el fichero [Link]. Tienes que:
a) Escribir el código necesario en la función renderLives de la clase GameArea para insertar LIVES
imágenes de la nave en dicho <div>. Debes usar obligatoriamente un bucle para ello. Dentro
de dicho bucle crearás un elemento <img> con los tres atributos adecuados para: (i) emplear la
imagen [Link] y (ii) ponerle un ancho y un alto de SPACE_SHIP_SIZE/2. No olvides usar
[Link] para almacenar el <div> “livesleft”.
b) Después, llamar a dicha función renderLives como última instrucción de la función initialise en la
misma clase GameArea.
c) A continuación, escribir el código necesario en la función deleteLife, también de GameArea, para
borrar una de las “vidas” (naves) insertadas en dicho <div>. Se recomienda que, simplemente,
borres el último nodo (“hijo”) insertado.
d) Finalmente, invoques a esta función deleteLife desde la función updateGame cada vez que se produce
una colisión entre la nave y un asteroide y disminuye una “vida”. Emplea la instancia adecuada de la
clase GameArea para ello.
5. Ahora mismo, se puede jugar al juego pero éste termina de manera abrupta (un canvas vacío) y no permite
reiniciarlo. Te pedimos que palíes este problema:
a) En primer lugar, escribe el código de la función removeCanvas de la clase GameArea: simplemente
debe eliminarse el canvas creado y almacenado en uno de los atributos de dicha clase. Fíjate que debe
eliminarse del <div> “gameplay” almacenado en otro de los atributos de la clase.
b) Después, escribe el código de la función drawFinalBanner que está justo debajo. Esta función debe
dibujar en el canvas el texto que se la pasa como parámetro. El texto se dibujará en el mismo centro
del canvas, en color negro, con letra Arial de 36 pt y con valor “center” para la propiedad textAlign.
c) Finalmente, escribe el código necesario al final de la función endGame para que: (i) se llame a
la función drawFinalBanner empleando la instancia adecuada de la clase GameArea y pasando el
texto “GAME OVER!” como parámetro, y (ii) ejecutar el código necesario para reiniciar el juego
transcurridos cinco segundos. Para reiniciar el juego basta con ejecutar removeCanvas (nuevamente
con la instancia adecuada) y volver a visualizar el elemento <div> “playbutton” que previamente
habías almacenado en la variable global playButtonDiv (y habías ocultado).
Phaser (3,5 ptos.)
Abre en VS Code la carpeta Bloque III - Phaser. Al abrirla, encontrarás una estructura de carpetas y
ficheros que conforman un proyecto de juego Phaser similar a los de las clases de prácticas. El ejercicio con-
siste en (1) rotar con el ratón la imagen de una paleta de colores; (2) soltar una gota con cada clic; (3) agrandar
la paleta cuando le alcanza una gota; (4) realizar una animación de la paleta al final. Para ello, se da ya parte
del código y se necesita completar las siguientes funciones según las indicaciones correspondientes. Fíjate
también que se han declarado una serie de variables en el fichero [Link] para que las utilices en
3
VJ1217: Diseño y Desarrollo de Juegos Web Prueba de programación
los diferentes apartados de este bloque. Los nombres de dichas variables son lo suficientemente explíci-
tos, aunque en algunos apartados se mencionan directamente. Consulta el vídeo que hay disponible en Aula
Virtual, que muestra el funcionamiento tras las modificaciones pedidas.
1. start() para añadir e iniciar el estado ’principal’ asociado a la variable estadoPrincipal ya
definida.
2. cargarAssets() para cargar las imágenes de la paleta de acuarelas y de una gota de agua, disponibles
en la carpeta assets/imgs. Asócialas con las claves ’paleta’ y ’gota’, respectivamente.
3. crearPaleta() para añadir la imagen de la paleta como sprite, no como imagen. Hazlo en la posición
(0, 0). Además:
a) reduce su tamaño al 30 %;
b) fija su ancla al centro de la imagen;
c) coloca la paleta en el centro del mundo, usando las variables y atributos oportunos (sin constantes ni
números mágicos); y
d) habilita su gestión con físicas “arcade”.
4. crearGotas() para crear un grupo de Phaser gotas, que contenga el número de gotas indicado como
parámetro de la función (numGotas). Cada gota se corresponde con la imagen con clave ’gota’ usada
en (2). Luego:
a) habilita las físicas sobre los elementos del grupo (o sea, cada una de las gotas);
b) fija el ancla de cada gota a su centro;
c) escala cada gota al 5 % del tamaño de la imagen original;
d) indica que se quiere comprobar que una gota alcanza los límites del mundo; e
e) indica que cuando se salga una gota de estos límites se llame a resetMember(), ya definida.
5. actualizar() para: (i) rotar la paleta en sentido horario/antihorario según sentido de movimiento
del ratón (derecha o izquierda, respectivamente), y de forma proporcional a la magnitud de la velocidad
horizontal del ratón, según el valor de proporcionalidad factor_rotacion, ya definido, y (ii) soltar
una gota de agua (función soltarGota(), ya existe) cuando se hace clic en el botón izquierdo del ratón.
6. soltarGota() para que la velocidad v = (vx , vy ) de la nueva gota sea una cantidad aleatoria entre 15 y
20 para la componente horizontal vx , y entre 30 y 45 para su componente vertical vy . Utiliza oportunamente
la función randomInRange() que te proporcionamos.
7. aguaMojaPaleta() para, además de agrandar la paleta (agrandarPaleta(), a definir en (8)),
a) eliminar la gota con la que se ha detectado el solapamiento;
b) incrementar en una unidad la humedad de la paleta; y
c) si la humedad supera MIN_HUMEDAD, ejecutar eliminarGotas() y animarPaleta(). La
función eliminarGotas() ya existe y la función animarPaleta() se pide en (9).
8. agrandarPaleta() para escalar la paleta en un factor FACTOR_ESCALA_PALETA. Usa los atributos
scale.x y scale.y.
9. animarPaleta() para que, primero, y mediante un tween, se desplace al extremo izquierdo del mundo
(sin ocultarse), durante 1 segundo; y, segundo, cuando este tween termine, se inicie un segundo tween que
consista en desplazarse cíclica e indefinidamente al extremo derecho (también sin ocultarse) y seguida-
mente al izquierdo, cada uno con una duración de 2 segundos. Define este segundo tween en una función
adicional empezarOtroTween().
Entrega: Una vez hayas concluido, abre la carpeta Espai en disc personal —¡Ojo! Debes abrirla— que
hay en el Escritorio de Windows y copia, dentro de ella, la carpeta ExamenJunio, que debe tener todos
los contenidos de los ejercicios que has estado desarrollando. Si no copias esta carpeta en Espai en disc
personal será como si no hubieses efectuado el examen.