Aceleración independiente de la velocidad de fotogtwigs

¿Es esta la manera correcta, o al less una manera que funciona, para hacer frente a las aceleraciones en los entornos de pasos de time variables?

// Pseudo-code void onUpdate() { mySpeed += acceleration * timeElapsed; // More specifically, this part myPosition += mySpeed * timeElapsed; } 

A decir verdad, estoy usando un timeElapsed constante definido por (1.0f / FPS_LIMIT) , siendo FPS_LIMIT el valor de la FPS_LIMIT de fotogtwigs en la que quiero que se bloquee el juego. Las velocidades y aceleraciones se definen de las siguientes maneras:

  #define FRAME_DURATION (1.0f / FPS_LIMIT) #define RUNNING_SPEED 42 * FRAME_DURATION #define GRAVITY 42 * FRAME_DURATION 

Y me he dado count de que, cuanto más aumente mi FPS_LIMIT , más rápido se acelerarán las cosas. Bueno, es obvio (o no) que estoy usando lógica defectuosa para definir las constantes de aceleración, pero también me gustaría saber qué estoy haciendo mal y cuál es la forma correcta de calcular estos valores, porque lo que haré prácticamente a través de mis scripts será tan simple como esto:

  void onUpdate() { mySpeed += acceleration; myPosition += mySpeed; } 

Como si la independencia de framerate ni siquiera existiera.

Si desea get asistencia técnica, estoy usando SFML simple para los pasos de time fijos, a través de una llamada a window.setFramerateLimit(FPS_LIMIT) .

En primer lugar, su time timeElapsed absolutamente no debería ser reparado. Mida el time real del cuadro. Un montón de artículos sobre eso. Incluso con cosas como una llamada a setFramerateLimit , es posible que el ciclo del juego no se ejecute en ese momento exacto en cada fotogtwig.

 #define FRAME_DURATION (1.0f / FPS_LIMIT) #define RUNNING_SPEED 42 * FRAME_DURATION #define GRAVITY 42 * FRAME_DURATION 

Esta parte no tiene sentido. ¿Por qué la velocidad depende de una variable de time? La velocidad es distance/time . Por ejemplo, 1.2 meters/second . Multiplica velocidad por time para get distancia.

Tome su time de cuadro transcurrido y multiplíquelo por la velocidad para get la cancelación de la unidad.

 timeElapsed = 7; // milliseconds --> .007 seconds speed = 1.2; // meters / second movement = speed * timeElapsed; 

Trabajando ese último pedazo en el papel nos da:

 movement = 1.2 meters / second * .007 seconds = movement = (1.2 * .007) * (1 meters * 1 second / 1 second) movement = .0084 * (1 meters) movement = .0084 meters 

En cuanto a la aceleración, es lo mismo. La aceleración está en meters/(second*second) (metros por segundo al cuadrado). Obtienes velocidad (o velocidad en el caso monodimensional) con velocity=acceleration*time=meters/(second*second)*second=meters/second .

Entonces sí, la línea en cuestión es válida. Sin embargo, generalmente se trata de velocidad , no de velocidad . La diferencia es la dirección. La velocidad dice que tan rápido vas, la velocidad dice qué tan rápido vas en la dirección en que vas. Esto es importante para la gravedad La gravedad no solo te hace acelerar; si estás saltando sobre un hoyo, la fuerza de gravedad hará que disminuyas la velocidad, te detengas por un instante en el cenit de tu arco y luego comienzas a hacer que aceleres hacia abajo. Probablemente haya entendido todo esto, estoy seguro, pero sea preciso con su terminología cuando pueda. Evitará problemas en el futuro.

 void onUpdate() { mySpeed += acceleration; myPosition += mySpeed; } 

Esto tiene poco sentido, y nuevamente, terminología. En este caso, está agregando velocidad a otro valor de velocidad (una aceleración premultiplicada con el time), y luego la segunda línea no tiene ningún sentido. La aceleración es la segunda derivada de la position con respecto al time, por lo que debe integrar el time dos veces para calcular correctamente la position. Incluso si premultiplicas tu velocidad inicial, el resultado de agregar la aceleración premultiplicada la desequilibrará. Debes multiplicar por time en la segunda línea, y casi puedo garantizarte que estarás mucho mejor multiplicando la aceleración por time en la primera línea.

Usando la integración Eular (que supongo que es lo que estabas buscando aquí), tus constantes deberían definirse independientemente del time de tu fotogtwig. Esto se debe a que tiene en count el time durante su ciclo de actualización.

Entonces tus constantes se vuelven:

 #define FRAME_DURATION (1.0f / FPS_LIMIT) #define RUNNING_SPEED 42.0f #define GRAVITY 42.0f 

Esto debería solucionar la incoinheritance que está experimentando con el ciclo de actualización.

Sin embargo, notará que esto hace que sus objects se aceleren (y se ejecuten) mucho más rápido de lo que solían hacerlo. Para solucionarlo, puede elegir una tasa de cuadros arbitraria y usarla para recalcular sus constantes:

 #define RUNNING_SPEED 0.7f // 42 / 60 #define GRAVITY 0.7f 

Aunque recomendaría usar valores más realists:

 #define GRAVITY 9.8f // Earth's gravity in meters per second squanetworking 

Esto significa que cuando vayas a agregar nuevos objects a tu juego, puedes basar sus properties en objects del mundo real e instantáneamente tendrás una física que parece consistente, por ejemplo, tu jugador podría medir 1.6 metros de altura, la altura del promedio del humano .

También estoy de acuerdo con Sean en que debes ser preciso con tu terminología, y la próxima vez tu pseudo código debería hacer uso de las constantes que has definido para que podamos ver exactamente lo que estás tratando de lograr.