Videojuegos Educativos DSL

De wikiPLII
Saltar a: navegación, buscar
Videojuegos Educativos DSL
Arcade Tongame: editor de juegos e-learning
Miembros Juan Antonio Caballero
Carlos-Helder García
Curso Académico 2012/2013
Tipo de Contribución DSL
Keywords MDD, DSL, libgdx

Contenido

Resumen

Se va a desarrollar un DSL visual mediante el cuál se podrán generar distintos juegos orientados al aprendizaje de idiomas, para lo cuál el usuario del editor podrá crear varias pantallas/fases para cada juego representadas a través de un grid o cuadrícula por cada fase a la que el usuario podrá añadir una serie de objetos disponibles a un cuadrado o varios. Piénsese en el juego de "hundir la flota" para poder imaginarse mejor la interfaz gráfica que podrá manejar el usuario del DSL.

La idea básica de estos juegos consiste en que el jugador al entrar en una fase se le plantee una pregunta (mediante texto o audio) y para resolverlo tenga que mover un personaje para seleccionar palabras mostradas por pantalla que podrán ser correctas o incorrectas: las correctas aumentarán la puntuación del usuario mientras que las incorrectas harán que esta puntuación baje.

Una vez resuelta o fallada la pregunta se abrirá una nueva puerta (dependiendo de si acertó o falló) que dará paso a una nueva fase, así hasta llegar a la última.

Posibles juegos que el usuario del DSL podría generar:

  • Suena una palabra y el jugador debe pasar sobre ella para pasar la fase. Si pasa por una incorrecta pierde puntos.
  • Aparecen varias palabras y el jugador debe seleccionar la que no está relacionada con las demás.
  • Suena la descripción de la palabra y el jugador debe pasar por la palabra correcta,
  • Hay que pasar por las palabras en el orden correcto 5: hay miles de posibilidades, ¡dejemos al usuario del DSL volar su imaginación! :)

Cabe destacar que el código generado por el DSL será en java para ejecutarlos como aplicaciones de escritorio. Este código hará uso de la librería libgdx para la implementación del juego.

Proceso de Desarrollo

En esta sección se describirá todo lo referente al proceso de desarrollo utilizado para este proyecto.

Metodología Software

Vamos a seguir un método de desarrollo ágil del software. Dicho método está basado en el desarrollo iterativo e incremental, donde los requisitos y las soluciones para satisfacerlos van evolucionando y aumentando con el tiempo, de forma que al final de cada iteración el usuario del DSL tendrá una versión funcional.

En cada nueva iteración se añadirán una serie de requisitos mínimos que resulten en una nueva versión con una nueva funcionalidad. Se trata, por tanto, de un prototipado evolutivo.

Lo que ocurre en nuestro caso es que todo el entregable para PL2 constituye únicamente la primera iteración del DSL. Se trata de una idea muy novedosa para ayudar a aprender un idioma y todavía no conocemos el impacto que tendrá. Según resulte, se continuará el prototipado evolutivo o no.

Esquema general de una metodologia ágil para el desarrollo de software

Planificación de tareas y responsabilidades

No habrá una clara división de tareas en la primera iteración. Esta decisión de debe a que todos los integrantes del grupo deberían tener los conocimientos básicos que constituyen la primera iteración de Arcade Tongame. No obstante, la división de responsabilidades se hará de forma en que quien tenga dicha responsabilidad será el encargado de investigar mejor el menester en cuestión e informar correctamente al resto de compañeros con el consiguiente ahorro en tiempo de investigación.

Ejemplo.jpg

Concurso Universitario de Software Libre

El software ha sido inscrito en el concurso. Unas de las ventajas del mismo y, en general del software libre, es la posibilidad de que otros programadores ayuden en la programación del proyecto. No esperamos que esta colaboración llegue en la primera iteración del proyecto pero consideramos importante considerar que esa posibilidad podría llegar a ocurrir y por tanto, formaría parte del desarrollo del proyecto.

Proyecto: Enlace al proyecto Arcade Tongame en la web del concurso

Documentación Técnica

En esta sección se incluirá toda la documentación asociada al ciclo de vida de desarrollo del proyecto: análisis, diseño, implementación, pruebas y preparación de instrucciones de uso/instalación.

Análisis de los Requisitos

