2011-01-11 7 views
2

ヘイ私のカメラをスプライトに追従させようとしていて、何らかの理由でスプライトが常にカメラより速く動いていて、カメラが画面に固定できません。私はカメラが常にスプライトの中心に来て、彼が動くように彼に従うようにしたいと思います。XNA 2Dカメラ - アニメーションスプライトにロック/センターする方法

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 

namespace wintertermrpg 
{ 
    public class AnimatedSprite 
    { 
     public enum Facing 
     { 
      Left, 
      Right, 
      Up, 
      Down 
     } 
     public Facing facingDirection; 

     public Dictionary<string, FrameAnimation> Animations = new Dictionary<string,  FrameAnimation>(); 
     Camera cam = new Camera(); 
     public Vector2 Position = Vector2.Zero; 
     Texture2D texture; 
     public bool IsCharacter = false; 
     public bool isAnimating = true; 
     string animationName = null; 
     float speed = 2f; 

     public float Speed 
     { 
      get { return speed; } 
      set { speed = Math.Max(value, .1f); } 
     } 

     public string CurrentAnimationName 
     { 
      get { return animationName; } 
      set 
      { 
       if (Animations.ContainsKey(value)) 
        animationName = value; 
      } 
     } 

     public Vector2 OriginOffset = Vector2.Zero; 
     public Vector2 Origin 
     { 
      get { return Position + OriginOffset; } 
     } 

     public Vector2 Center 
     { 
      get 
      { 
       return Position + new Vector2(
        CurrentAnimation.currentRect.Width/2, 
        CurrentAnimation.currentRect.Height/2); 
      } 
     } 

     public FrameAnimation CurrentAnimation 
     { 
      get 
      { 
       if (!string.IsNullOrEmpty(animationName)) 
        return Animations[animationName]; 
       else 
        return null; 
      } 
     } 

     public AnimatedSprite(Texture2D texture, bool isCharacter) 
     { 
      this.texture = texture; 
      IsCharacter = isCharacter; 
     } 

     public AnimatedSprite(Texture2D texture, bool isCharacter, Camera cam) 
     { 
      this.texture = texture; 
      IsCharacter = isCharacter; 
      this.cam = cam; 
     } 

     public void clampToArea(int width, int height) 
     { 
      if (Position.X < 0) 
       Position.X = 0; 
      if (Position.Y < 0) 
       Position.Y = 0; 
      if (Position.X > width - CurrentAnimation.currentRect.Width) 
       Position.X = width - CurrentAnimation.currentRect.Width; 
      if (Position.Y > height - CurrentAnimation.currentRect.Height) 
       Position.Y = height - CurrentAnimation.currentRect.Height; 
     } 

     private void updateSpriteAnimation(Vector2 motion) 
     { 
      float motionAngle = (float)Math.Atan2(motion.Y, motion.X); 

      if (motionAngle >= -MathHelper.PiOver4 && 
       motionAngle <= MathHelper.PiOver4) 
       CurrentAnimationName = "Right"; 
      else if (motionAngle >= -MathHelper.PiOver4 && 
       motionAngle <= 3f * MathHelper.PiOver4) 
       CurrentAnimationName = "Down"; 
      else if (motionAngle <= -MathHelper.PiOver4 && 
       motionAngle >= -3f * MathHelper.PiOver4) 
       CurrentAnimationName = "Up"; 
      else 
       CurrentAnimationName = "Left"; 
     } 

     public void update(GameTime gameTime) 
     { 
      GamePadState state = GamePad.GetState(PlayerIndex.One); 
      if (IsCharacter) 
      { 
       Vector2 movement = Vector2.Zero; 
       if (state.ThumbSticks.Left.X < 0) 
       { 
        movement.X--; 
        facingDirection = Facing.Left; 
       } 
       if (state.ThumbSticks.Left.X > 0) 
       { 
        movement.X++; 
        facingDirection = Facing.Right; 
       } 
       if (state.ThumbSticks.Left.Y > 0) 
       { 
        movement.Y--; 
        facingDirection = Facing.Up; 
       } 
       if (state.ThumbSticks.Left.Y < 0) 
       { 
        movement.Y++; 
        facingDirection = Facing.Down; 
       } 
       if (movement != Vector2.Zero) 
       { 
        movement.Normalize(); 
        Position += movement; 
        cam.Pos = Position; 
        updateSpriteAnimation(movement); 
        isAnimating = true; 
       } 
       else 
        isAnimating = false; 

      } 

      if (!isAnimating) 
       return; 
      FrameAnimation animation = CurrentAnimation; 

      if (animation == null) 
      { 
       if (Animations.Count > 0) 
       { 
        string[] keys = new string[Animations.Count]; 
        Animations.Keys.CopyTo(keys, 0); 
        animationName = keys[0]; 
        animation = CurrentAnimation; 
       } 
       else 
        return; 
      } 
      animation.Update(gameTime); 

     } 

     public void draw(SpriteBatch sb) 
     { 
      FrameAnimation animation = CurrentAnimation; 
      if (animation != null) 
      { 
       sb.Draw(texture, Position, animation.currentRect, Color.White); 
      } 
     } 
    } 
} 
+0

まず、updateSpriteAnimationを呼び出してから、カメラの位置を新しいスプライト位置に設定しますか? –

+0

それはまだまったく同じことをしません – mramazingguy

答えて

0

ここでは、あなたがしようとしているものに対するより簡単な解決策があります。

あなたのキャラクターは、目に見えないボックスの中にスクリーン上に配置されていますか?キャラクターがこのバウンディングボックスの外側に移動しようとすると、あなたはそのレベルを彼の動きにスクロールさせます。キャラクターに絶対的なカメラの焦点を当てたい場合は、キャラクターの周りをスクロールするだけです。画面上の文字の位置と、レベルのオフセットスクロールを追跡する必要があります。あなたがそれらの両方を持っているなら、あなたのキャラクターが衝突のための「レベル」のどこにいるかを知っています。

これはあなたが探しているものではない場合は申し訳ありませんが、はるかに簡単なアプローチです。

6

カメラは、SpriteBatch.Beginメソッドのビュー行列を生成する必要があります。ビュー行列は2つの変換を行わなければなりません。

  1. ウィンドウの中央に左から の原点を移動します。 (ハーフビューサイズを追加)
  2. 文字が中央の にあるので と翻訳されています。

    using Microsoft.Xna.Framework; 
    
    namespace wintertermrpg 
    { 
        public class Camera 
        { 
         public Matrix viewMatrix; 
         private Vector2 m_position; 
         private Vector2 m_halfViewSize; 
    
         public Camera(Rectangle clientRect) 
         { 
          m_halfViewSize = new Vector2(clientRect.Width * 0.5f, clientRect.Height * 0.5f); 
          UpdateViewMatrix(); 
         } 
    
         public Vector2 Pos 
         { 
          get 
          { 
           return m_position; 
          } 
    
          set 
          { 
           m_position = value; 
           UpdateViewMatrix(); 
          } 
         } 
    
         private void UpdateViewMatrix() 
         { 
          viewMatrix = Matrix.CreateTranslation(m_halfViewSize.X - m_position.X, m_halfViewSize.Y - m_position.Y, 0.0f); 
         } 
        } 
    } 
    

    次に、あなただけのSpriteBatch.Begin方法でビュー行列を設定する必要があります:

    spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, m_camera.viewMatrix); 
    
    次のコードは、これを行いカメラクラスを示し

(文字 位置を減算)

関連する問題