Presentation is loading. Please wait.

Presentation is loading. Please wait.

Animation (動畫) 靜宜大學資工系 蔡奇偉 副教授 © 2011. 大綱 Introduction Game Loop Motion Animation Game Components 範例 參考資料.

Similar presentations


Presentation on theme: "Animation (動畫) 靜宜大學資工系 蔡奇偉 副教授 © 2011. 大綱 Introduction Game Loop Motion Animation Game Components 範例 參考資料."— Presentation transcript:

1 Animation (動畫) 靜宜大學資工系 蔡奇偉 副教授 © 2011

2 大綱 Introduction Game Loop Motion Animation Game Components 範例 參考資料

3 簡介 動畫是由隨時間而改變的圖片所產生 2D 遊戲動畫可由下列三種技巧產生: Motion Animation Sprite Animation Motion + Sprite Animation

4 XNA Game Loop Initialize() LoadContent () Game quit? Draw () UnLoadContent () Y Update () N Exit

5 Fixed-Step Game Loops A fixed-step Game tries to call its Update method on the fixed interval specified in TargetElapsedTime. Setting Game.IsFixedTimeStep to true causes a Game to use a fixed-step game loop. A new XNA project uses a fixed-step game loop with a default TargetElapsedTime of 1/60th of a second. In a fixed-step game loop, Game calls Update once the TargetElapsedTime has elapsed. After Update is called, if it is not time to call Update again, Game calls Draw. After Draw is called, if it is not time to call Update again, Game idles until it is time to call Update.

6 If Update takes too long to process, Game sets IsRunningSlowly to true and calls Update again, without calling Draw in between. When an update runs longer than the TargetElapsedTime, Game responds by calling Update extra times and dropping the frames associated with those updates to catch up. This ensures that Update will have been called the expected number of times when the game loop catches up from a slowdown. You can check the value of IsRunningSlowly in your Update if you want to detect dropped frames and shorten your Update processing to compensate. You can reset the elapsed times by calling ResetElapsedTime.

7 Variable-Step Game Loops A variable-step game calls its Update and Draw methods in a continuous loop without regard to the TargetElapsedTime. Setting Game.IsFixedTimeStep to false causes a Game to use a variable-step game loop.

8 Animation and Timing Using a fixed step allows game logic to use the TargetElapsedTime as its basic unit of time and assume that Update will be called at that interval. Using a variable step requires the game logic and animation code to be based on ElapsedGameTime to ensure smooth gameplay. Because the Update method is called immediately after the previous frame is drawn, the time between calls to Update can vary. Without taking the time between calls into account, the game would seem to speed up and slow down. The time elapsed between calls to the Update method is available in the Update method's gameTime parameter. You can reset the elapsed times by calling ResetElapsedTime.

9 When using a variable-step game loop, you should express rates—such as the distance a sprite moves—in game units per millisecond (ms). The amount a sprite moves in any given update can then be calculated as the rate of the sprite times the elapsed time. Using this approach to calculate the distance the sprite moved ensures that the sprite will move consistently if the speed of the game or computer varies.

10 Motion Animation 遊戲角色的位置隨時間而變。 玩家控制角色移動 自主性移動:遊戲角色按照既定路徑而移動, 不受外界因素的干擾(碰撞除外)。 被動性移動:遊戲角色的移動受到其他角色的 牽引,如追逐與逃脫。 如何設定移動路徑?

11 移動路徑 直線路徑 速率 (velocity) = 單位時間的位移向量 (dx, dy) 速度 (speed) = 單位時間的位移長度 = | (dx, dy) | 距離 (distance) = 速度  時間

12 多線段路徑 計算簡單 足夠密的多線段可以用來模擬曲線路徑

13 曲線路徑 explicit formula: 簡單曲線如二次錐線 parametric formula: 複雜曲線或 Bezier curves 足夠密的多線段

14 範例一:顯示棒球圖片 public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Texture2D baseball; Vector2 baseball_position;

15 protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here baseball = Content.Load ("images/baseball"); baseball_position = new Vector2(0, (GraphicsDevice.Viewport.Height - baseball.Height) / 2); }

16 protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); spriteBatch.Draw(baseball, baseball_position, Color.White); spriteBatch.End(); base.Draw(gameTime); }

17