Actores

  • Usuario: persona que usará este metamodelo para crear el juego final.
  • Jugador: persona que finalmente jugará al juego.
  • Editor: entorno que manejará el usuario para crear los juegos.
  • Juego: modelo creado por el usuario y con el que interactuará el jugador.

Requisitos de Información

  • El juego mostrará al jugador los puntos conseguidos.
  • El editor permitirá al usuario definir un tipo principal de objetos: las pantallas de juego.
  • Las pantallas podrán contener los siguientes tipos de objetos:
    • Objetos de texto.
    • Objetos de audio.
    • Objetos obstáculos.
    • Objetos de entrada.
    • Objetos de salida.

Requisitos Funcionales

  • El usuario podrá definir el tamaño de cada pantalla (cuadros nxm).
  • El editor permitirá al usuario añadir objetos a las pantallas. Cada objeto podrá ocupar uno o más cuadros de la cuadrícula.
  • El usuario podrá unir dos o más pantallas usando objetos de entrada y de salida.
  • El jugador controlará un personaje que se podrá mover por la pantalla.
  • El usuario podrá incluir obstáculos en los cuadros de una fase por los cuáles no podrá pasar el personaje.
  • El sistema redimensionará los objetos de texto número de cuadros que especifique el usuario.
  • El jugador activará un audio cuando el personaje interactúe con dicho objeto de audio.
  • El usuario podrá asociar un audio a una pantalla.
  • El usuario podrá asociar un texto a una pantalla.
  • El usuario podrá asociar un audio a los objetos de entrada y de salida.
  • El usuario podrá asociar un texto a los objetos de entrada y de salida.
  • El usuario podrá indicar que un objeto de salida es la posición final del juego.
  • El usuario podrá incluir en una misma pantalla uno o más objetos de entrada y de salida.
  • El usuario podrá asociar objetos de texto y/o audio a objetos de salida, de manera, que en función de los objetos activados por el jugador se active un objeto de salida u otro.
  • Una vez abierto un objeto de salida el sistema siempre lo mantiene abierto.
  • El sistema debe controlar el tiempo que el jugador tarda en llegar de la casilla de inicio a la casilla de fin.
  • El sistema controlará que el jugador no pueda mover al personaje fuera de la pantalla.

Requisitos No Funcionales

Deberá funciona en cualquier equipo con Windows o Linux con la máquina virtual de Java instalada.

Trabajo futuro

  • Permitir al jugador introducir texto por teclado.
  • Permitir al jugador introducir audio por el micrófono del ordenador (necesario reconocedor de voz). Soñar es gratis :)


Diseño

En este apartado se habla sobre el diseño del DSL, de manera que se muestra el diagrama de las metaclases, la interfaz de usuario del editor visual y su maping a código.

Diagrama de las Metaclases

Tongame diagrama análisis v5.png

Interfaz de Usuario

Para el editor del DSL se ha definido una interfaz de usuario la cuál consiste en una paleta de elementos a la derecha y desde los cuáles el usuario del editor podrá arrastrar los elementos que desee al fondo blanco, así como conectarlos entre sí.

A las propiedades de cada elemento se accederá desde una pestaña ubicada en la parte inferior de la pantalla al pulsar sobre el elemento en cuestión. A continuación se muestra un ejemplo de la interfaz gráfica del editor:

RCP application ejemplo.png


Paleta de herramientas

La paleta de herramientas se divide en dos partes: Objects y Connections. En primer lugar se van a detallar los objetos:


In.png Entradas que puede tener una Stage. Indican la posible posición inicial del jugador en la fase.

Out.png Salidas que puede tener una Stage. Sirven de enlace a otra Stage.

Sound.png Elementos de sonido que puede tener una Stage. En la propiedad Filename se indicará el nombre del archivo de sonido.

Stage.png Fases del juego. Sirven como contenedores del resto de elementos.

Text.png Texto que puede contener la Stage.

Wall.png Muros que puede tener una Stage. Sirven para dificultar el avance del jugador.


Una vez descritos los objetos, se procede a comentar las conexiones de la paleta de herramientas:

Opens.png Enlaza un elemento con una salida. Indica que la interacción con el elemento abre la salida.

Stagesconnection.png Enlaza una salida con la entrada de otra fase.

Maping de las Metaclases

