Hola que tal!
Estoy desarrollando un juego con la 39DLL y mi pregunta es la siguiente:
¿Cuál es el mejor método para recibir coordenadas de varias instancias del mismo objeto?
Según como lo he programado tengo del lado del Servidor un arma que ,obviamente, dispara. Sin embargo el Cliente solo recibe las coordenadas de la última instancia creada por el servidor, es decir, que a la próxima que crea se leen las coordenadas y la ya antes creada queda pegada en la pantalla sin moverse.
Entonces, ¿Cómo podría hacer para que el Cliente lea las coordenadas de todas las instancias que crea el Servidor?
Tenía en mente usar listas o arreglos , pero no sé cómo podría programarlas. Y si es, además, un método efectivo.
Saludos!

  Saludos makera Silver_light:


  Ante todo ¡feliz año nuevo!, te deseo mucha salud y dinero... que el resto se puede comprar... XD

  Mi propuesta es que no solo envíes al cliente las coordenadas del objeto arma creado en el servidor, sino que también envíes el identificador de esa arma. Por ejemplo: (arma1, x, y), (arma2, x, y), etc. Asi sabrás de que arma es cada coordenada. Y por supuesto que el uso de arreglos es recomendado para llevar el control de todos estos datos. Tengo entendido que son más eficientes que las listas.

  Cada arma creada en el servidor debe ser enviada al cliente y de esta forma es que se pueden leer. Consejo, crea una lista de las armas creadas y sus coordenadas en el cliente y en el servidor. De esta forma tendrás más control de cada arma desde ambos lados.

Espero te sirva de algo, un saludo.  ;D 


Ferhand, las listas son mucho más eficientes en muchos sentidos
Pero sí, básicamente necesitás ponerle un identificador a cada instancia cuando se crea y al asignar buscás con with(object) y comprobás que el identificador sea igual al que te enviaron




  Saludos Makera Silver_light y Makero Texic:


   Disculpa hermana si tomo tu espacio de pregunta para una corta discusión.   :-*

  Lo siento hermano Texic, pero estoy en desacuerdo contigo.   :-[

  Las listas en el tras fondo están programadas utilizando Arreglos (array[a,b]), por lo que son una interfaz para el trato con los mismos. En lo único que yo veo eficiencia en las listas es que desde el lado del programador es menos engorroso a la hora de insertar un nuevo elemento en cualquier posición de la lista, o a la hora de organizar sus elementos basados en algún criterio. Aún así el programa guarda por cada lista una serie de parámetros que muchas veces no vamos a utilizar y sin embargo ocupan espacio en memoria.

  Los arreglos se pueden utilizar del mismo modo, la dificultad es que tenemos que programar las acciones que necesitamos ya sean insertar un elemento, ordenar o eliminar, etc. Lo bueno es que es una primitiva del lenguaje y no guardará parámetros extras al tiempo que se ejecutan con rapidez.    8)

Es solo mi opinión, a lo mejor estoy dejando pasar algo por alto. El problema es que me encanta discutir  y vi la oportunidad para hacerlo.  :P  Disculpa Silver_light y Texic. Todo es para aprender y divertirnos.  ;D   


Jaja, no hay problema, pero no tuviste en cuenta un par de aspectos. Para buscar un valor en un array hay que recorrer con un for, que es mucho más lento que ds_list_find_index. O para ordenar los valores de un array de forma ascendente, en un array es un dolor de cabeza, para las ds_list hay una función muy simple y eficiente. Para quitar un valor en un array lo mismo, tenés que andar recorriendo con un for de vuelta y moviendo todo de lugar, en la ds_list es una sola función. La diferencia principal radica en que las funciones internas que ejecuta la ds_list están previamente compiladas, y los scripts o códigos que vos crees con tus arrays son interpretados, la diferencia de velocidad es abismal




