html5-img
1 / 61

2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C#

2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C#. 2D 圖形與字型的呈現. 本章目的. 介紹 XNA 支援的 2D 圖形格式 介紹 2D 圖形的應用範圍 以多個範例來示範在 XNA 架構下 2D 圖形和字型的呈現方式 介紹 2D 圖形碰撞測試的演算法。 . 2D 圖形的應用範圍 . 紋理圖 (Texture) 精靈圖 (Sprite) 小張的背景拼圖 大張的背景圖 . 紋理圖 展開的 UV 貼圖 . 2D 角色精靈圖 . 無接縫 2D 圖形 . 大張捲動的背景圖 . XNA 可輸入的 2D 圖形格式 .

tala
Download Presentation

2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C#

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 2D圖形與字型的呈現

  2. 本章目的 • 介紹XNA支援的 2D圖形格式 • 介紹2D圖形的應用範圍 • 以多個範例來示範在XNA架構下2D圖形和字型的呈現方式 • 介紹2D圖形碰撞測試的演算法。

  3. 2D 圖形的應用範圍 • 紋理圖(Texture) • 精靈圖(Sprite) • 小張的背景拼圖 • 大張的背景圖

  4. 紋理圖展開的UV貼圖

  5. 2D角色精靈圖

  6. 無接縫2D圖形

  7. 大張捲動的背景圖

  8. XNA可輸入的 2D圖形格式 • .BMP取自Bitmap的縮寫,是無壓縮的點陣圖形檔。 • .DDS 是可以包含有 alpha 值的圖形檔案。也可以是有六張貼圖的立體紋理圖 (cube map) • .DIB與BMP相似,所以BMP也被稱為DIB。 • .HDR每一個像素除了有RGB資訊外,還有改點的亮度資訊。 • .JPG全彩及灰階圖形資料標準壓縮檔。採用失真壓縮演算法。 • .PFM一種字型格式。 • .PNGPNG 是包含有 alpha 值的圖形檔案。 • .PPM可移植的像素映射位圖檔。 • .TGA全稱Truevision Targa,包含有 alpha 值的圖形檔案。

  9. MipMap 圖

  10. 一個典型的2D圖形上載與繪出方式 public class Game1 :Microsof.Xna.Framework.Game { // 宣告 一個 Texture2D 參照 Texture2D mySpriteTexture; … protected override void LoadContent() { // 上載一張2D圖形 mySpriteTexture = Content.Load<Texture2D>("png-0001"); … Protected override void Draw(GameTime gameTime) { // 繪出 Texture2D spriteBatch.Begin(); Vector2 pos = new Vector2(100, 100); spriteBatch.Draw(mySpriteTexture, pos, Color.White); spriteBatch.End(); 宣告 上載 (更新) 繪出

  11. 呈現出一個2D圖形 protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); Vector2 pos = new Vector2(0, 0); spriteBatch.Draw( mySpriteTexture, pos, // 位置 Color.White); // 過濾顏色 也就是完全不過濾 spriteBatch.End(); base.Draw(gameTime); }

  12. Draw XNA提供: 七種繪出紋理圖的方法 和三種畫出字串的方法 範例一:上載並呈現一張2D圖形(4-9~4-11) • 載入一張2D圖在content中 • 宣告2D圖之變數於Game1 • Load 2D圖於LoadContent() • 繪圖於Draw()

  13. 縮放或呈現部分 2D 圖形 (範例一及範例二) // 方式 1 :目的地位置 Vector2 pos = new Vector2(0, 0); spriteBatch.Draw(mySpriteTexture, pos, // 位置 Color.White); // 過濾顏色 也就是完全不過濾 // 方式 2 :改變 過濾顏色 pos.X = 150; spriteBatch.Draw(mySpriteTexture, pos, Color.Red); // 只要紅色

  14. 縮放或呈現部分 2D 圖形 // 方式 3 :標示目的地的位置和寬高 Rectanglerec = new Rectangle(300, 10, 43, 64); spriteBatch.Draw(mySpriteTexture, rec, Color.White); // 方式 4 :標示目的地位置寬高和來源矩形的位置寬高 Rectangle rec2 = new Rectangle(400, 10, 340, 210); Rectangle rec_SRC = new Rectangle(40, 20, 380, 230); spriteBatch.Draw(mySpriteTexture, rec2, rec_SRC, Color.White);

  15. 範例三:2D圖形的旋轉 • 宣告一Global variable “Angle”於Game1 • 在Update()中改變Angle的值 • 於Draw()中繪出旋轉後的圖形

  16. 旋轉的 2D 圖形(範例三) Rectangle recDest = new Rectangle(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2, mySpriteTexture.Width, mySpriteTexture.Height); spriteBatch.Draw(mySpriteTexture, // 2D Texture recDest, // 目的區 的 矩形區塊 null, // 來源區 的 矩形區塊 Color.White, // 顏色 濾鏡 MathHelper.ToRadians(Angle), // 旋轉徑度 new Vector2(mySpriteTexture.Width / 2, mySpriteTexture.Height / 2), // 2D Texture旋轉中心點 SpriteEffects.None, // 旋轉效果 0.6f); // 圖層深度 0.0 ~ 1.0 (後)

  17. SpriteSortMode.BackToFront

  18. SpriteSortMode.FrontToBack

  19. 範例四:彈跳得2D圖形 如何實作一個精靈圖類別: 專案 加入類別 輸入檔案名稱,選擇『加入』 加入程式碼

  20. 範例四:彈跳得2D圖形 namespace WindowsGame1 { class ClassSprite { public Texture2D texture; // 2D 紋理圖 public Vector2 position; // 2D 紋理圖 的位置 private Vector2 screenSize; // 視窗寬高 public Vector2 velocity = Vector2.Zero; // 2D 紋理圖 的位移速度 public ClassSprite(Texture2D texture, Vector2 position, Vector2 screenSize) { this.texture = texture; this.position = position; this.screenSize = screenSize;}

  21. 範例四:彈跳得2D圖形 // 移動 public void Move() {// 右緣 碰到 視窗右邊了 if (position.X + texture.Width + velocity.X > screenSize.X) velocity.X = -velocity.X; // 下緣 碰到 視窗底邊了 if (position.Y + texture.Height + velocity.Y > screenSize.Y) velocity.Y = -velocity.Y; // 左緣 碰到 視窗左邊了 if (position.X + velocity.X < 0) velocity.X = -velocity.X; // 上緣 碰到 視窗上邊了 if (position.Y + velocity.Y < 0) velocity.Y = -velocity.Y; position += velocity;}} }

  22. 範例四:彈跳得2D圖形 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 Texture2D texture = Content.Load<Texture2D>("CD");// 上載圖形 // 產生精靈圖物件 mySprite1 = new ClassSprite(texture, new Vector2(0f, 0f), new Vector2(graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height)); mySprite1.velocity = new Vector2(5, 5); // 設位移速度 }

  23. 範例四:彈跳得2D圖形 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 mySprite1.Move(); // 移動精靈圖物件 base.Update(gameTime); }

  24. 範例四:彈跳得2D圖形 protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(SpriteBlendMode.AlphaBlend); spriteBatch.Draw(mySprite1.texture, mySprite1.position, Color.White); spriteBatch.End(); base.Draw(gameTime); }

  25. 範例五:互相碰撞的2D圖形 定義『碰撞』 宣告兩個Sprite物件 設定位置及速度 處理碰撞的情況 繪圖

  26. 兩個矩形是否在水平方向(X軸) 重疊 如果 X2 > X3 而且 X4 > X1

  27. 兩個矩形是否在垂直方向(Y軸) 重疊

  28. 範例五:互相碰撞的2D圖形(新增mthod) public bool Collides(ClassSprite other) { // 檢查是否 碰撞 return (this.position.X + texture.Width > other.position.X && this.position.X < other.position.X + other.texture.Width && this.position.Y + texture.Height > other.position.Y && this.position.Y < other.position.Y + other.texture.Height); }

  29. 範例五:互相碰撞的2D圖形 namespace WindowsGame1 { /// <summary> /// This is the main type for your game /// </summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; ClassSprite mySprite1; // 精靈圖物件參照 ClassSprite mySprite2; // 精靈圖物件參照 ………

  30. 範例五:互相碰撞的2D圖形 protected override void LoadContent() {……… mySprite1 = new ClassSprite(texture, new Vector2(0f, 0f), new Vector2(graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height)); mySprite1.velocity = new Vector2(5, 5); // 設位移速度 mySprite2 = new ClassSprite(texture, new Vector2(300f, 200f), new Vector2(graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height)); mySprite2.velocity = new Vector2(-8, -5); }

  31. 範例五:互相碰撞的2D圖形 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 mySprite1.Move(); // 移動精靈圖物件 mySprite2.Move(); // 移動精靈圖物件 if (mySprite1.Collides(mySprite2)) { Vector2 tempVelocity = mySprite1.velocity; mySprite1.velocity = mySprite2.velocity; mySprite2.velocity = tempVelocity; } base.Update(gameTime); }

  32. 範例五:互相碰撞的2D圖形 protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(SpriteBlendMode.AlphaBlend); spriteBatch.Draw(mySprite1.texture, mySprite1.position, Color.White); spriteBatch.Draw(mySprite2.texture, mySprite2.position, Color.White); spriteBatch.End(); base.Draw(gameTime); }

  33. 使用無接縫圖佈滿視窗客戶區

  34. 範例六:無接縫貼圖 在Game1.cs宣告一個global variable叫BX_Texture 在LoadContent內上載2D圖形 利用視窗與圖形的長度與寬度計算Do Loop 的巡迴次數,並於Draw中繪圖

  35. 範例六:無接縫貼圖 利用視窗與圖形的長度與寬度計算Do Loop 的巡迴次數,並於Draw中繪圖 for (int i = 0; i <= W / BG_Texture.Width; i++) // i 是 X 方向 要貼幾次 { for (int j = 0; j <= H / BG_Texture.Height; j++) // j 是 Y 方向 要貼幾次 { Vector2 position = new Vector2(i * BG_Texture.Width, j * BG_Texture.Height); // 算出要 貼上的位置 spriteBatch.Draw(BG_Texture, position, Color.White); } }

  36. 使用捲動的無接縫圖佈滿視窗客戶區

  37. 範例七:捲動的無接縫貼圖 在Game1.cs宣告一個global variable叫BX_Texture 在LoadContent內上載2D圖形 加入一個global variable為橫向與縱向的偏移植Offset_X和Offset_Y,並於Update()中修改其值 利用視窗與圖形的長度與寬度加上偏移值後計算Do Loop 的巡迴次數,並於Draw()中繪圖

  38. 範例七:捲動的無接縫貼圖 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 Offset_X += -1; // 向左 Offset_Y += 0; // 不增加 base.Update(gameTime); }

  39. 範例七:捲動的無接縫貼圖 protected override void Draw(GameTime gameTime) { ……. int W = graphics.GraphicsDevice.Viewport.Width; int H = graphics.GraphicsDevice.Viewport.Height; spriteBatch.Begin(); for (int i = -1; i <= W / BG_Texture.Width; i++) // i 是 X 方向 要貼幾次 { for (int j = -1; j <= H / BG_Texture.Height; j++) // j 是 Y 方向 要貼幾次 { Vector2 position = new Vector2( i * BG_Texture.Width + (Offset_X % BG_Texture.Width), j * BG_Texture.Height + (Offset_Y % BG_Texture.Height)); // 算出要 貼上的位置 spriteBatch.Draw(BG_Texture, position, Color.White);}} spriteBatch.End(); base.Draw(gameTime);}

  40. 範例八:2D精靈與捲動背景 public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Texture2D BG_Texture; int Offset_X = 0; // X 軸 偏移値 int Offset_Y = 0; // Y 軸 偏移値 Texture2D mySpriteTexture; Rectangle[,] srcRect = new Rectangle[4, 4]; int pcW = 85; // 主角的寬 int pcH = 153; // 主角的高 int Dir = 2; // 走路的方向 int Seq = 0; // 走路的第幾個動作 bool pcStop = true; // 主角 停止走路 KeyboardState oldState; double StepDuration = 0; …........... }

  41. 範例八:2D精靈與捲動背景 public class Game1 : Microsoft.Xna.Framework.Game {…………. public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; this.IsMouseVisible = true; this.Window.AllowUserResizing = true; this.Window.Title = "行走中的小王子 (↑↓←→空白鍵)"; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { srcRect[i, j] = new Rectangle(j * pcW, i * pcH, pcW, pcH); } }

  42. 範例八:2D精靈與捲動背景 protected override void Update(GameTime gameTime) {………… // TODO: Add your update logic here KeyboardState newState; // 宣告一個 KeyboardState 結構的變數 newState = Keyboard.GetState(); //得到目前鍵盤全部按鍵的狀況 if (newState.IsKeyDown(Keys.Escape)) this.Exit(); //判斷Esc鍵是否已經被按下 else if (newState.IsKeyDown(Keys.Up) && Dir != 1) { Dir = 1; Seq = 0; pcStop = false;} else if (newState.IsKeyDown(Keys.Down) && Dir != 0) { Dir = 0; Seq = 0; pcStop = false;} else if (newState.IsKeyDown(Keys.Right) && Dir != 2) { Dir = 2; Seq = 0; pcStop = false;} else if (newState.IsKeyDown(Keys.Left) && Dir != 3) { Dir = 3; Seq = 0; pcStop = false;} else if (newState.IsKeyDown(Keys.Space) && oldState.IsKeyUp(Keys.Space)) { pcStop = !pcStop;} else if (!pcStop) { StepDuration += gameTime.ElapsedGameTime.TotalMilliseconds; if (StepDuration > 300) { StepDuration = 0; Seq++; // 下一張 Seq = Seq % 4; // 每一方向只有四張 } } oldState = newState; if (pcStop) { } else if (Dir == 1) // 向下 Offset_Y += 1; else if (Dir == 0) // 向上 Offset_Y -= 1; else if (Dir == 2) // 向左 Offset_X -= 1; else if (Dir == 3) // 向右 Offset_X += 1; base.Update(gameTime); }

  43. 範例八:2D精靈與捲動背景 protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here int W = graphics.GraphicsDevice.Viewport.Width; int H = graphics.GraphicsDevice.Viewport.Height; spriteBatch.Begin(); for (int i = -1; i <= W / BG_Texture.Width+1; i++) // i 是 X 方向 要貼幾次 { for (int j = -1; j <= H / BG_Texture.Height+1; j++) // j 是 Y 方向 要貼幾次 { Vector2 position = new Vector2( i * BG_Texture.Width + (Offset_X % BG_Texture.Width), j * BG_Texture.Height + (Offset_Y % BG_Texture.Height)); // 算出要 貼上的位置 spriteBatch.Draw(BG_Texture, position, Color.White);}} Rectangle DesRect = new Rectangle( this.Window.ClientBounds.Width / 2 - pcW / 2, this.Window.ClientBounds.Height / 2 - pcH / 2, pcW, pcH); spriteBatch.Draw(mySpriteTexture, DesRect, srcRect[Dir, Seq], Color.White); spriteBatch.End(); base.Draw(gameTime); }}}

  44. 有16個小圖的角色圖

  45. 範例九: 2D 字型 新增XNA遊戲方案 Contnet(^-R); 加入; 新增項目; 選用Sprite Font範本,並將名稱改為Courier New.spritefont; 加入 系統產生新的文字檔Courier New.spritefont在Content下

  46. 加入字型項

  47. Courier New.spritefont 字型項目

  48. 範例九: 2D 字型 說明page 4-35XML格式檔案 宣告global variable(Font1)在Game1 Load Font 於LoadContent() 設定字串的內容及要寫的位置 使用spriteBatch.DrawString在draw()來顯示字串。 說明三種spriteBatch.DrawString的格式(4-37~4-39)

  49. SpriteBatch .DrawString() • 第一種格式:(簡易型) • SpriteBatch.DrawString (SpriteFont, String, Vector2, Color); • 使用範例: • spriteBatch.DrawString(Font1, // 字型 • message, // 字串 • FontPos, // 位置 • Color.Black // 字的顏色 • );

  50. SpriteBatch .DrawString() • SpriteBatch.DrawString (SpriteFont, String, Vector2, Color, Single, Vector2, Single, SpriteEffects, Single); • 使用範例: • spriteBatch.DrawString(Font1, // 字型 • message, // 字串 • FontPos, // 位置 • Color.Black, // 字的顏色 • 0, // 旋轉角度 • FontOrigin,// 字串中心點 • 3.0f, // 縮放倍數 • SpriteEffects.None,// 旋轉效果 • 0); // 圖層深度 0.0 ~ 1.0 (後)

More Related