2013-08-23 5 views
0

У меня есть стрелка в моем XNA проекта, который я успешно сделал, чтобы повернуть в сторону положения мыши с этим code-XNA Направление на основе ротации

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 

namespace Test 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 

     Texture2D arrowSprite; 
     float rotation; 
     Vector2 direction; 
     Vector2 position; 
     float speed; 
     Vector2 mousePos; 
     SpriteFont font1; 

     public Game1() 
     { 
      graphics = new GraphicsDeviceManager(this); 
      Content.RootDirectory = "Content"; 
     } 

     /// <summary> 
     /// Allows the game to perform any initialization it needs to before starting to run. 
     /// This is where it can query for any required services and load any non-graphic 
     /// related content. Calling base.Initialize will enumerate through any components 
     /// and initialize them as well. 
     /// </summary> 
     protected override void Initialize() 
     { 
      // TODO: Add your initialization logic here 
      position = new Vector2(GraphicsDevice.Viewport.Width/2, GraphicsDevice.Viewport.Height/5); 
      speed = 1000.0f; 
      this.IsMouseVisible = true; 
      MouseState mouse = Mouse.GetState(); 
      mousePos.X = mouse.X; 
      mousePos.Y = mouse.Y; 
      rotation = Angle(position, mousePos); 
      base.Initialize(); 
     } 

     /// <summary> 
     /// LoadContent will be called once per game and is the place to load 
     /// all of your content. 
     /// </summary> 
     protected override void LoadContent() 
     { 
      // Create a new SpriteBatch, which can be used to draw textures. 
      spriteBatch = new SpriteBatch(GraphicsDevice); 
      arrowSprite = Content.Load<Texture2D>("Sprites\\Arrow"); 
      font1 = Content.Load<SpriteFont>("Sprites\\Test"); 
      // TODO: use this.Content to load your game content here 
     } 

     /// <summary> 
     /// UnloadContent will be called once per game and is the place to unload 
     /// all content. 
     /// </summary> 
     protected override void UnloadContent() 
     { 
      // TODO: Unload any non ContentManager content here 
     } 

     /// <summary> 
     /// Allows the game to run logic such as updating the world, 
     /// checking for collisions, gathering input, and playing audio. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     protected override void Update(GameTime gameTime) 
     { 
      // Allows the game to exit 
      if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
       this.Exit(); 

      // TODO: Add your update logic here 
      MouseState mouse = Mouse.GetState(); 
      mousePos.X = mouse.X; 
      mousePos.Y = mouse.Y; 
      rotation = Angle(position, mousePos); 
      direction = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)); 
      position += direction * 10.0f * (float)gameTime.ElapsedGameTime.TotalSeconds; 
      base.Update(gameTime); 
     } 

     /// <summary> 
     /// This is called when the game should draw itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     protected override void Draw(GameTime gameTime) 
     { 
      GraphicsDevice.Clear(Color.CornflowerBlue); 

      // TODO: Add your drawing code here 
      spriteBatch.Begin(); 
      spriteBatch.Draw(arrowSprite, position, null, Color.White, rotation, new Vector2(arrowSprite.Width/2, arrowSprite.Height/2), 1.0f, SpriteEffects.None, 1.0f); 
      spriteBatch.DrawString(font1, mousePos.X.ToString()+ " " + mousePos.Y.ToString(), new Vector2(GraphicsDevice.Viewport.Width/2, 0), Color.White); 
      //spriteBatch.DrawString(font1, "Rotation:" + rotation.ToString(), Vector2.Zero, Color.White); 
      spriteBatch.DrawString(font1, "Direction" + direction.ToString(), Vector2.Zero, Color.White); 
      spriteBatch.End(); 
      base.Draw(gameTime); 
     } 

     public static float Angle(Vector2 from, Vector2 to) 
     { 
      return (float)Math.Atan2(from.X - to.X, to.Y - from.Y); 
     } 
    } 
} 

Однако, когда я запускаю код, в стрелка просто поворачивает ВОКРУГ мыши, и радиус, с которым он это делает, немного расширяется со временем. Я хочу, чтобы стрелка поворачивалась к мыши, а затем она двигалась к области, в которую она повернута. Спасибо, любая помощь приветствуется.

ответ

-1

Я заметил, что ты сказал

и радиус, при котором она так слегка расширяется с течением времени

и увидел эту

position += direction * 10.0f * (float)gameTime.ElapsedGameTime.TotalSeconds;

В обновлении XNA называется 60 раз в секунду в теории и gameTime.ElapsedGameTime.TotalSeconds постоянно увеличивается каждую секунду. Если вы добавите значение этого уравнения в позицию переменной, он постепенно изменит «орбиту» из-за этого приращения. Кроме того, из того, что я могу собрать, как вы работаете, повороты могут возвращать отрицательный (подача назад «орбиты»), который будет возвращать необычные числа при умножении на положительный поплавок.

0

Ваш расчет Angle() означает, что стрелка спрайт направлена ​​вверх в исходном состоянии. Но тогда ваш расчет direction неверен. Расчет направления и углов может быть выполнен следующим образом:

private void CalculateAngleAndDirection(Vector2 from, Vector2 to, out Vector2 direction, out float angle) 
{ 
    direction = to - from; //get the direction vector 
    direction.Normalize(); //make it a unit vector 
    angle = (float)Math.Atan2(-direction.X, direction.Y); 
} 

protected override void Update(GameTime gameTime) 
{ 
    //... 
    MouseState mouse = Mouse.GetState(); 
    mousePos.X = mouse.X; 
    mousePos.Y = mouse.Y; 
    CalculateAngleAndDirection(position, mousePos, out direction, out angle); 
    position += direction * 10.0f * (float)gameTime.ElapsedGameTime.TotalSeconds; 
    base.Update(gameTime); 
} 
Смежные вопросы