[XNA] Rotar un sprite en 2D y desplazarlo hacia un vector posición

Lo que vamos a hacer es dibujar un sprite que rote hacia la dirección del mouse. Es decir, que moveremos el mouse y el sprite, en mitad de la pantalla, irá girando, de forma que quede orientado hacia el puntero del ratón. Después parametrizando el vector dirección resultante, haremos que el sprite se mueva hacia donde esté el ratón en dirección recta. Una vez sacado el polvo a los viejos libros de trigonometría es sencillo de hacer. El código es fácil, pero un diagrama de clases siempre ayuda a ver las cosas mejor.

La clase Game es la encargada de instanciar a los objetos MouseInput (controla el ratón y su posición en la pantalla, así como sustituir la textura del cursor) y sprite (imagen 2D que se pintará, rotará y desplazará por la pantalla siguiendo al mouse).

A ver… si sabemos el punto orígen, y el punto destino… necesitamos saber el ángulo de un triángulo… sabemos que uno de sus ángulos es recto… (tenemos casi todos los datos!), como era? ahh sí, con el Arcotangente!

Con un poco de wikipedia conseguiremos escribir el código siguiente:

float angulo = (float)Math.Atan2(raton.posicion.Y – nave.posicion.Y, raton.posicion.X – nave.posicion.X);

Ahora sólo tenemos que utilizar el angulo obtenido para rotar el sprite -ovsérvese que en el parámetro orígen hay que pasar un nuevo vector que es el centro del sprite que vamos a dibujar, para que la rotación la haga sobre ese eje-:

spriteBatch.Draw(this.textura, this.posicion, null, Color.White, anguloRadianes + MathHelper.ToRadians(90), new Vector2(this.textura.Width / 2, this.textura.Height / 2), 1.0f, SpriteEffects.None, 1);

Con ello ya tenemos la nave que va rotando sobre si misma y que «mira» siempre al puntero del mouse a medida que lo vamos moviendo por la pantalla.

Ahora, si queremos que la nave se mueva en la dirección del ratón.. ¿como lo hacemos? Si como a mi os falla la memoria recurriremos nuevamente a la wikipedia… Finalmente podremos actualizar la posición del sprite «nave» con el siguiente código:

 float velocidadUnitaria = 3.0f;

this.velocidad.X = (float)Math.Cos(anguloRadianes) * velocidadUnitaria;
this.velocidad.Y = (float)Math.Sin(anguloRadianes) * velocidadUnitaria;

this.posicion += this.velocidad;

La velocidad en los ejes X e Y se puede calcular a partir del coseno y el seno del ángulo que habíamos calculado previamente, y multiplicándolo por un valor estático (simplemente para hacer que el sprite se mueva un poco más rápido hacia el ratón). Finalmente se modifica la posición del sprite en función de la velocidad.

Si ejecutamos la aplicación, el resultado será parecido a este:

El código se puede descargar en este enlace

3 comentarios sobre “[XNA] Rotar un sprite en 2D y desplazarlo hacia un vector posición”

  1. Creo que la x se calcula con el seno, no con el coseno, lo digo porque me ha funcionado con el seno y con el coseno me da invertido.

    Exelente el turorial, me salvo la vida.

  2. Lo haría encantado, pero mira, álguien ya lo ha hecho en este post:

    http://forums.xna.com/forums/p/33472/191913.aspx

    Básicamente lo que necesitas hacer es obtener la posición del mouse, crear una instancia del objeto Rectangle en esa posición, con un ancho y alto que tu creas conveniente (5px por ejemplo). Después creas otro rectángulo para el sprite. En el método Update reposicionas el rectangle del mouse acorde a su posición, y ya sólo te queda comprobar si hay intersección entre el rectángulo del mouse y el del sprite. Si lo hay, desplazas el sprite al vector posición del mouse.

    Un saludo,

    Jesús

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *