Bienvenidos sean a este post, hoy agregaremos el ultimo elemento de nuestro juego como son las cajas de textos.
En este post mencionamos que primero ibamos a trabajar en el menu de inicio, en el siguiente post trabajamos en el menu pausa y hoy nos centraremos en trabajar con la caja de textos para enviar notificaciones al usuario, pero como mencionamos en el proyecto anterior trabajamos con show_message para notificar sobre el juego al usuario y si bien esto es funcional no encaja con nuestra estetica del mismo y si bien GameMaker Studio no tiene una funcion para poder crear un caja de texto o textbox con los siguientes pasos podremos crear uno para cuando perdemos en el juego.
Para comenzar crearemos un nuevo objeto al cual llamaremos obj_CajaTexto, una vez creado le agregaremos el evento Create, una vez creado agregaremos las siguientes variables:
depth = -90;
altura = 128;
ancho = 200;
relleno = 24;
En la primer linea estableceremos la profundidad de nuestro objeto, luego estableceremos la altura de la caja de texto, la siguiente sera para el ancho y por ultimo el relleno que sera para establecer la separacion entre el texto y el borde, para nuestro siguiente paso trabajaremos con la lista de estructura de datos (Data Structure List) la cual trabaja de la misma forma que un array pero de una forma mas practica y dinamica, tambien nos permiten tener distintos valores, ordenarlos o tener valores en cualquier y aunque como todo en programacion esto no significa que no debemos volver a usar arrays porque la lista no permite trabajar con mas de una dimension y trabajar con dos listas o mas al mismo tiempo puede desencadenar en problemas de memoria, por este motivo como siempre se deben usar cada tipo cuando sea necesario, volviendo a nuestro codigo agregaremos la siguiente linea:
inicio = ds_list_create();
ds_list_add(inicio,0);
Esta variable almacenara los distintos lugares o indices donde se almacenara cada nueva linea, es decir que guardara la posicion del primer caracter de cada nueva linea, despues de esta linea iniciamos a la lista por medio de la funcion ds_list_add y le pasaremos a la variable antes creada y su primera posicion, detras de estas lineas agregaremos las siguientes variables:
contar = 0;
ultimo_espacio = 0;
linea = 0;
La primera variable sera para almacenar la posicion actual del texto que se esta imprimiendo, la segunda almacena la ultima posicion del texto impreso, y la ultima almacena la linea actual que estamos imprimiendo, nuestro siguiente paso sera agregar la siguiente variable:
mensaje = global.msj + "\nPresiona Enter para continuar";
En esta variable almacenaremos la concatenacion del valor de la variable global mas el texto que pasamos en el literal, si se preguntan por el \n es para indicar una nueva linea, por ultimo agregaremos las siguientes dos variables:
cdn = "";
global.caja_texto_finalizado = false;
La primera variable sera para almacenar la linea que estemos imprimiendo y por eso debemos iniciarla como vacia, por ultimo estableceremos una variable global para indicar que la caja es finalizada como false, nuestro codigo quedo de la siguiente forma:
depth = -90;
altura = 128;
ancho = 200;
relleno = 24;
inicio = ds_list_create();
ds_list_add(inicio,0);
contar = 0;
ultimo_espacio = 0;
linea = 0;
mensaje = global.msj + "# Presiona Enter para continuar";
cdn = "";
global.caja_texto_finalizado = false;
Para nuestra siguiente modificacion agregaremos un evento Destroy y agregaremos el siguiente codigo:
ds_list_destroy(inicio);
Esta se encargara de destruir la lista que creamos en Create, el siguiente paso sera agregar un evento de tipo Step, en el cual agregaremos el siguiente codigo:
if (keyboard_check_pressed(vk_enter))
{
instance_destroy();
global.caja_texto_finalizado = true;
}
En este condicional verificamos si se presiono Enter y en caso de ser verdadero procede a destruir la instancia y por ultimo establece caja_texto_finalizado como verdadero para indicar que se destruyo a la caja de texto, para nuestra siguiente modificacion agregaremos un evento tipo Draw, una vez creado agregaremos el siguiente codigo:
draw_set_alpha(0.70);
draw_roundrect_color(x,
y,
x + ancho,
y + altura,
c_black,
c_black,
false);
Primero estableceremos un valor de alfa, un nivel de transparencia, menor al total y luego dibujaremos un rectangulo redondeado tal como vimos en el post anterior, aqui usamos el ancho y la altura y yo use el color negro (c_black) pero pueden probar con otros si lo desean, luego de esto agregaremos el siguiente bloque:
draw_set_alpha(1);
draw_set_color(c_white);
if (string_width(cdn) > (ancho - (relleno * 2)))
{
mensaje = string_delete(mensaje,ultimo_espacio,1);
mensaje = string_insert("#",mensaje,ultimo_espacio);
ds_list_add(inicio, ultimo_espacio + 1);
}
Nuestro siguiente paso sera agregar el texto dentro de la caja de texto, por esta razon volveremos a reestablecer el alfa con el nivel maximo de opacidad, despues establecemos el color en blanco para que nuestro texto sea de ese color, luego tenemos un condicional que verifica si el ancho de texto en cdn es mayor que el ancho de la caja de texto menos el relleno por 2, si se cumple modificaremos a mensaje para eliminar el espacio sobrante, en este caso un espacio en blanco, esto lo haremos por medio de string_delete donde pasaremos la cadena, la ultima posicion y el contador de espacios a remover en este, todo esto lo almacenamos en mensaje, luego usaremos a string_insert para agregar lo restante del mensaje, el primer caracter indicara que es una nueva linea, pasaremos el texto y le diremos desde cual indice debe comenzar, en este caso ultimo_espacio, por ultimo debemos agregarlo en nuestra lista otra vez el valor de inicio y el caracter sera ultimo_espacio mas 1, a continuacion agregaremos el siguiente condicional:
if (contar < string_length(mensaje))
{
if (string_char_at(mensaje, contar) == " ")
{
ultimo_espacio = contar;
}
++contar;
}
Primero verificamos si contar es menor al tamaño del mensaje, en caso de ser cierto significa que tenemos mas texto que mostrar por lo tanto tenemos otro condicional donde verificamos si el caracter dentro de mensaje en la posicion que contiene contar es un espacio en blanco, en caso de ser verdadero estableceremos a ultimo_espacio con el valor de contar, para finalmente fuera de este condicional incrementamos en uno a contar, para nuestra siguiente modificacion agregaremos el siguiente condicional:
if (string_height(mensaje) > (altura - relleno))
++linea;
En este condicional verificamos si la altura de mensaje es mayor a la diferencia entre la altura y el relleno, en caso de ser verdadero incrementamos el valor de linea, con todo esto ya tenemos nuestro mensaje armado y solo nos falta unas tareas para mostrarlo correctamente, para ello agregaremos el siguiente bloque:
cdn = string_copy(
mensaje,
ds_list_find_value(inicio, linea),
contar - ds_list_find_value(inicio, linea));
draw_text(x + relleno, y + relleno, cdn);
draw_set_color(c_black);
Asignaremos a cdn la copia del contenido creado en mensaje, y los siguientes dos campos definen desde que posicion iniciar y la cantidad de caracteres que deberemos copiar, y en este caso no debemos empezar desde cero sino desde uno, en el caso de la posicion solamente buscamos el valor por medio del valor de inicio y linea, en cambio para la cantidad tomamos el mismo valor pero se lo restamos a contar, una vez copiado el contenido en cdn lo «dibujamos» por medio de draw_text y por ultimo volvemos a setear el color en negro, si utilizaron otro color modifiquenlo a ese, con esto concluimos con nuestro objeto ahora solo nos resta hacer las ultimas modificaciones en el objeto del jugador.
En el objeto del jugador, obj_Pepe, iremos al evento Create y agregaremos la siguiente linea:
hacer_caja_texto = false;
Esta sera para hacer la caja de texto pero solo se activara cuando sea necesaria, la siguiente modificacion sera en el evento Step donde cambiaremos el siguiente condicional:
if (y > room_height)
{
room_restart();
}
De la siguiente manera:
if (y > room_height)
{
if (!hacer_caja_texto)
{
global.msj = "Haz muerto, y el juego se reiniciara.";
instance_create_depth(
156,
320,
0,obj_CajaTexto);
hacer_caja_texto = true;
}
if (global.caja_texto_finalizado)
room_restart();
}
Seguiremos chequeando si nos pasamos del limite de la pantalla, ya sea porque nos caimos o porque tocamos a un enemigo, dentro de este agregaremos un nuevo condicional donde verificamos que hacer_caja_texto sea falso, si se cumple la condicion estableceremos un mensaje para global.msj, puse este de ejemplo, luego crearemos una instancia de obj_CajaTexto y por ultimo establecemos a hacer_caja_texto como true, por ultimo tenemos otro condicional mas donde verificamos si global.caja_texto_finalizado es true, recuerden que lo hicimos al destruir la caja, y por lo tanto procede a reiniciar el room, con esto tenemos todas nuestras modificaciones realizadas solo nos resta probarlo como lo haremos mediante el siguiente video
En el video podemos ver como nuestro juego ya esta realizado al 100% y si lograron lo mismo que en el video Felicitaciones!!! Porque acaban de lograr algo extraordinario pero esto no termina aun tenemos mucho mas que aprender.
En resumen, hoy hemos visto como trabajar con un cuadro de texto que inclusive nos puede servir para otro proyectos, hemos visto como manipular cadenas para poder encajarlas dentro de un rectangulo, tambien hemos visto como poder implementarla para que se active con cualquiera de las dos posibilidades de muerte y como reiniciar el nivel o room, espero les haya gustado sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.00
