Esto se acaba…

Todo principio tiene un final, (o al menos eso esperemos xD) y este es el nuestro, nuestro punto final a las prácticas de esta apasionante asignatura que al menos…no nos deja indiferente a ninguno.
Porque…quien no se ha emocionado alguna vez cuando te compilaba ese pedazo de programa tras 5 horas de intento tras intento….o quien no se ha acordado de la gran familia de Microsoft y compañía cuando llegabas a las 9 de la mañana un viernes y veías q no funcionaba tu ordenador.
Esta asignatura nos ha dado grandes alegrías y tristezas y ahora en junio, nuestra fecha definitiva,  debemos enseñar a todos de lo que somos capaces y lo que hemos aprendido en este arduo camino.
Igual que este año España si pasará de cuartos nosotros este año si…si pasaremos del cuatro!!
Y con eso y las horas que hemos echado a esos grandes videojuegos (mención especial para este año donde la cosecha pinta muy elegante en mi opinión)…OBJETIVO CUMPLIDO.Nuestra valoración sobre las prácticas es por lo general buena pese a que en las últimas no prestáramos toda la atención necesaria porque estábamos liados con el juego. De hecho de la última no hay ni post (sorry!!)  pero si la cosecha de este año es elegante es debido también a este tipo de horas de trabajo xD. Las quejas sobre las prácticas son las de siempre, muy largas, pero hay que decir que gran parte de lo que no daba tiempo a hacer en clase se intentaba en casa (con más o menos fortuna).

En cuanto al blog…es una buena iniciativa en nuestra opinión ya que, además de que desde chiquitito ya se sabe que toda iniciativa que conlleve una subida de nota siempre se debe presuponer buena xD, también ha fomentado que, teniendo que escribir una entrada semanal, consigamos familiarizarnos aun más con el entorno java. También hemos podido solucionar dudas consultando en los diversos blogs de nuestros  distinguidos compañeros de fatiga y nos hemos dado cuenta de que si no eres capaz de explicar algo con tus palabras, es que no sabes ese algo.
Cierto es que a veces se hace pesado tener q escribir una entradita por práctica, la mayoría de nosotros nacimos cansados y eso no es culpa nuestra, pero habiendo conseguido, en parte, vencer esa pereza (en nuestro caso al menos), pero los beneficios obtenidos pueden ayudarnos muy mucho. Lo mejor, hemos conseguido ir más o menos al día y ahora nos queda menos por hacer. Lo peor, la comunicación entre blogs ha sido algo difícil pues no éramos muchos los que íbamos más o menos al día con los post (aunque no sabernos si meternos del todo en este saco…).

Y desde aquí, ánimos a los que dudan en presentarse o no al examen, si total, la convocatoria va a pasar igual y quien sabe…quizás estos maravillosos profes que tenemos (ya de paso haremos un poco la pelota) no se portan muy mal con los ejercicios… Y a los que nos presentamos al examen, nos vemos el día 20 y…

Memoria de nuestro juego

 

El juego que nos hemos aventurado a hacer es un “PUZZLE”. Como todo el mundo sabe, el objetivo es completar una imagen que se muestra al inicio de la partida, antes de que se agote el tiempo. La interacción con el usuario se hará mediante el ratón y en la zona de juego que es la siguiente:

 

 

 Hemos formada nuestro juego con 9 clases, que son las siguientes:

 

- PantallaPrincipal: es la que contiene el main y, por ello, la que se ejecuta en primer lugar. Desde aquí podrás acceder, pinchando sobre los botones correspondientes, a la pantallaInstrucciones (creando un objeto de la misma al pulsar el botón “Instrucciones”), elegir un nivel (creando un objeto de la pantallaNivel), ir a la pantalla de juego (creando un objeto de PantallaJugar) o cerrar toda la ejecución (con un System.exit(0)).

 

- PantallaInstrucciones: crea una ventana que muestra una serie de normas a seguir en el juego. Además contiene dos botones que te permiten salir (pues esta ventana no se puede cerrar mediante la cruz de la misma) o ir a la pantalla de juego.

 

 

- PantallaNivel: su función principal es dar un valor a las variables que controlan el número de piezas y el tiempo disponible para completar el puzzle, según el nivel que se seleccione. No se puede salir sin hacer clic sobre el botón “OK”, pues hemos anulado la función del botón X del Jframe mediante el siguiente código en el constructor: this.setDefaultCloseOperation (JFrame.DO_NOTHING_ON_CLOSE)

 

 

