online_leaderboard_tutorial_3

en Tutoriales, UE4

Como crear una tabla de clasificación online (Parte 3)

Este es el último tutorial de esta serie sobre como crear una tabla de clasificación online. La clase C++ que hemos creado en el tutorial anterior será integrada en un proyecto blueprint, con ejemplos de como utilizar las llamadas de nuestro gestor de puntuaciones.

Parte 1: Archivos del servidor
Parte 2: Archivos del cliente
Parte 3: Integración con el proyecto UE4

Widgets

Vamos a hablar un poco de la Interfaz de usuario, vamos a crear dos widgets, el primero de ellos será el encargado de mostrar la tabla de puntuaciones, le pondremos algunos botones para recargar la lista, volver a subir la puntuación máxima, (el usuario podría no tener conexión en el momento de obtenerla) y un par de botones para navegar por las páginas de la lista.

leaderboard_ui
leaderboard-diagram

El segundo de los widgets lo utilizaremos para pedirle información al usuario, como el nombre a mostrar junto a su puntuación, y también para mostrar mensajes de error en caso de que se produzcan. Podemos crear este widget como un hijo del primero. Para controlar los diferentes estados del widget podemos utilizar un enumerator, y establecer su estado y aspecto antes de añadír el widget al viewport.

lb_info_widget
lb_info_show
new-record-diagram

Continuaremos con mas código de estos widgets una vez preparemos el blueprint de nuestro gestor de puntuaciones leaderboardManager. El árbol de widgets quedaría así:

  • Actor_Game
    • UI_Menu_LB
      • UI_Menu_LB_info

LeaderboardManager Blueprint

Abrimos el proyecto de nuestro juego y creamos un nuevo blueprint utilizando como clase padre la clase C++ leaderboardManager.

blueprint-class
class-selector

Vamos a sobrecargar las funciones de leaderboardManager para interaccionar con los widgets. Podemos añadir una referencia a nuestro Actor del juego para simplificar esta interacción.

override_functions

Cuando recibimos un callback de un envío de puntuación correcto lo primero que hacemos es comprobar si la operación fue cancelada por el usuario y evitar mostrar el widget. Después de esto podemos comprobar si el usuario no tiene userId, su ausencia nos indica que este ha sido su primer envío.

La llamada con el primer envío devuelve un userId único, que como recordarás ha sido generado en los archivos PHP. Necesitamos almacenarlo en nuestro savegame para que pueda cargarse y utilizarse en el próximo arranque del juego.

Cuando la puntuación se ha envío con éxito podemos simplemente reportárselo al jugador o también podemos mostrar la tabla de clasificación con la posición que ocupa. Para hacer esto podemos llamar a nuestro diálogo de información (segundo widget) con el parámetro Loading para desencadenar el proceso que muestra la tabla de clasificación.

sendscore_bp_callback

Cuando la descarga de la tabla de puntuaciones ha sido parseada, lo único que tenemos que hacer en la clase blueprint del gestor es mostrar el widget de la tabla de puntuaciones (primer widget) y ocultar el diálogo de información.

getleaderboard_bp

Si obtenemos un error en cualquier momento de las peticiones tendremos que mostrar el diálogo de información utilizando como parámetro de estado Error.

error_leaderboard_bp

Veremos en más detalle estas llamadas a los widgets en las próximas secciones del tutorial.

Game Blueprint

Ahora ya podemos añadir la variable de tipo leaderboardManager al Actor del juego.

blueprint-variables

Recuerda que antes de poder utilizarla tenemos que inicializarla con un nodo Construct Object from Class.

LoadGameData es una función auxiliar para trabajar con la clase Savegame. Se encarga de recuperar los valores de las variables de la última vez que se jugó desde un fichero físico. Por ejemplo, la cadena que contiene el userId recibida en el primer envío de puntuación debe guardarse para ser asignada en el constructor de nuestro gestor de puntuaciones en próximos arranques. Cada vez que el jugador manda una nueva puntuación esta debe tener ir acompañada del mismo userId.

gamebp_initialization

