Ultimos temas
Cargando...
lunes, 26 de marzo de 2018



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.

Por último se envía el paquete de dato usando la función network_send_paket(socket,buffer_id,tamaño), en socket es el tipo de socket por donde enviara que en realidad eso es un protocolo de conexión de red, y en este caso se enviara los datos por el protocolo TCP  en buffer_id es el buffer declarado en el evento créate del obj_cliente y en tamaño, es el tamño del buffer que se calcula usando la función buffer_tell() y se envia


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.
Siguiente
Este es el mensaje más reciente.
Entrada antigua

2 comentarios:

  1. 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!

    ResponderEliminar
  2. Gracias 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