- PantallaJugar: es la clase que define la pantalla de juego. Un Jlabel situado en la parte superior, te irá mostrando la información que necesitas en cada momento. Esta clase incluye un Timer que actualiza a cada segundo el tiempo restante que te queda para lograr completar el puzzle y un método pintar( ) que coloca las piezas en su sitio inicial. Los botones de abajo te sirven para definir los cambios en el funcionamiento que quiera hacer el usuario: empezar una nueva partida (llama al método pintar e inicializa el Timer), consultar la pista (crea un objeto de la clase BotonPista), resolver (muestra la solución y finaliza tu partida), comprobar las piezas que lleva bien colocadas (llama al método comprobar polución de la clase Sñlgoritmos), salir (cierra limpiamente el programa con un System.exit(0)) y cambiar de nivel (crea un objeto de PantallaInstrucciones).

 

- BotonPista: cuando el botón “Pista” de la pantalla de juego es pulsado, se crea un objeto de esta clase que implantará una ventana con la imagen que debes formar. También contiene un Timer para controlar su desaparición al cabo de 5 segundos. Cada vez que se pulsa disminuye el tiempo que te queda en 10 segundos como penalizacion.

 

- Algoritmos: clase auxiliar que implementa varios métodos que se utilizarán en PantallaJugar. Entre ellos están:

- comprobarSolucion ( ): comprueba si la colocación de las piezas que has puesto en el tablero se corresponde con la correcta, con la imagen bien formada. Si es así te mostrará un mensaje de enhorabuena, y si no te dirá cuantas piezas tienes bien colocadas. Esto se hace gracias a un array donde vamos almacenando que pieza hay en cada posición. Se comprueba a cada segundo si el tablero está completo (no falta ninguna pieza por colocar, bien o mal, en él), utilizando el Timer de la clase PantallaJugar, para que si es así se llame a este método.

- crearAleatorios ( ): crea números aleatorios que se almacenarán en variables para controlar cual es la imagen y el orden de las piezas en cada partida. Por tanto la imagen que aparece al empezar una partida y el orden de las piezas, es aleatorio.

 

- Audio: define el comportamiento de cualquier objeto de sonido, pues deberá  ser de tipo Audio, esta clase esta basada en los ejemplos de teoría. Para que un sonido se reproduzca, tan solo deberás poner nombreObjetoAudio.player.star( ) en el lugar correspondiente y después pararlo cuando querar (por ejemplo al pulsar un botón) con nombreObjetoAudio.player.star( ).

 

- EventosPiezas: esta clase define el funcionamiento de las piezas de la pantalla de juego. Para ello hemos implementado de MouseListener, y en el método mouseClicked(MouseEvent ev) hemos añadido la funcionalidad que deseábamos que  realice cada pieza al pinchar sobre ella con el ratón. Hay que recordar que aunque no se utilicen, hay que poner todos los métodos que contiene el Mouse Listener.

 

- EventosTablero: se encarga de crear el movimiento de la zona del tablero de la pantalla de juego. Es una clase muy parecida a la anterior, sólo que describe otro comportamiento.

 

 

Pues estas son las pautas generales que hemos seguido para hacer el juego que… visto a si, no parece ni complicado xD pero os aseguro que ha dado mucho que pensar. Encima cuando ya parecía todo hecho porque compilaba, nos aparecían errores de ejecución o nos poníamos a jugar y hacía cosas que no debería… cada vez aparecían más problemas. Pero los fuimos resolviendo uno a uno con mucha paciencia y al final… ¡LO CONSEGIMOS!

Práctica 11: Swing y Eventos II

En esta sesión, intentamos dedicarnos solo a la práctica y no terminar haciendo algo del videojuego pero… algunos de vosotros (no diré culpables) nos pedisteis, muy amablemente, que os ayudáramos con el juego echando una partidita para comprobar si funcionaba todo bien y… ¡No sabemos decir que no!

Pero entre partida y partida de algunos juegos, conseguimos hacer algo:

 

Primer y único ejercicio (lo que no hace que la práctica sea corta):

 

1. Este punto es sencillo, lo más importante (y lo único que merece la pena comentar) es como va a crearse el evento en este caso. Lo primero es no olvidar poner el implements ActionListener. Para añadir nuestro botón (no todos los componentes se podrán añadir) a la interfaz  ActionListener (que se va a encargar de controlar los eventos) hay que poner:

 

nombreBoton.addActionListener (this);

 

(El this se pone si hemos heredado de JFrame y lo escribimos dentro del constructor, sino habrá que poner un objeto de tipo ActionListener) De este modo, cada vez que se pinche sobre este botón, se generará un evento. Los eventos son guardados en una cola y por ello el sistema los trata en orden de creación.

 

Una vez que ya tenemos esto, podemos definir el método actionPerformed que se ejecuta cada vez que se produce un evento sobre cualquier componente añadido al ActionListener. Este método quedará así:

 

public void actionPerformed(ActionEvent e){
  if (e.getSource( )== nombreBoton){
    System.out.println (“Se ha pulsado el Botón”);
  }

}

 

