Creación de la bola

En este nuevo artículo vas a poder conocer cómo desarrollar el código necesario para comenzar la animación de la bola por la pantalla.

Tamaño de la ventana

Aunque antes vas a realizar algunos cambios sencillos al código que tienes ahora mismo, para que el tamaño de la ventana sea algo mayor para poder utilizar el juego más adecuadamente.

Ya había comentado en el artículo anterior que al crear el objeto Scene se indicaba por parámetro el tamaño de la ventana, concretamente en el segundo y tercer parámetro. Por tanto, cambia esos dos valores para asignar un tamaño de ventana de 600 x 400 puntos.

Screen Shot 2018 01 10 at 19.19.47 141f8

Ejecuta la aplicación y comprueba que la ventana aparece con un tamaño mayor.

Creación del objeto Circle

JavaFX dispone de varias clases que permiten el dibujo de formas geométricas. Por ejemplo, Circle, Rectangle, Line, EllipsePolygon, etc. Si pulsas en el enlace que he puesto en cada una de ellas podrás ver su documentación oficial para conocer cómo se deben usar y todos los métodos que puedes aplicar. Todas ellas son clases hijas (extendidas) de la clase Shape, por lo que si consultas la documentación de esta clase puedes ver todas las clases que permiten la creación de formas.

En la web https://openjfx.io/javadoc/13/ puedes consultar todas las clases que aporta JavaFX, o bien usas un buscador e indicas "API JavaFX 13", o con la ayuda de las listas emergentes de los entornos de desarrollo como ya hemos visto con NetBeans.

La API (Application Programming Interface) de un lenguaje de programación es el conjunto de funciones (o métodos cuando se habla de lenguajes orientados a objetos como Java) que pueden ser utilizados para desarrollar aplicaciones usando dicho lenguaje. 

Para el diseño de la bola de nuestro juego nos puede venir bien la clase Circle que permite la presentación de círculos en pantalla.

Para conocer cómo se debe usar esa clase o cualquier otra clase Java, debemos consultar la API correspondiente o buscar ejemplos de su uso que se hayan publicado en blogs o foros, teniendo la precaución en esos casos de que no se trata de una documentación oficial y pueden contener errores.

De esa manera habremos podido ver que se debe crear un objeto de esa clase (new Circle()), indicar la posición en la que se desea colocar en pantalla y su tamaño especificando su radio.

Empieza creando un objeto de la clase Circle, almacenando dicho objeto en una variable, que puedes llamar, por ejemplo, circleBall. Obviamente esa variable deberá estar declarada de tipo Circle (Circle circleBall)

Screen Shot 2018 01 10 at 21.14.35 22887

No te extrañe que aparezca el nombre de la variable aparezca subrayado en gris. Si sitúas el ratón sobre él verás el mensaje de aviso, donde nos informa que esa variable no está siendo usado, lo que es obvio ahora mismo.

Con esa línea se esta declarando una variable de tipo Circle, que se llama circleBall y en la que se almacena directamente un objeto de la clase Circle. Ten en cuenta que algo así se podría haber hecho también en 2 sentencias, pero para este caso queda bien hacerlo todo en la misma sentencia. Esa otra manera sería declarando por un lado la variable, y luego almacenar en ella el objeto creado:

Screen Shot 2018 01 10 at 21.20.40 67d35

Pero en cualquier caso sólo se ha creado un círculo sin indicar su posición ni su tamaño. Como se puede ver en la API de la clase Circle, dispone de los métodos setCenterXsetCenterYsetRadius para indicar la posición del círculo en el eje X (horizontal), la posición Y (vertical) y el radio.

Si empiezas a escribir el nombre de la variable junto con el punto (esperas un instante) y el comienzo del nombre de uno de esos métodos, podrás ver una lista desplegable con el formato de su uso y la ayuda de la API del método que esté seleccionado:

Screen Shot 2018 01 10 at 21.26.51 5d776

Debes ver ahí que tanto para el método setCenterX como para setCenterY se debe indicar un parámetro de tipo double (numérico con decimales) que en cada caso corresponderá con la coordenada X e Y donde se colocará el centro del círculo.

En JavaFX las coordenadas se indican con valores de tipo double, es decir, que se pueden indicar coordenadas con valores decimales, aunque también admitirá sin problemas valores literales sin decimales.

Por tanto, si queremos colocar el círculo en la posición (10, 30) hay que indicar las siguientes sentencias:

Screen Shot 2018 01 10 at 21.36.46 7774b