A continuación mostramos un resumen del mapeo que se realizará respecto a las metaclases y sus relaciones indicando las cabeceras de las clases y algunos comentarios.

Game

En primer lugar se creará un archivo MyGame.java que será la clase principal del juego, el cuál contendrá lo siguiente:

 public class MyGame extends Game implements ApplicationListener{

     static final float WORLD_WIDTH = (int)[aGame.width/];
     static final float WORLD_HEIGHT = (int)[aGame.height/];

     //atributos por defecto
     //incluye las pantallas del juego
     StageScreen[] stages;
     
     public void create() {
         //contenido del método
         //se define al protagonista
         prota = new Player ();
         //AQUÍ VAN A RELLENARSE EL VECTOR DE FASES
         //se indica que la primera pantalla será la primera incluida en el vector
         setScreen(stages[0]);
         }

	 // Método para añadir Stage al vector stages
     }

Una vez creada la clase principal creamos el archivo Player.java que contendrá los métodos del protagonista del juego:

 public class Player {
     //atributos por defecto

     public Player (){
         //contenido del constructor
     }
	
     //Método al que se llama en cada render de las distintas Stages o Pantallas
     public void render(float delta, OrthographicCamera guiCam) {
         //contenido del método
     }
 }

Debe de crearse un archivo StageScreen.java el cuál hacer referencia a las pantallas del juego.

 public class StageScreen implements Screen {
     //atributos por defecto
     // Vector de sonidos
     Vector sonidos = new Vector();
     // Vector de textos
     Vector textos = new Vector();
     // Vector de muros
     Vector muros = new Vector();
     // Vector de entradas
     Vector entradas = new Vector();
     // Vector de salidas
     Vector salidas = new Vector();

     public StageScreen(MyGame game){
	 //contenido del constructor, se crean los objetos que contendrá
     }
	
     //Método que renderiza la pantalla (se va llamando continuamente)
     public void render(float delta) {
	 //contenido del método
     }

     //Se incluyen el resto de métodos de la clase
 }

Además de la clase para las stage, también han de crearse las clases MyOut, MyIn, MyText y MySound. De estas clases no indicamos nada aquí ya que el mapeo referente a estos elementos afecta a los objetos creados y no a la implementación de las clases.

Finalmente se crea la clase que crea el juego utilizando la clase MyGame definida anteriormente.

 public class JuegoDesktop {
     public static void main (String[] argv) {
	// Heigth y Width vienen definidos desde el editor
        new JoglApplication(new MyGame(), "Arcade Tongame", (int)[aGame.width/], (int)[aGame.height/], false);
     }
}

Todo el mapeo visto en este apartado hace referencia a todas las clases necesarias para que funcione el juego. En los siguientes apartados vamos a ver como se mapean el resto de elementos y se añaden al juego.

Stage

En el método MyGame.create() indicamos las fases:

//creacion del vector de fases
[for(s: Stage | aGame.stages)]
	stages.add(new StageScreen(this));
[/for]

StagesConnections

Se mapea como un enlace entre dos fases, de forma que cuando el jugador se posicione sobre un Out abierta, pasará a la StageScreen conectada.

Element

Element es una metaclase abstracta por lo que no se crearán instancias de ella.

Opens

Cualquier elemento puede abrir una salida. Ejemplo de mapeo de un texto que abre una salida:

//Justo después de añadirse al vector de textos de la fase
[if not(e.oclAsType(Text).opens.oclIsUndefined())]
	mytext.establecerSalida("[e.oclAsType(Text).opens.name/]", salidas);
[/if]

containsElements

Por cada elemento incluido en una Stage se añade un nuevo objeto del tipo de elemento a su vector correspondiente. Lo veremos más adelante.

IMPORTANTE: Como de momento sólo contamos con una fase los elementos se inicializan directamente en el código de la propia clase, en una versión futura se añadirían al crearse los objetos de las fases en el método create() de la clase MyGame.

Text

Se añaden al vector de textos de la StageScreen:

