程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> XNA入門教程(三) 簡單的動畫

XNA入門教程(三) 簡單的動畫

編輯:關於.NET

繼續我們的XNA之旅...

上周,我們簡單的介紹了XNA的相關控制器,並且實現了鼠標和鍵盤對屏幕內的 某個Sprite(精靈)進行簡單的位置控制.

但是,美中不足的,我們並沒有實現Sprite人物的移動動作,即Animation.

現在,我們繼續上周所講的, 實現簡單的動畫.

關於Animation

對動畫有所了解的朋友對於逐幀動畫一定不會陌生.其以最簡單的形式,將各 動畫元件相鄰單位時間的動作位置記錄在每個幀裡.這樣,當我們

一幀幀播放時,由於視覺暫留現象,我們便能看到相對"運動"的動畫了.我們通 常看到的GIF動畫,就是基於這個原理的.

回來說們的游戲,由於在一般游戲內Sprite的"動作"都是有限可枚舉得,我們 便同樣可以用類似的方案來記錄Sprite的所有動作.

我們現在嘗試用上面的GIF來實現我們的移動動畫.

由於原生的XNA不支持直接從GIF動畫中讀取各幀圖象,即不能直接從Content 中Load到GIf動畫或其相關幀圖像

雖然從技術上而言,由於有很多開源項目支持如何讀取或生成GIF(有興趣的 朋友可以看看這裡),我們完全可以通過之自己加載Gif動畫的某幀來實現游戲 動畫。

但這裡,我們老老實實的將各幀拆開,得到以下的圖像。

這樣,我們只要通過加載不同的同一圖像的不同位置,便可實現人物的”運 動“了 。

加載動畫

我們回到這個系列的第一篇

在sprite的Draw時候,我們提供以下重載參數

其中我們就可以通過設置sourceRectangle的值來顯示texture2D的一部分了 。

經過計算,我們得知每個單獨人物的尺寸為60X110

這樣,我們便用以下方法來動態顯示不同“幀”的人物動畫了

protected override void Update(GameTime gameTime)
         {
             KeyboardState state = Keyboard.GetState ();
             if (state.IsKeyDown(Keys.Up))
             {
                 this.Position.Y -= 10;
             }
             if (state.IsKeyDown(Keys.Down))
             {
                 this.Position.Y +=10;
             }
             if (state.IsKeyDown(Keys.Left))
             {
                 this.Position.X -= 10;
             }
             if (state.IsKeyDown(Keys.Right))
             {
                 this.Position.X += 10;
             }
             MouseState state1 = Mouse.GetState ();
             if (state1.LeftButton ==  ButtonState.Pressed)
             {
                 IPathFinder pathFinder = new  PathFinderFast(m_matrix);
                 pathFinder.Formula =  HeuristicFormula.Manhattan;
                 pathFinder.SearchLimit =  2000;
                 m_path = pathFinder.FindPath(new  Vector2((int)this.Position.X, (int)this.Position.Y), new Vector2 (state1.X , state1.Y ));
             }
             if (this.m_path != null &&  this.m_path.Count() != 0)
             {
                 int index = this.m_path.Count()  - 1;
                 this.Position = new Vector2 (this.m_path[index].X, this.m_path[index].Y);
                 this.m_path.RemoveAt(index);
                 return;
             }
             m_frameIndex = m_frameIndex + 1 >  5 ? 0 : m_frameIndex + 1;
             base.Update(gameTime);
         }
         protected override void Draw(GameTime  gameTime)
         {
             GraphicsDevice.Clear (Color.CornflowerBlue);
             spriteBatch.Begin();
             this.spriteBatch.Draw(this.img, new  Vector2(this.Position.X, this.Position.Y), new Rectangle (m_frameIndex * m_frameSize.X, 0, m_frameSize.X, m_frameSize.Y),  Color.White, 0, Vector2.Zero, 1f, SpriteEffects.None, 0);
             spriteBatch.End();
             base.Draw(gameTime);
         }

其中,m_frameSize 便是我們每個單獨動作的尺寸   Point m_frameSize = new Point(60, 110);

編譯後,我們 便能看到“動”的人物了。

調節動畫的“速度” 

我們很快發現,用這個方法顯示的逐幀動畫很暴走。即動畫幀變化速度太快 了。

這其實是由於我們的動畫變幀邏輯在Update方法中,而通常,update的調用 是基於游戲內置循環的,即根據XNA的默認刷新率---60fps(Frame/Second)。

如果直接用默認速度的幀循環速度,一則CPU使用率太高,二則也沒有這個必 要。這裡,我們決心“降低”幀數。

我們知道,在XNA中,我們可以通過gameTime.ElapsedGameTime得到自從上次 循環結束後到現在的時間。

因此,我們可以將我們的Update方法改成如下結構

protected override void Update(GameTime gameTime)
         {
             timeSinceLastFrame +=  gameTime.ElapsedGameTime.Milliseconds;
             if (timeSinceLastFrame >  millisecondsPerFrame)
             {
                 timeSinceLastFrame -=  millisecondsPerFrame;
                 //TODO
             }
         }

其中,int millisecondsPerFrame = 50;就是我們設定的閥值。

經過以上修改,我們就會發現幀速明顯下降,當然,CPU使用率也下去了。

一些細節/P>

或許大家發現,人物不動時還在原地跑步,只需我們加上類似下文邏輯即可 。

if (isActive)
                 {
                     m_frameIndex =  m_frameIndex + 1 > 5 ? 0 : m_frameIndex + 1;
                 }
                 else
                 {
                     m_frameIndex = 0;
                 }

總結

本文主要簡單介紹了逐幀動畫及其在XNA中的實現。並且引入了幀速的控制。 相信各位看完本文,便會對XNA的簡單2D動畫有了一個全面的了解。

本例源代碼:http://files.cnblogs.com/edwin1986/WindowsGame3.rar

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved