2011-11-30 56 views
1

我正在用XNA構建我的第一場比賽,我試圖讓我的精靈運行。 一切工作正常,爲第一個精靈。 例如:如果我向右轉(D)我的精靈看起來是正確的,如果我離開(A)我的精靈向左看,如果我沒有碰到任何東西,我的精靈是默認的。 現在我想要做的是如果精靈去右,我想要或者改變精靈(左腿,右腿,左腿等)。x當前是當前精靈繪製xRunRight是第一次運行的精靈和xRunRight1是在運行時必須與xRunRight進行交換。 這是我現在有:做一個基本的運行精靈效果

protected override void Update(GameTime gameTime) 
    { 
     float timer = 0f; 
     float interval = 50f; 
     bool frame1 = false ; 
     bool frame2 = false; 
     bool running = false; 

     KeyboardState FaKeyboard = Keyboard.GetState(); 
     // Allows the game to exit 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 


      if ((FaKeyboard.IsKeyUp(Keys.A)) || (FaKeyboard.IsKeyUp(Keys.D))) 
      { 
       xCurrent = xDefault; 
      } 

      if (FaKeyboard.IsKeyDown(Keys.D)) 
      { 

       timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds; 
       if (timer > interval) 
       { 
        if (frame1) 
        { 
         xCurrent = xRunRight; 
         frame1 = false; 
        } 
        else 
        { 
         xCurrent = xRunRight1; 
         frame1 = true; 

        } 
       } 

       xPosition += xDeplacement; 


      } 

任何想法...?我一直堅持這一段時間.. 在此先感謝,讓我知道如果你需要從代碼中的任何其他部分。

+0

我知道幀1,幀2和(定時器>間隔)邏輯不起作用,但它是我意識到它不起作用之前所處的位置。 – phadaphunk

回答

2

您忘了重置計時器,您可以在遇到timer interval條件時執行此操作。另外,50ms似乎有點太小了一段時間,也許你可以做到400ms?

除此之外,看起來不錯,它會做你想做的。

或者,您可以考慮製作動畫精靈步行。你所做的就是製作一個相同大小的步行動畫精靈圖像。你只畫出這個圖像的一部分(一個精靈),然後根據時間移動它們。

這裏是什麼可能是動畫紋理的快速代碼:

class AnimatedTexture2D : Texture2D 
{ 
    int _numberOfImages; 
    int _currentImage = 0; 

    int _timeInterval; 
    int _spriteWidth; 

    public Rectangle DrawFromRectangle 
    { 
     get 
     { 
      return new Rectangle(_currentImage * _spriteWidth, 0, _spriteWidth, this.Height); 
     } 
    } 

    public AnimatedTexture2D(Texture2D entireImage, int spriteWidth, int numberOfImages, int timeInterval) 
     : base(entireImage.GraphicsDevice, entireImage.Width, entireImage.Height) 
    { 
     _numberOfImages = numberOfImages; 
     _timeInterval = timeInterval; 
     _spriteWidth = spriteWidth; 

     Color[] data = new Color[entireImage.Width * entireImage.Height]; 
     entireImage.GetData<Color>(0, new Rectangle(0, 0, entireImage.Width, entireImage.Height), data, 0, entireImage.Width * entireImage.Height); 

     this.SetData<Color>(data); 
    } 

    public void Animate(GameTime gameTime) 
    { 
     int totalImageTime = _timeInterval * _numberOfImages; 
     int currentPoint = (int)gameTime.TotalGameTime.TotalMilliseconds % totalImageTime; 

     _currentImage = currentPoint/_timeInterval; 
    } 
} 

用法相當簡單:

1)某處聲明它:

AnimatedTexture2D animatedTexture; 

2)啓動它與你的紋理(我有一個2560×64序列的40 64 * 64圖像),其中個別圖像水平放置在彼此相鄰:

animatedTexture = new AnimatedTexture2D(Content.Load<Texture2D>(@"Textures\Loading"), 64, 40, 20); 

3)在您的Update()方法,調用:

animatedTexture.Animate(gameTime); 

4)在draw()方法,調用:

SpriteBatch.Draw(animatedTexture, new Rectangle(20, 20, 64, 64), animatedTexture.DrawFromRectangle, Color.White); 

不要忘了DrawFromRectangle部分4 ! (注意目標矩形使用聲明的單獨部分寬度,而不是整個紋理寬度,這是我測試的2560像素)

現在,在您的代碼中,您可以忘記間隔部分和遊戲時間部分,並且可以只是用這個而不是默認的!另外,如果你不喜歡我的計時代碼(它的超級簡單但缺乏重置動畫的方法),請改變它,讓你有一個經過時間的變量,並像你在自己的代碼中那樣添加它,並用它來改變_currentImage。您甚至可以將該變量設置爲公開,以便您可以使用它重置動畫(或將其設置爲指定點)。

當然,你也可以使默認的一個動畫紋理只有一幀,所以你可以在任何地方使用相同的代碼。希望這可以幫助!

1

您需要保持最後一次更新(..)被調用,並且間隔應該是...很好..間隔,即ElapsedGameTime和上次調用ElapsedGameTime之間的差值。 使用類的新成員(LastElapsedGameTimeUpdateCalled)或您的子靜態成員執行此操作。

1

如果您知道每個動畫將具有相同數量的幀,您可以爲每個精靈保留3個變量(封裝在類中以獲得最佳效果)。 BaseFrame是一個整數,用於保存全局動畫編號。 子框架是保存您當前所在框架的動畫的偏移量。 FrameAccumulator保存定時信息。

每次更新被調用時,將自上次更新以來的ms數加到累加器中。一旦累加器高於動畫定時,增加SubFrame並重置累加器。檢查subFrame是否大於每個動畫的幀數,如果是,則將其設置爲0.您可以通過添加BaseFrame + Subframe來從中獲取真實幀索引。當您需要顯示不同的動畫時,只需更改BaseFrame。

可以說每個動畫都有3個幀,並且您有2個動畫。你將有6個總幀。 RunLeft將是BaseFrame 0,RunRight將是BaseFrame 3.這應該很容易給你繪製的幀號。

相關問題