// Creamos los textos
MyText mytext;
float e_width;
float e_height;
[for(e: Element | aGame.stages.elements)]
	[if(e.oclIsTypeOf(Text))]
		[if (e.size_x = 0.0)]
			e_width = MyText.DEFAULT_W;
		[else]				
			e_width = (float)[e.size_x/];
		[/if]
		[if (e.size_x = 0.0)]
			e_height = MyText.DEFAULT_H;
		[else]				
			e_height = (float)[e.size_y/];
		[/if]				
		mytext = new MyText("[e.oclAsType(Text).text/]", e_width, e_height, (float)[e.position_x/], (float)e.position_y/]);
        	//se añade al vector
        	textos.add(mytext);
		[if not(e.oclAsType(Text).opens.oclIsUndefined())]
			mytext.establecerSalida("[e.oclAsType(Text).opens.name/]", salidas);
		[/if]
	[/if]
[/for]

Sound

Se añaden al vector de sonidos de la StageScreen:

// Creamos los sonidos
TextureRegion texIpod = new TextureRegion(new Texture(
Gdx.files.internal("data/ipod.png")), 0, 0, 64, 64);        		       		
Image im;
Music mu;

[for(e: Element | aGame.stages.elements)]
	[if(e.oclIsTypeOf(Sound))]
		im = new Image("ipod", texIpod);
        	im.x = (float)[e.position_x/];
        	im.y = (float)[e.position_y/];
        	im.width = (float)[e.size_x/];
        	im.height = (float)[e.size_y/];
		mu = Gdx.audio.newMusic(Gdx.files.getFileHandle("data/[e.oclAsType(Sound).filename/]", FileType.Internal));
        	//se añade al vector
        	sonidos.add(new MySound(im,mu));
	[/if]
[/for]

Wall

Se añaden al vector de muros de la StageScreen:

//Creamos los muros
Image w;
TextureRegion texWall = new TextureRegion(new Texture(
				Gdx.files.internal("data/Wall.png")), 0, 0, 64, 64);
[for(e: Element | aGame.stages.elements)]
	[if(e.oclIsTypeOf(Wall))]
		w = new Image("Wall", texWall);
        	w.x = (float)[e.position_x/];
        	w.y = (float)[e.position_y/];
        	w.width = (float)[e.size_x/];
        	w.height = (float)[e.size_y/];
        	//se añade al vector y a la stage
        	muros.add(w);
		stage.addActor(w);
	[/if]
[/for]

In

Se añaden al vector de entradas de la StageScreen:

//Creamos las entradas
MyIn mi;
[for(e: Element | aGame.stages.elements)]
	[if(e.oclIsTypeOf(In))]
		mi = new MyIn((float)[e.position_x/], (float)[e.position_y/], [e.oclAsType(In).isStart/]);
		entradas.add(mi);
	[/if]
[/for]

Out

Se añaden al vector de salidas de la StageScreen:

// Creamos las salidas
MyOut mo;
[for(e: Element | aGame.stages.elements)]
	[if(e.oclIsTypeOf(Out))]
        	mo = new MyOut((float)[e.position_x/], (float)[e.position_y/], 
(float)[e.size_x/], (float)[e.size_y/], [e.oclAsType(Out).isOpen/], "[e.name/]");
		salidas.add(mo);
	[/if]
[/for]

Implementación

La implementación del DSL consta de tres grandes etapas: Definición del metamodelo, Creación del editor visual y Generación de código. Procedemos a comentar los aspectos tecnológicos de estas etapas.

Definición del Metamodelo

Para la definición del metamodelo se ha utilizado el lenguaje Emfatic, un editor textual para la creación de modelos ecore. Emfatic posee una sintaxis muy similar a la de Java. A continuación se muestra un ejemplo del código Emfatic de nuestro DSL, el cuál se ubica en el archivo ArcadeTongame_editor.emf del proyecto.

@namespace(uri="http://wikis.uca.es/wikiPLII/index.php/Videojuegos_Educativos_DSL", prefix="ArcadeTongame_editor")
@gmf(foo="bar")

package ArcadeTongame_editor;

@gmf.diagram(foo="bar")
class Game {
    val Stage[*] stages;
    val StagesConnection[*] stagesconnections;
    attr float height;
    attr float width;
}

Creación del editor visual

Para la creación de nuestro editor visual GMF hemos utilizado la herramienta EuGENia, ya que automatiza muchos pasos de la creación del editor.

Únicamente es necesario pulsar botón derecho sobre el archivo ArcadeTongame_editor.emf antes creado para abrir el menú contextual y seleccionar la opción Eugenia --> Generate GMF Editor.

Producto RCP