Cuando se obtiene un nuevo record tendremos que llamar al dialogo de información con el parámetro InputName para que se muestre con un campo de entrada de texto para que rellene su nombre, sobre este campo se pueden implementar múltiples comprobaciones como la longitud máxima y mínima del nombre o evitar el uso de palabras inapropiadas.

new-record-call

La otra llamada importante es el botón de puntuaciones del menú principal, para solicitar la tabla de clasificación solo tendremos que llamra al diálogo de información con el  parámetro Loading.

top100-call

Leaderboard-widget

leaderboard_ui

Cuando realizamos la llamada al widget de la tabla de puntuaciones el gestor ya ha recibido todos los datos de nuestra lista top 100, solo tendremos que extraerlos de las variables del gestor y ponerlas en los textblock del widget. La función UpdateData preparará las variables del widget, como cuantas páginas tiene que contener o, si el jugador esta en el top, navegar para mostrar la página en la que se encuentra. La función LoadLeaderboard extrae los datos de la página actual y llena cada una de las columnas con esta información, podemos aplicar diferentes efectos según se va añadiendo información para que resulte más atractivo.

LBW-show-hide

Los botones para navegar por la lista solo tienen que actualizar las variables del widget relacionadas con la navegación y realizar después una llamada a LoadLeaderboard. Está llamada no realiza una petición para volver a obtener los datos del top al servidor, solo los extrae de los datos contenidos en el gestor.

LBW-updatetabs


Por último el botón para recargar la lista hará una llamada al dialogo de información para desencadenar la petición de la nueva lista al servidor, y el botón para volver a subir la puntuación que tiene el mismo comportamiento que cuando hay un nuevo record, mostrará el dialogo para poner el nombre y desencadenará el proceso de envío de puntuación.

LBW-more-buttons
LBW-updatedata-1

Ahora ya podemos ver más en profundidad la función UpdateData. La primera parta se encarga de calcular las variables del widget relacionadas con la navegación, como pueden ser el limite de página a mostrar o la página en la que se encuentra el jugador dentro del top.

La parte intermedia solo es para ocultar la fila con los datos del jugador si aun no ha puntuado

LBW-updatedata-2

La última parte se encarga de rellenar los textblocks de la fila con los datos del jugador con su mejor puntuación y posición actual.

LBW-updatedata-3

La función LoadLeaderboard recorre los elementos de la página actual.

LBW-load-1

En cada iteración concatena la información de la fila actual con las anteriores. Cada columna cuenta con su propia variable (posición , puntuación, nombre).

LBW-load-2

Finalmente asignamos el contenido de estas variables a los textblock según correspondan.

LBW-load-3
get-leaderboard-gif

Leaderboard-info-widget

lb_info_widget

El diálogo de información es utilizado como un desencadenante, cuando se le llama con el parámetro Loading desencadena la petición de la tabla de puntuaciones (getLeaderboard), si se le llama con Sending desencadena la petición de envío de puntuación (SendScore)

LBWI-show-hide

La función UpdateData para este widget solo se encarga de controlar los textos y la visibilidad de los componentes en función del estado aportado en la llamada del widget.

LBWI-updatedata

La función que ejecuta el botón del diálogo depende del estado también. Si se encuentra en el de InputName el botón será el iniciador del proceso de envío de puntuación, en caso contrario se comportará como un botón de cancelación de la petición actual.

LBWI-button
send-score-gif

Todo lo que necesitamos ahora es añadir algunos efectos de animación a los botones y los textos para que resulte visualmente más atractivo, no te olvides de añadir algunos sonidos también 😀

Ahora nuestro juego cuenta con un sistema ligero de tabla de clasificación online con el cual los jugadores pueden aceptar el reto de ocupar las primera posiciones del ranking.

Tutorial files

2021/10/05 – Updated to PHP 7 and Unreal Engine 4.27

Ayudanos con este blog!

El último año he estado dedicando cada vez más tiempo a la creación de tutoriales, en su mayoria sobre desarrollo de videojuegos. Si crees que estos posts te han ayudado de alguna manera o incluso inspirado, por favor considera ayudarnos a mantener este blog con alguna de estas opciones. Gracias por hacerlo posible!

Escribe un comentario

Comentario