No te extrañe que si intentas ejecutar la aplicación ahora mismo no aparezca ningún círculo. Aún nos queda faena para eso!!!

Por ejemplo nos queda indicar el tamaño del círculo. Consulta de la misma manera cómo se debe usar el método setRadius:

Screen Shot 2018 01 10 at 21.40.29 e50e2

Resulta que es muy similar a los métodos anteriores. Hay que indicar un parámetro de tipo double que corresponderá al radio del círculo. Asígnale un radio de tamaño 7:

Screen Shot 2018 01 10 at 21.42.23 c24e7

Si has buscado algún ejemplo de uso de Circle en JavaFX quizá hayas visto que todo esto también se puede hacer usando otra manera de crear el objeto Circle, es decir empleando otro método constructor con otros parámetros, en lugar del método constructor que hemos empleado sin parámetros (new Circle()).

Se denominan métodos constructores a aquellos métodos que permiten la creación de objetos de una determinada clase, es decir, los que se emplean junto con la palabra new.

En la API de la clase Circle puedes ver que existen todos estos métodos constructores para crear objetos Circle:

Screen Shot 2018 01 10 at 21.48.02 472ff

Por tanto, para la creación del objeto Circle que habíamos hecho también podíamos haber empleado el tercer método constructor, que tiene como parámetros centerX, centerY y radius. Eso se haría así:

Screen Shot 2018 01 10 at 21.52.14 e1ee9

El resultado va a ser el mismo, por lo que utiliza la manera que prefieras. Esta última es más breve, pero en la anterior queda mejor especificado qué es cada dato.

Añadir la bola a la escena

Aunque se haya creado el objeto Circle no aparecerá en pantalla hasta que se añada a algún contenedor (layout) que se encuentre en la escena o ventana (Scene) de la aplicación.

Si recuerdas el artículo anterior, se había creado automáticamente un layout de tipo StackPane que se encuentra almacenado en la variable llamada root. Al crear la escena (el objeto Scene) se había indicado que ese layout va a ser el contenedor principal para la ventana de la aplicación. Eso ya estaba hecho anteriormente con las sentencias:

Screen Shot 2018 01 10 at 22.01.34 46dad

Por tanto, lo que podemos hacer ahora es añadir el Circle al layout que tenemos (root). Eso se puede hacer con la sentencia:

Screen Shot 2018 01 10 at 22.03.41 c1489

Esta sentencia realiza lo siguiente: Del layout root obtiene la lista de elementos hijos o elementos que contiene (getChildren), y a esa lista le añade (add) el círculo que tenemos almacenado en la variable circleBall.

Todo el código del método start debería estar quedando similar al siguiente:

Screen Shot 2018 01 10 at 22.08.05 fdb65

Ejecuta ahora la aplicación. Ya debe salir la bola!!!

Screen Shot 2018 01 10 at 22.09.08 f5fac 

Vaya, pero si la ventana mide 600 x 400 y hemos querido colocar la bola en la posición (10, 30) no parece que esté bien, porque la bola se muestra en el centro de la ventana. Esto es debido a que el layout StackPane es un contenedor que va colocando todos los elementos que contenga en el centro de la pantalla, uno sobre otro, como una pila. Así que hay que buscar otro tipo de layout para nuestro propósito. En el artículo anterior se habían indicado algunos enlaces con información sobre los diferentes tipos de layouts que se pueden utilizar en JavaFX.

El tipo de layout que recomiendo para poder colocar elementos en cualquier posición de su contenido es el que utiliza la clase Pane.

Screen Shot 2018 01 10 at 23.22.18 8b12a

Al cambiar StackPane por Pane, se mostrarán errores por no conocer esa clase. Deberás reparar las importaciones de la manera que ya debes conocer.

Screen Shot 2018 01 10 at 23.24.31 7e929

Ahora sí debe aparecer la bola en la posición inicial que se había indicado. Observa que en JavaFX el origen de coordenadas (la posición 0, 0) se encuentra en la esquina superior izquierda.

Screen Shot 2018 01 10 at 23.25.14 86e44 

Cambio de color de la bola

El juego original de Pong utilizaba un fondo negro y los elementos de la pantalla (bola, pala, etc) en blanco. Así que vamos a ver cómo podemos cambiar los colores para obtener ese resultado.

En primer lugar vas a conocer cómo cambiar el color de la bola. El inconveniente ahora mismo es que si ponemos la bola de color blanco y el fondo también es blanco se va a perder de vista. Así que vamos a darle un color provisional, por ejemplo, rojo.