18 範例二:讓棒球水平飛 public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Texture2D baseball; Vector2 baseball_position, baseball_velocity;

19 protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here baseball = Content.Load ("images/baseball"); baseball_position = new Vector2(0, (GraphicsDevice.Viewport.Height - baseball.Height) / 2); baseball_velocity = new Vector2(5,0); }

20 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 // update baseball position baseball_position += baseball_velocity; base.Update(gameTime); }

21

22 範例三:不讓棒球飛出界外 W w W - w

23 public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Texture2D baseball; Vector2 baseball_position, baseball_velocity; int maxRight;

24 protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here baseball = Content.Load ("images/baseball"); baseball_position = new Vector2(0, (GraphicsDevice.Viewport.Height - baseball.Height) / 2); baseball_velocity = new Vector2(5,0); maxRight = GraphicsDevice.Viewport.Width – baseball.Width; }

25 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 // update baseball position baseball_position += baseball_velocity; if (baseball_position.X > maxRight) baseball_position.X = maxRight; base.Update(gameTime); }

26 範例四:讓棒球反彈 (a, 0) (-a, 0) (a, 0) (-a, 0)

27 protected override void Update(GameTime gameTime) {... // TODO: Add your update logic here // update baseball position baseball_position += baseball_velocity; if (baseball_position.X > maxRight) { baseball_position.X = maxRight; baseball_velocity = -baseball_velocity; } else if (baseball_position.X < 0) { baseball_position.X = 0; baseball_velocity = -baseball_velocity; } base.Update(gameTime); }

28 Game Components 模組化元件 GameComponent DrawableGameComponents Game.Components GameServiceContainer Game.Services

29 使用 Game Component 的步驟 1. 利用 IDE 的專案新增項目功能加入 Game Component 骨架碼。 2. 如果元件不牽涉繪圖,則建立一個繼承 GameComponent 的類別, 並依需求改寫其中的 Initialize 與 Update 的方法。 3. 如果元件牽涉繪圖,則建立一個繼承 DrawableGameComponent 的 類別,並依需求改寫其中的 Initialize 、 Update 、與 Draw 的方法。 4. 在 Game1 的建構函式中,用 Components.Add 方法把上述類別的 元件加入 Game1 物件的元件集中。

30 加入 Game Component 骨架碼 步驟一:在專案名稱上按滑鼠右鍵,然後如下圖所示,加入新增項目:

31 步驟二:選擇如下圖所示的項目。 123

32 Game Services Game services are a mechanism for maintaining loose coupling between objects that need to interact with each other. Game Services Provider Comsumer AddService GetService public void AddService ( Type type, Object provider ) public Object GetService (Type type)

33 範例五:利用 game components 來加入動畫元件 (DrawableComponent.rar) // File: BallComponent.cs public class BallComponent : Microsoft.Xna.Framework.DrawableGameComponent { protected Texture2D sprite;// sprite 的圖片 protected SpriteBatch spriteBatch;// 用於繪製 sprite protected Vector2 position;// sprite 的位置 protected Vector2 velocity;// sprite 的速率 protected string contentPath;// 圖片的路徑

34 public BallComponent(Game game, string path) : base(game) { // TODO: Construct any child components here contentPath = path; } protected override void LoadContent() { spriteBatch = Game.Services.GetService(typeof(SpriteBatch)); sprite = Game.Content.Load (contentPath); base.LoadContent(); } File: BallComponent.cs

35 public override void Draw (GameTime gameTime) { spriteBatch.Begin(); spriteBatch.Draw(sprite, position, Color.White); spriteBatch.End(); base.Draw(gameTime); } File: BallComponent.cs

36 public class BaseBall : BallComponent { int maxRight; public BaseBall(Game game, string path) : base(game, path) { // TODO: Construct any child components here } File: BaseBall.cs

37 protected override void LoadContent() { base.LoadContent(); position = new Vector2(0, (GraphicsDevice.Viewport.Height - sprite.Height)/2); velocity = new Vector2(3, 0); maxRight = GraphicsDevice.Viewport.Width - sprite.Width; } File: BaseBall.cs

38 public override void Update(GameTime gameTime) { // TODO: Add your update code here position += velocity; if (position.X > maxRight) { position.X = maxRight; velocity.X = -velocity.X; } else if (position.X < 0) { position.X = 0; velocity.X = -velocity.X; } base.Update(gameTime); } File: BaseBall.cs

39 public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; Components.Add(new BaseBall(this, "images/baseball")); Components.Add(new BasketBall(this, "images/basketball")); } File: Game1.cs 建立 Baseball 物件與 BasketBall 物件 並加入遊戲物件成為其元件

40 protected override void Initialize() { // TODO: Add your initialization logic here base.Initialize(); } File: Game1.cs 執行遊戲元件集( Components )中各元件 的 Initialize() 方法(其中也執行該元 件的 LoadContent() 方法)。

41 protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); Services.AddService(typeof(SpriteBatch), spriteBatch); …… } File: Game1.cs 把 spriteBatch 加入 Services

42 protected override void Update(GameTime gameTime) {... // TODO: Add your update logic here base.Update(gameTime); } File: Game1.cs 執行遊戲元件集( Components )中各元件 的 Update() 方法。

43 protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here base.Draw(gameTime); } File: Game1.cs 執行遊戲元件集( Components )中各個可 繪元件的 Draw() 方法。

44 Sprite Animation Sprite Sheet Play List Frame Rate & Animation Speed

45 Sprite Sheet 為了減少圖片的數量,我 們通常把用來組合動作的 sprites 擺在一張圖片中, 稱之為 sprite sheet 。譬 如,右圖是一個轉動三環 動畫套圖的組合。

46 Sprite 指定法 – 2D 若把 sprite sheet 中的 sprite 安排如右圖所示 的 2D array 結構。 第 (i, j) 的 sprite 所佔據的 矩形區域的左上角座標 為 (i  w, j  h) (0,0)(1,0)(2,0)(3,0)(4,0)0 (0,1)(1,1)(2,1)(3,1)(4,1)1 (0,2)(1,2)(2,2)(3,2)(4,2)2 (0,3)(1,3)(2,3)(3,3)(4,3)3 (0,4)(1,4)(2,4)(3,4)(4,4)4 (0,5)(1,5)(2,5)(3,5)(4,5)5 01234 h w

47 Sprite 指定法 – 1D 若把 sprite sheet 中的 sprite 安排如右圖所示的 2D array 結構。 假定 sprite sheet 含有 m  n (行  列) 個 sprites ,則第 k 個 sprite 所佔據的矩形區域的 左上角座標為 (k % m  w, k / m  h) 01234 h w 56789 1011121314 1516171819 2021222324 2526272829 整數除法

48 Play List Sprite sheet 通常含多個動作組合(如下圖所示)。 Play list 記錄某一動作的所需的 sprite 及其順序。 譬如:出右拳的動作 序列為 0 , 10 , 12, 11, 12, 10 0 10 20 30 40 50 60

49 Frame Rate & Animation Speed Frame Rate: 遊戲迴圈的更新率(預設為 60 fps ) Animation Speed: sprite 動畫的播放速度,由動畫設計師 來決定。

50 範例: Sprite Animation (AnimatedSprites.rar) public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; // Texture stuff Texture2D texture; Point frameSize = new Point(75, 75); // (width, height) Point currentFrame = new Point(0, 0); // (i, j) Point sheetSize = new Point(6, 8); // (col, row) // Framerate stuff int timeSinceLastFrame = 0; int millisecondsPerFrame = 50;

51 protected override void Update(GameTime gameTime) {... timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds; if (timeSinceLastFrame > millisecondsPerFrame) { timeSinceLastFrame -= millisecondsPerFrame; ++currentFrame.X; if (currentFrame.X >= sheetSize.X) { currentFrame.X = 0; ++currentFrame.Y; if (currentFrame.Y >= sheetSize.Y) currentFrame.Y = 0; } base.Update(gameTime); }

52 protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.White); spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend); spriteBatch.Draw(texture, Vector2.Zero, new Rectangle(currentFrame.X * frameSize.X, currentFrame.Y * frameSize.Y, frameSize.X, frameSize.Y), Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0); spriteBatch.End(); base.Draw(gameTime); }


Download ppt "Animation (動畫) 靜宜大學資工系 蔡奇偉 副教授 © 2011. 大綱 Introduction Game Loop Motion Animation Game Components 範例 參考資料."

Similar presentations


Ads by Google