El editor se puede generar como producto RCP, pero para ello es necesario usar GMF además de Eugenia. Al ser un proceso algo complejo se detallan los pasos a seguir:

  • Con el archivo emf generamos el ecore.
  • Con el archivo ecore y usando EuGENia se generan los archivos gmftool, gmfgraph y gmfmap.
  • A partir del archivo gmfmap se crea el gmfgen (en el asistente se debe seleccionar 'aplicacion RCP').
  • Con el archivo ecore y usando EuGENia generamos el genmodel.
  • En las propiedades del genmodel es necesario indicar Runtime Platform = RCP. Una vez hecho esto se selecciona desde el genmodel la opción generate All y se crean los proyectos edit, editor y test.
  • Con el GMF Dashboard se seleccionan todos los modelos anteriormente generados y se crea el proyecto diagram. Sin embargo, es importante indicar que para incluir imágenes .svg en el editor necesitamos instalar el paquete GMF Tooling Experimental.
  • Al generar el proyecto diagram no se utilizan los plugin de este paquete correctamente, por lo que hay que corregir algunos errores en el proyecto diagram. Basta con pinchar sobre el error y seleccionar la opción Fix Project Setup. De esta forma se importan las dependencias necesarias de forma automática.

Generación de código

Finalmente, para implementar la tranformación de modelo a código (M2T) se ha utilizado el sistema de generación de código Acceleo. Todo el código Acceleo se encuentra en el archivo generateJuegoDesktopModule.mtl. A continuación se muestra un trozo de código de ejemplo:

[comment encoding = Cp1252 /]
[**
 * The documentation of the module.
 */]
[module generateJuegoDesktopModule('/Eugenia_ArcadeTongame/model/ArcadeTongame_editor.ecore')/]

[**
 * The documentation of the template.
 * @param aGame
 */]
[template public generateJuegoDesktopModule(aGame : Game)]
	
[comment @main /]
[file ('JuegoDesktop.java', false, 'Cp1252')]
package org.pl2.dslvideojuegos;

import com.badlogic.gdx.backends.jogl.JoglApplication;

public class JuegoDesktop {
	public static void main (String['['/][']'/] argv) {
		new JoglApplication(new MyGame(), "Arcade Tongame", (int)[aGame.width/], (int)[aGame.height/], false);
	}
}	[/file]


Pruebas

Las pruebas realizadas han sido de dos tipos: pruebas creadas sobre un modelo creado como instancia desde Eclipse y las pruebas sobre modelos generados con el producto RCP.

Las primeras pruebas se han utilizado durante el desarrollo para añadir funcionalidades al juego o para probar distintos datos de un mismo objeto (por ejemplo distinas posiciones o tamaños). Por tanto, aquí se van a mostrar 3 pruebas creadas con el RCP y su resultado en la generación de código:

  1. Prueba 1: Juego vacío.

Prueba1.png

Prueba1 juego.png


  1. Prueba 2: Juego con dos Stages (sólo muestra la primera).

Prueba2.png

Prueba2 juego.png


  1. Prueba 3: Juego con los mismos datos que se van a usar durante la presentación.

Prueba3editor.png

Prueba juego3.png

Instalación

La instalación del DSL consta de tres pasos fundamentales:

  1. Descarga del producto RCP
  1. Descarga del proyecto Acceleo encargado de la generación de código.
  1. Importación del proyecto en un entorno Eclipse. Configurar en Run Configurations... de Eclipse la ejecución del archivo .mtl del proyecto importado:

Configuracion.png

Ejemplo de creación de un juego

  1. Abrimos el producto RCP, creamos un modelo y lo guardamos con el nombre deseado (por ejemplo prueba1).
  1. Copiamos el archivo prueba1.arcadetongame_editor dentro de la carpeta model del proyecto Acceleo y le cambiamos la extensión a .xmi.
  1. Ejecutamos el archivo .mtl, cuya configuración indicamos en la instalación. Hay que tener en cuenta que para cada modelo distinto habría que poner un nombre distinto en la configuración realizada anteriormente.

Descargas

Enlaces externos

Libgdx Official Site

Libgdx Project Home

Libgdx Blog

Manual en español de Libdx

Información sobre lenguaje Emfatic

Herramientas personales
Espacios de nombres

Variantes
Acciones
Navegación
Herramientas