El  getSource(), devuelve el nombre del componente que ha producido el evento.

2. Es parecido al anterior pero, en lugar de observar el cambio que produce el evento en la consola, se visualizará en la misma ventana donde se produce el evento. Para esto hay que crear un label (no olvides añadirlo a un panel, para que se pueda ver, y hacer su fondo opaco, para que pueda cambiar de color) y cambiar la sentencia de antes que imprimía un mensaje por pantalla, por un código que haga lo pedido ahora; es decir, que cambie el color de fondo de nuestro label. Para ello, nos ayudaremos del setBackground (Color.BLUE).

 

3. Ahora sólo hay que añadir que cuando el usuario introduzca un “enter” por la consola, se cambie también el color de fondo de la etiqueta. Para hacer esto nos hemos ayudado de las clases de la práctica anterior que hacían algo parecido… y así fue fácil.

Con las preguntas que te hacen sobre los hilos en este punto, ya nos liamos y no conseguimos avanzar más, la verdad es que no se nos dan nada bien los hilos. Sabemos que en el punto anteriores el hilo que produce el cambio es sólo uno y por tanto el que tenga asignado JAVA por defecto pero ahora… ¿Qué es lo que pasa? ¿Hay dos hilos?.. Puff!!, vaya lío, habrá que trabajar más esto de los hilos a ver si conseguimos llevarnos bien con ellos.

 

Bye!!

Práctica 10: Swing y Eventos

Esta vez empezamos solucionando algunos problemillas del videojuego (que ya parece que va funcionando de verdad), así que no nos dio tiempo a hacer demasiado de esta práctica en clase. Esto fue todo lo que logramos:

 

Ejercicio 1: Simplemente  hay que ejecutar los tres programas que te dan para entender un poco esto de los hilos. Si no lo veis muy claro no os preocupéis demasiado porque no es algo que suela caer en el examen de OCA y se da a fondo en una asignatura de segundo, “Servidores de Información Multimedia”. Lo más importante es quedarse con la idea de que como Windows no es un Sistema Operativo Multiproceso, un mismo proceso (programa) no puede tener a la vez dos hilos en ejecución. Por esto la clase DingDongPoor no funciona bien porque no se pueden hacer más de una tarea simultáneamente (en este caso dormir durante un segundo y esperar a que se pulse ENTER).

 

Ejercicio 2: Los hilos se representan en Java mediante la clase Thread y para poder trabajar con ellos debemos crear objetos de esta clase y utilizar sus métodos, uno de ellos es el start() que nos permite lanzar el hilo. Los objetos de la clase Thread no son exactamente hilos, sino secuencias de control que van a controlar a los verdaderos hilos. Una vez que controlamos esto, vamos a analizar las clases que nos dan:

 

Clase TwoThreads: Creamos en el main un objeto Runnable que se arranca mediante el método run (). Este método llama al PrintThreadName( ) que imprime el nombre del hilo actual, es decir el main, que es lo que nos aparece escrito por consola al ejecutarlo.

El constructor del objeto Thread es el siguiente : Thread (Runnable target), por esto le ponemos como parámetro el objeto Runnable que hemos creado.

 

Clase TwoThreadsSimple: Hace exactamente lo mismo que la clase anterior pero implementar la interfaz Runnable, lo que nos ahorra el tener que crear un objeto Runnable. Ahora el parámetro del constructor del objeto Thread, será un objeto se nuestra clase que, como implementa de Runnable, es de este tipo.  

 

Clase TwoThreadsSimple2: También hace lo mismo que las dos anteriores. La diferencia es que ahora heredamos de la clase Thread y no tenemos que crear ni un objeto de la clase Runnable, ni de la case Thread. Ahora al crear un objeto de la clase TwoThreadsSimple2, le podemos aplicar directamente los métodos de Thread.

 

Ejercicio 3: Hay que saber que la pega de usar multithreading es que no sabemos exactamente el orden en que van a ser ejecutados ni cuando van a ser interrumpidos para realizar otro. Esto se comprueba al ejecutar la clase RaceCondition donde va imprimiéndose un grupo de 1 tras otro grupo de 0 sin dibujar siempre la misma forma.

Y justo aqui fue cuando llegaba la hora de irse, echamos un vistazo a la clase RaceConditionSolved pero no sacamos mucho en claro. Sabemos que ahora tenemos  el objeto Runnable eventDispacherRunnable que controla que el primer hilo no esté ejecutándose en ese momento antes de dejar trabajar al segundo. Pero no entendemos muy bien como consigue hacer esto. Nos pasaremos por algunos blogs, haber si se os ha dado mejor a vosotros.

 

Hasta la próxima práctica, y ánimo que ya quedan pocas.

 

 

 

 

Seguir

Get every new post delivered to your Inbox.