Cita de: Texic en Enero 07, 2013, 06:24:24 PMLa diferencia principal radica en que las funciones internas que ejecuta la ds_list están previamente compiladas, y los scripts o códigos que vos crees con tus arrays son interpretados, la diferencia de velocidad es abismal
  ¡Anjá, yo sabía que me pasaba algo por alto! En ese caso la ejecución de lista debe ser mucho más rápida... Pido disculpas por mi error y le sugiero a Silver_light que considere tu consejo.

Hermano, particularmente estoy utilizando "arrays" en el diseño de mi juego. Los utilizo por el aquello de los índices, los necesito, pero si las listas son mejores...¿Crees que las estructuras como los "grid" sean más eficientes que un "array" 2D? Lo pregunto pues en mi diseño tengo montones de "arrays" bidimensionales en memoria ram.

Pido disculpas si ya esto se sale del tema...¿Debería crear uno nuevo...?  :-[   



Las grid más o menos, a mi me resultan cómodas para guardarlas y cargarlas, pero no traen demasiadas funciones útiles, la de búsqueda sería la que más destaca. Lo que uso con frecuencia para la 39dll son los stacks, resultan útiles en juegos de movimiento rpg por cuadrícula. Las list son las que más funciones útiles traen




   Estoy de regreso ... con información fresca:


   Saludos y al debate...

   Los "arrays" son estructuras que guardan datos en "Ram" en espacios de memoria contiguos. Cuando se desea insertar otro elemento se debe crear un "array" nuevo con un elemento de más y copiarle la información que existía en el otro "array" incluyendo el cambio. Todo este trabajo es por la razón de que el sistema debe encontrar un espacio lo suficientemente grande para que quepa el nuevo "array" todo de un golpe. A la hora de ir directamente a algún indice, el sistema tiene como llegar sin mayores complicaciones.

Si embargo, las listas se guardan en la "Ram" de otra forma. Cada elemento de la lista es una estructura llamada nodo, formada por dos piezas, en una está el valor y en la otra está la dirección de memoria del próximo nodo (índice). Para alcanzar algún nodo (indice) dentro de la lista hay que recorrerla pues la dirección de memoria de dicho nodo está en el nodo anterior.  Si queremos alcanzar el nodo (índice) 3 debemos acceder al nodo 2 pues en él esta la dirección del nodo 3, pero para acceder al nodo 2 debemos acceder al nodo 1 pues en él está la dirección del nodo 2. Todo esto lo hace el sistema por detrás, pero es bien lento cuando se tiene una lista muy grande.

  Yo no recordaba estos detalles de cuando estudiaba progarmamción. Aún así la documentación de GM dice "They are implemented using simple arrays but, as this is done in compiled code it is a lot faster than using an array yourself." Lo cual es irrefutable por mi.

  ¡Por lo tanto ha usar listas....!!!!   XD XD XD XD

  ¡Texic, tenías razón...!   ;D   


Saludos again!
Interesante debate, lastima que no entendí mucho el final :-[

Em... bueno de la forma en que yo lo programé era de la siguiente forma:
Al presionar el boton X, el arma dispara, entonces en ese momento envia el byte al cliente indicando que debe crear una instancia de bala:
Citar
clearbuffer();
writebyte(5);
sendmessage(global.tcp_cliente);
En el objeto que recibe los datos quedó así:
Citar
case 5:
   disparo = instance_create(0,0,disparo);
break;
Luego el disparo del servidor enviaba su identificador, la coordenada X e Y:
Citar
clearbuffer();
writebyte(6);
writeuint(id);
writeshort(x);
writeshort(y);
sendmessage(global.tcp_cliente);
Despues el objeto que recibe los datos leía estas coordeanadas, con:
Citar
case 6:
     disp = readuint();
     disp.x = readshort();
     disp.y = readshort();

Esa es la forma que opté por hacer de acuerdo a la primera respuesta de Ferhand.

Ahora, cómo implementaría la forma que dices tu, Texic?

#9 Enero 09, 2013, 02:39:46 AM Ultima modificación: Enero 09, 2013, 02:41:48 AM por Wadk
¿Esa forma, la probaste? ¿Y funciona? Porque para que funcione, el id de las balas en el cliente y el servidor debería estar sincronizado, y es muy difícil que pase...
Yo te recomendaría lo siguiente.

Para crear la bala:
[gml]clearbuffer();
writebyte(5);
writeuint(id);  // Enviás el id de la bala también.
sendmessage(global.tcp_cliente);[/gml]

Al recibir el paquete de creación de bala:
[gml]case 5:
    with (instance_create(0, 0, disparo)) {
        remote_id = readuint();
    }
break;[/gml]

El código para enviar las coordenadas como lo pusiste en el post anterior, y el código para recibirlas:
[gml]case 6:
    var recieved_remote_id = readuint();
    with (disparo) {
        if (remote_id == recieved_remote_id) {
            x = readshort();
            y = readshort();
            break;
        }
    }
break;[/gml]
No estoy seguro de si se puede usar break en un with. Si no se puede, sacalo, el código quedaría menos optimizado pero debería seguir funcionando.

EDIT: Por cierto, ahora que me fijo esto es exactamente lo que propuso Texic su primer post en el tema.
Vim.

Es para una bala? Silver, es mejor enviar la dirección, la velocidad y las coordenadas iniciales en el byte y asignarlos al crear, que el cliente saque sus propios cálculos, sino es un mambrollo de datos volando de un lado a otro y jamás te va a funcionar bien en wan




Había usado lo que coloqué y funcionaba bien, si se ponia +1 o -1 en el id que se enviaba.
Por ejemplo:
Citarclearbuffer();
writebyte(6);
writeuint(id+1);
writeshort(x);
writeshort(y);
sendmessage(global.tcp_cliente);
-Pero claro pensé que algo como eso estaría mal y podría afectar en un futuro.

Usé el metodo de Wadk, que es el que propuso Texic, y que no sabía como aplicarlo, así que gracias por contestar.

Cita de: Texic en Enero 09, 2013, 09:03:37 PM
Es para una bala? Silver, es mejor enviar la dirección, la velocidad y las coordenadas iniciales en el byte y asignarlos al crear, que el cliente saque sus propios cálculos, sino es un mambrollo de datos volando de un lado a otro y jamás te va a funcionar bien en wan

Si, son para disparos. Que el cliente o el servidor dispare y se vea en la otra pantalla.
Ok haré eso que dices así no hay tanto "embrollo de datos" haha


Cita de: Silver_light en Enero 10, 2013, 12:05:37 AM
Cita de: Texic en Enero 09, 2013, 09:03:37 PM
Es para una bala? Silver, es mejor enviar la dirección, la velocidad y las coordenadas iniciales en el byte y asignarlos al crear, que el cliente saque sus propios cálculos, sino es un mambrollo de datos volando de un lado a otro y jamás te va a funcionar bien en wan

Si, son para disparos. Que el cliente o el servidor dispare y se vea en la otra pantalla.
Ok haré eso que dices así no hay tanto "embrollo de datos" haha
Yo no lo recomendaría. Las balas podrían des-sincronizarse a la más mínima fluctuación de los fps de alguno de los jugadores...
Lo que podés hacer, que es lo que más se recomienda en estos casos, es enviar la posición, la velocidad y la dirección una vez cada x steps. 5, por ejemplo. Así cualquier des-sincronización solo duraría un poco y no sería muy notoria, y a la vez te ahorrás tener que enviar los datos una vez por frame.
Vim.

#13 Enero 10, 2013, 12:54:30 PM Ultima modificación: Enero 10, 2013, 12:56:45 PM por Texic
Mejor hacer que el cálculo de movimiento tenga en cuenta los fps y listo
En wan siempre va a haber desincronización, es mejor vivir con ella que tratar de sacársela de encima enviando más y más datos (cosa que la vuelve más grande) xD

PD: El número de mensajes de Silver_light coincide con mi número de puntos  :P




Cita de: Texic en Enero 10, 2013, 12:54:30 PM
Mejor hacer que el cálculo de movimiento tenga en cuenta los fps y listo
Vaya. Yo no confiaría en eso. ¿Ya lo probaste anteriormente?
Vim.