Movimiento sincronizado

Started by Arcontus, March 08, 2011, 08:09:02 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Arcontus

Hola chicos,

necesito de vuestro consejo o ayuda. Estoy desarrollando un videojuego de navecillas, y desearía que el movimiento de las naves fuera totalmente independiente a los FPS del juego. Para un "movimiento rectilineo uniforme" no hay dudas, pero si la nave acelera, y rota estoy viendo que he de implementar cosas que en estos momentos desconozco.

Por otro lado también está el problema de las colisiones, ya que si en un ordenador va a 1FPS o menos (exagerando un poco), cabe la posibilidad, si el calculo de movimiento se realiza por tiempo, al usar collision algunas veces los disparos atravesarían la nave. Así que también necesito algo para calcular trayectorias de intercepción.

Así que si alguno de vosotros ha hecho algo parecido o bien, existe algún ejemplo por ahí, o funciones en alguna librería, os estaría muy agradecido.

5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

SplinterGU

el movimiento rectilineo uniforme, es en linea recta...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Arcontus

Quote from: SplinterGU on March 08, 2011, 08:59:04 PM
el movimiento rectilineo uniforme, es en linea recta...
Si, para ese no hay problema. El problema está en el movimiento no uniforme, ni rectilineo :)
5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

DCelso

si, yo tampoco entendi muy bien el problema
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

osk

En mi manualillo hay varios ejemplos de movimiento curvilíneo, acelerado, etc

Arcontus

Quote from: DCelso on March 08, 2011, 10:16:31 PM
si, yo tampoco entendi muy bien el problema
Oks, voy a intentar describirlo con un ejemplo:
*Tenemos el PC A, con 4fps y el PC B con 1fps. Queremos conseguir que las naves se muevan a misma velocidad en el tiempo, independientemente de los FPS. Si implementamos un algoritmo como el siguiente:

<pseudocodigo>
LOOP
* contador = calcular tiempo entre frame actual y anterior.
* avanza 5 pixels * contador.
* gira 5 grados * contador.
END

Resultado (aproximado):
PC A
FPS = 1, Tiempo ultimo frame=0, angulo=0, avance=0.
FPS = 2, Tiempo ultimo frame=250, avance=1250, angulo= 1250
FPS = 3, Tiempo ultimo frame=250, avance=1250, angulo= 2500
FPS = 4, Tiempo ultimo frame=250, avance=1250, angulo= 3750
FPS = 5, Tiempo ultimo frame=250, avance=1250, angulo= 5000

PC B
FPS = 1, Tiempo ultimo frame=0, angulo= 0, avance= 0
FPS = 2, Tiempo ultimo frame=1000, avance=5000, angulo= 5000

Si visualizáis este ejemplo, comprobaréis que el PC A ha desplazado el proceso formando una "curva" compuesta de 4 rectas ya que ha avanzado 1250 pasitos cada vez, y añadiendo al giro 1250. El PC B en cambio, ha avanzado 5000 y posteriormente ha girado 5000, de manera que la totaldidad del movimiento ha sido recto, no girando.

El mismo problema me surge en la aceleración, ya que no quiero que mi nave salga de 0 a velMAX en 1ms.

¿¿Se entiende mejor ahora??

¿¿Es posible que alguien se haya encontrado antes con esto y haya creado las funciones pertinentes??

Gracias por adelantado.
5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

Arcontus

Quote from: osk on March 08, 2011, 10:22:50 PM
En mi manualillo hay varios ejemplos de movimiento curvilíneo, acelerado, etc
Excelente!! lo reviso mañana y te cuento!
5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

Drumpi

Yo sigo diciendo, como opinión personal, que un juego en un divlike que no dependa de los FPS es un error, porque todo está lligado a los FPS.
Se puede plantear un escenario como este, en el que los procesos no son dependientes de los FPS, pero tarde o temprano te enfrentarás a algo que sí esté sincronizado, ya que el sistema en sí mismo lo está.

Si en un PC te va a 4FPS y en otro a 1FPS, optimiza o usa frameskip.

Como digo, es una opinión personal. Si aun así quieres seguir, sólo tienes que consultar los apuntes de física del colegio o buscar "movimiento rectilíneo uniformemente acelerado" o "movimiento curvilíneo" por internet.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

SplinterGU

yo creo que no se trata de tiempos o frame, si sabemos cuantos frames necesitamos por segundo y nuestro juego esta pensado haciendo uso de eso, quizas necesitamos usar frameskip para que los personajes se muevan en el tiempo que necesitamos pero a costa de perder frames de dibujo.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Arcontus