Los objetos de tipo Shape de JavaFX como es el caso de Circle, disponen de un método llamado setFill que permite cambiar su color. El formato de uso de este método es como el que puedes ver al escribir el nombre del método detrás del objeto circleBall:

Screen Shot 2018 01 10 at 23.33.29 0e8e0

Es decir, hay que darle un parámetro de la clase Paint  que correponderá con el color que se desea aplicar a la forma geométrica. ¿Pero cómo se crea un objeto de la clase Paint que haga referencia al color rojo? Como siempre hay que buscar algún ejemplo que pueda ser de utilidad o analizar la documentación oficial de esa clase.

Si se observa la documentación de la clase Paint, no aparece nada donde que haga referencia a la manera de indicar un color determinado, pero esta clase tiene una clase hija llamada Color que puede servirnos de ayuda.

En Java, siempre que se necesite un objeto de una determinada clase, se puede utilizar también en su lugar un objeto de una clase hija o subclase.

Screen Shot 2018 01 10 at 23 fb20e

En la documentación de la clase Color sí aparecen algunos ejemplos claros de uso para asignar colores a formas geométricas y aparece un listado de propiedades (fields) de esa clase correspondientes a algunos colores que ya están predefinidos.

Screen Shot 2018 01 10 at 23b 92357

Para hacer referencia a una propiedad estática (static) de una clase, se debe indicar el nombre de la clase seguido de un punto y el nombre de la propiedad, sin utilizar paréntesis a diferencia de las llamadas a métodos. Por ejemplo: Color.RED

Como siempre, cuando escribes el punto después de una clase o de un objeto se mostrará la lista de los métodos o propiedades que puedes utilizar. Así que puedes usarlo para seleccionar el color rojo como parámetro del método setFill:

Screen Shot 2018 01 10 at 23.53.51 642c5

Al utilizar la clase Color por primera vez en el código deberás añadir el import correspondiente. Al utilizar alguno de los mecanismos que añaden las importaciones de manera automática (por ejemplo el Fix Imports del menú contextual) descubrirás en este caso que aparece una lista desplegable con varias posibilidades:

Screen Shot 2018 01 10 at 23.59.18 35890

Esto ocurre porque hay varias clases en Java que tienen ese mismo nombre (Color). Cada una de esas clases tendrá un funcionamiento diferente respecto a las otras aunque tengan el mismo nombre, es decir, cada una tendrá sus propiedades y sus métodos diferentes o con funcionalidades diferentes, por lo que es importante seleccionar la importación adecuada. En este caso queremos hacer referencia a la clase Color del paquete JavaFX, por lo que debes seleccionar la opción javafx.scene.paint.Color. Ante la duda debes comprobar en la documentación de clase a qué paquete pertenece.

Screen Shot 2018 01 11 at 00.05.10 60b18

Comprueba si lo deseas que la bola aparece en color rojo.

Color de fondo de la ventana

Ya se había comentado en el artículo anterior que el contenido de la ventana está asociado a la clase Scene. Por tanto, debes usar el objeto (scene) que se había creado de esa clase para cambiar el color de fondo de toda la ventana.

Si se busca información se puede comprobar que la clase Scene también ofrece el método setFill con el mismo formato que el visto anteriormente. Así que también puedes usar sobre scene lo que acabas de aprender.

Screen Shot 2018 01 11 at 00.13.16 514ff

Así ya podríamos tener el resultado deseado, pero podemos reducir algo más el código fuente si lo deseamos. Si recuerdas los distintos métodos constructores que había para Circle, puedes ver que había otro método que también incluía el color que se desea aplicar a la forma, además de la posición y el tamaño del radio.

Lo mismo ocurre con los métodos constructores de la clase Scene. Es decir, hay un formato que permite indicar 4 parámetros siendo el último de ellos el color a aplicar:

Screen Shot 2018 01 10 at 18.49.57 7bc6f

Como puedes ver al pulsar Ctrl+Espacio justo al final del nombre de la clase Scene en la sentencia new Scene, se puede indicar después del ancho y alto de la ventana, un objeto de la clase Paint para el relleno (fill) que se desea para la ventana.

Así que finalmente el código puede quedar como el siguiente (se ha cambiado el color de la bola a blanco):

Screen Shot 2018 01 11 at 00.22.11 e532a

El resultado de la ejecución hasta este momento debe ser como:

Screen Shot 2018 01 11 at 00.24.17 b1e5a