Estoy haciendo un juego en C++ donde hay un tanque que puede moverse en un escenario. El tanque tiene un ángulo (flotante, en grados, y supongo que el tanque está a 0º cuando su cañón apunta hacia la derecha), una velocidad (flotante), y hay una constante de tiempo llamada "deltaT" (flotación).C++ gamedev: truncar float a int
Cuando el jugador mueve el tanque hacia adelante, utilizo la trigonometría y la ecuación física de la posición en función del tiempo (quiero decir X (t), no sé cómo se dice en inglés) para calcular el nuevo las coordenadas del tanque en el escenario.
Este es mi problema: debido al paso de float a int, los valores más cercanos a cero no se tienen en cuenta. Entonces, en ciertos ángulos, el tanque aparece girado, pero se mueve en una dirección diferente.
Esto es lo que hace mi código:
1 - primero, I separar la velocidad en sus componentes X e Y, utilizando el ángulo en wich el tanque se está moviendo:
float speedX = this->speed * cos(this->angle);
float speedY = this->speed * sin(this->angle);
2 - a continuación, utilizar la ecuación he mencionado anteriormente para obtener las nuevas coordenadas:
this->x = (int) ceil(this->x + (speedX * deltaT));
this->y = (int) ceil(this->y - (speedY * deltaT));
el problema comienza en el primer paso: en ciertos ángulos, el valor del cos o el pecado es muy cercana a cero. Entonces, cuando lo multiplico por velocidad para obtener, digamos, speedX, todavía tengo un número muy bajo, y luego cuando lo multiplico para deltaT todavía es muy bajo, y finalmente cuando aplica el ceil, esa cantidad se pierde por completo .
Por ejemplo, a 94º, con el delta T = 1,5, y la velocidad = 2, y asumiendo que el valor inicial de X es de 400, tenemos:
speedX = -0.1395...
this->x = 400 //it must be 399.86..., but stays in 400 due to the ceiling
Por lo tanto, en mi juego del tanque aparece girado, pero se mueve hacia adelante. Además, a veces se mueve hacia atrás pero hacia adelante y viceversa.
¿Cómo puedo hacer para que la dirección del tanque sea más precisa? Para aumentar la velocidad o el valor de deltaT no son opciones, ya que se trata de un tanque, no una fórmula 1: P
+1: buen trabajo explicando su pregunta y proporcionando un código mínimo relevante. – ObscureRobot
Almacenar ángulos en grados rara vez es útil. C++ funciona de forma nativa en radianes. Terminará convirtiendo de ida y vuelta. La única excepción en la que no usaría radianes es cuando tiene una matriz de sprites, uno para cada rotación del tanque. En ese caso, puede ser útil usar el índice de matriz en su lugar. Pero nadie haría 360 sprites; 128 (4x32) sería mucho más común. – MSalters
@MSalters Sí, realicé sobre los radianes demasiado tarde. Pero, en realidad, el código que publiqué está un poco simplificado: no utilizo las funciones sin y cos de la biblioteca matemática, pero he tabulado los valores del cos y del sin de ciertos ángulos, para evitar calcular ellos en tiempo de ejecución. Además, para las imágenes giradas, no tengo 128 sprites, pero tengo solo uno, y uso la función "rotozoomSurface" (en SDL_gfx lib, un complemento para SDL), que funciona con grados. – Granjero