Osk, no encontré los ejemplos que comentas :(

Os explico el motivo para que podáis ayudarme a encontrar una solución. Estoy intentando hacer un videojuego en red, en el pasado ya hice mis "pinitos" con CDIV y logré comunicar un sencillo juego. En aquel momento, decidí sincronizar en cada frame la posicion de todos los jugadores, el resultado fue que en LAN funcionaba más o menos bien, pero a través de Internet la cosa iba muy lenta. Ahora trato de resolver el problema simplemente sincronizando eventos: el jugador a pulsado avanzar, el jugador a pulsado girar,... de manera que no tenga que preocuparme de sincronizar cada frame, liberando la red de tráfico inutil.

El problema es que para que este protocolo funcione, antes debo conseguir sincronizar el juego independientemente al rendimiento de la máquina donde se ejecute. Y de aquí las preguntas anteriores.

¿Alguna sugerencia?
5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

Windgate

A ver, os cuento:

Si haces:

x = x + 5;

Eso está MAL

Sobre todo en un juego online, si depende del FPS, unos jugadores corren más que otros.

Para solucionarlo existe un factor llamado deltaTime, que equivale al tiempo en segundos que tardó el último frame en dibujarse.

No sé si ese valor puede obtenerse en Bennu correctamente... Ya que es un float... Una vez lo tengas deberías hacer:

x = x + ( 5 * deltaTime);

Y eso teniendo en cuenta que la x es int, deberías usar una imagen intermedia.

¿Cómo aprendí esto? Pues os dejo la fuente:

http://unity3d.com/support/documentation/ScriptReference/Time-deltaTime.html
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Arcontus

#11
Quote from: Windgate on March 10, 2011, 09:18:46 PM
A ver, os cuento:

Si haces:

x = x + 5;

Eso está MAL

Sobre todo en un juego online, si depende del FPS, unos jugadores corren más que otros.

Para solucionarlo existe un factor llamado deltaTime, que equivale al tiempo en segundos que tardó el último frame en dibujarse.

No sé si ese valor puede obtenerse en Bennu correctamente... Ya que es un float... Una vez lo tengas deberías hacer:

x = x + ( 5 * deltaTime);

Y eso teniendo en cuenta que la x es int, deberías usar una imagen intermedia.

¿Cómo aprendí esto? Pues os dejo la fuente:

http://unity3d.com/support/documentation/ScriptReference/Time-deltaTime.html

Parece excelente!
Karma+

Por cierto, cuando dices:
"Y eso teniendo en cuenta que la x es int, deberías usar una imagen intermedia."
Has querido decir "variable intermedia", ¿verdad?


¿Sería apropiado leer al inicio del frame el tiempo desde ejecución con get_time() y restarlo al valor del frame anterior para obtener el deltaTime?

Usando este modo, ¿como se evalua el tema de colisiones para ordenadores muy lentos?

5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

SplinterGU

la unica forma de sincronizar bien el tiempo, en maquinas chicas, tenes que usar el parametro frameskip del set_fps.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Arcontus

SplinterGU, me parece más elegante la solución de Windgate ya que como dices, el frameskip penalizaría las máquinas omitiendo frames que podrían perfectamente pintarse y añadir suavidad al movimiento del juego.

Además, la sincronización del modo que comentas SplitnerGU, dependería tal y como la he entendido del resto de máquinas que esten en partida. Me imagino también que haría falta sincronizar este parametro muy amenudo entre los jugadores, ya que podría darse el caso de que se ejecute en cierto momento el antivirus y caigan los FPS de golpe, generando un desfase muy grande en la partida. Si puedo omitir ese tráfico en la red, creo que es interesante estudiar el rollo del tiempo.

Ahora bien, quizas sea imposible obtener el lapso entre el útlimo frame y el actual, pero por la definición de get_time(), parece apropiado para ello, ¿no?


5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

SplinterGU

#14
no, no, no, grave error... frameskip no penaliza, todo lo contrario, frameskip son frames maximos (de dibujado) que se pueden llegar a saltar si no alcanza la velocidad de proceso necesaria para cumplir con los fps deseados, o sea, la logica del juego funcionara al tiempo y fps deseados, solo que no todos los frames se dibujaran, se podran saltear hasta el maximo de fps definidos por frameskip, pero solo si la velocidad no alcanza...

todo lo que mencionas del antivirus y caidas de fps, se soluciona con el frameskip (que no indica saltar constantemente X frames, sino saltar tantos frames sean necesarios hasta un maximo de X frames si no se llega al fps deseado)

los frames se sincronizan por tiempo...

yo no creo que windgate haya dicho eso de que el frameskip penalizaria en maquinas chicas, si lo dijo, esta mal... yo entiendo que windgate quiso decir otra cosa.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2