Transmisión de
paquetes
En este artículo de
cómo crear un juego Multijugador Online explicare
como hacer transmisión de paquetes de datos por medio de buffers y por supuesto
que eso implica hacer movimientos de un objeto jugador o cualquier objeto desde
el cliente y visualizarlo en el servidor.
Trabajaremos con un sprite o tira de imagenes.
Esto será lo que paseara entre el servidor y cliente
Creamos el obj_jugador
y en el evento Create escribiremos estas líneas.
El array tecla_jug
servirá para hacer que se mueva el objeto por la room declare 2 índices que
serán los movimientos de izquierda a derecha, establecí esos dos por efectos de
simpleza.
En los eventos Step del obj_jug
establecí las acciones que tendrá el objeto en cuestión que será de moverse
de izquierda a derecha.
Donde se puede ver que si el array tecla_jug tiene los índices:
mac_der, mac_izq y estos son verdaderos el objeto procederá a moverse a la
derecha o izquierda haciendo uso de la variable hspeed. mac_der y mac_izq
son Macros que he declarado son un
tipo de variable global o palabra reservada al cual se le asigna un valor.
En el obj_servidor declararemos
dos variables, serán:
·
cliente
esta será un ds_map servirá para
almacenar el ID del jugador o socket
que conecte con el servidor que posteriormente podremos consultarlo y hacer lo
que queramos con ese ID por ejemplo
hacer cambios de sprite o cambios de estado por medios de variables.
·
b_jugador
con esto se declara un buffer con buffer_create() donde se le asigna el
tamaño de buffer, su tipo y aliniacion.
En el evento Destroy
se tiene que eliminar el buffer declarado en Create usando la función buffer_delete()
ya que de acuerdo a la documentación de Game Maker Studio es importante eliminar la memoria que no se
use para evitar perdida de esta.
En el obj_servidor del
evento Networking añadiremos unas
líneas de código. Se declarara dentro de la sentencia tipo==network_type_connect una variable llamada inst esta creara y almacenara el ID del obj_jugador en la siguiente línea se añade el ID obtenido por la instanciación del obj_jugador en el ds_map
de la variable cliente para luego
ser usado en algún momento, por ejemplo: el servidor podría asignaerles cambio
de estado al jugador, habilidades o cualquier otra cosa que pueda dar su imaginación.
En la siguiente sentencia tipo==network_type_disconnect cuando se desconecte se declarara
otra vez la variable inst que almacenara
el resultado de una búsqueda de un ds_map,
lo que buscara será el ID almacenado
en la conexión que realizo ese jugador; luego haciendo referencia al ID del jugador usando with() eliminara la instancia.
En la siguiente línea se eliminara el ID del ds_map
Fuera de ese bloque de código después del else se llama un script llamado sc_recibir_datos()
que profundizaremos, esto recibirá los paquetes de datos del cliente.
Dentro del script de sc_recibir_datos se declararan al
principio 4 variables que seran:
·
buffer: como
esto será un scrpt que solo se llamara dentro de un evento Asynchronous generara
una variable global llamada async_load; con
esto capturaremos los paquetes de datos enviados por el cliente o clientes.
·
recibido:
almacenamos nuestro primer dato que recibiremos de parte del cliente usando
la función buffer_read(buffer,tipo)
donde en el argumento buffer será el
buffer donde leeremos los datos que este será el buffer capturado por la
variable buffer y en el segundo
argumento que es tipo será el tipo de
buffer que esperara recibir, los tipos de buffer aparecen detallados en el
manual de Game Maker Studio; etos tipos son constantes y la constante que use fue buffer_u8, pues en el manual dice
que puede almacenar valores e 8bit enteros,
estos serán valores positivos del 0 a 255.
Use esta constante porque considere que será suficiente para este ejemplo
ya que tengo planeado almacenar solo un
numero nada más.
·
sock:
esta variable almacenara un ID de la
conexión recibida.
·
Inst:
esta variable almacenara el valor del ID
en el ds_map cliente
Usando un switch comprobaremos
los estados de la variable recibido donde
si en el caso esta variable sea igual a mac_tecla
ejecutara el siguiente bloque de código.
Se declaran 2 variables tecla
y pres estas almacenaran los buffer
recibidos del cliente, el tipo de buffer que espera recibir será buffer_s16 (esta constante también la
tiene que tener el cliente cuando envia) la variable tecla será que tecla ha pisado el cliente y la variable pres es si ha presionado la tecla.
Si la tecla presionada es igual a vk_left cambia el valor de la variable tecla a la constante definida en el Macro que es mac_izq. O si
el valor de la variable tecla es diferente a vk_left hará lo mismo pero con la derecha.
Ahora se traslada estos valores al obj_jugador.
si la variable pres
es igual a 0; accedera al obj_jugador por
medio de la variable inst que se
declaro al principio y que almacena el ID
de la conexión cliente usando un
puntero que es el punto (.) accedemos
a la variable que tiene ya declarada el obj_jugador
que es el array tecla_jug[]
El índice que llevara este array será la variable tecla que es la que le indicara cual es
la que se está pisando y a este array se le asigna el valor false ya que se comprueba si pres es igual a 0.
O sino hará lo mismo pero esta será true porque pres será 1.
Ahora el obj_cliente
Declaramos una variable de nombre bufferCliente usando buffer_create(1024,buffer_grow,1);
en sus parámetros o argumentos puse que se le asignara una memoria de 1024 bytes en el tipo de buffer se le
asigno buffer_grow, esos 1024 bytes
puede aumentar su valor declarando este tipo de buffer y una alineación de
memoria de 1.
En el invento Destroy. Eliminamos el buffer creado
cuando se elimine este objeto
En el evento Step se coloca las acciones
de teclado, estas acciones se escribirán en un buffer y se enviaran al
servidor, acá es donde ocurre la “magia”, al presionar se llama un scipt de
nombre sc_envio_tecla().
Dentro de ese script
Se usara la variable bufferCliente que es el que almacena el tamaño de la memoria
que se reservó para la escritura de datos.
Se establece desde donde va a
escribir los datos en el buffer con la función buffer_seek(buffer,base,offset) y como escribirá siempre debe iniciar desde el principio, declarando en el argumento base, buffer_seek_start, en el argumento buffer¸ es el buffer declarado en bufferCliente y en el argumento offset se asigna 0 siendo hay desde donde se desplazara.
Se escribe los datos que se
enviara al servidor usando la función buffer_write(buffer,tipo,valor),
en buffer se coloca la variable, en tipo el tipo de buffer que se escribirá;
como solo enviare un macro que tiene
definido un valor de 0 que es un numero entero positivo declare en este buffer_u8, y en valor el valor que será
escrito en esta caso un macro que es mac_tecla.
Lo mismo pasara con los siguientes
dos solo que el tipo de buffer será buffer_s16,
estos solo tendrán como valor la tecla pisada y un valor 0 y 1 indicado si
pisan o levantan la tecla.
Es importante saber que los tipos
de buffer enviados tienen que ser iguales a los que se esperan recibir, en este
caso el que envía es cliente y el
que recibe es servidor.
Con esto ya tenemos finalizado
este artículo, imagen del resultado.
Dejo el enlace de Descarga. para que estudien e proyecto.

















Genial, tengo una duda... Quiero que al presionar el boton Servidor, me lleve al room_jugar con el personaje N°1 i al presionar cliente me lleve a la misma room_jugar con el personaje N°2 un Modo Lan, Me Explico Bien?, espero me ayudes Gracias!
ResponderEliminarGracias por la explicacion me ayuda mucho sigue haciendo estas entradas pero quisiera saber mas de como hacer un juego mundo abierto para varios jugadores no puedo entender muy bien la relacion que tienen entre servidor y cliente
ResponderEliminar