1 / 54

Game State และ Game Component

Game State และ Game Component. Suphot Sawattiwong tohpus@hotmail.com. GameComponent ใน XNA.

lieu
Download Presentation

Game State และ Game Component

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. Game State และ Game Component SuphotSawattiwongtohpus@hotmail.com

  2. GameComponentใน XNA • ใน XNA มีการสร้าง Component เพื่อเรียกใช้ในเกม ใน Class Game Component โดยใน Class ดังกล่าวมีโครงสร้างในการแยก logic ในการใช้งานออกจากตัว Class Game หลักได้ และสามารถเพิ่ม class GameComponentใส่ไว้ใน project อื่นๆ ได้ด้วยเช่นกัน • แต่ GameComponent มีแค่ Method Update เท่านั้น หากต้องการให้มีการควบคุมการ Draw ด้วยให้ใช้ DrawableGameComponent

  3. GameComponentใน XNA • ใน XNA มีการสร้าง Component เพื่อเรียกใช้ในเกม ใน Class Game Component โดยใน Class ดังกล่าวมีโครงสร้างในการแยก logic ในการใช้งานออกจากตัว Class Game หลักได้ และสามารถเพิ่ม class GameComponentใส่ไว้ใน project อื่นๆ ได้ด้วยเช่นกัน • แต่ GameComponent มีแค่ Method Update เท่านั้น

  4. การใช้งาน Game Component • Game Component เป็น Class พิเศษของ XNA ที่ทำงานโดยต้องทำการ Add เข้า Component Collection ซึ่งทำได้ดังนี้ • ประกาศตัวแปร GameComponent • ทำการประกาศ Instance ใน Method Initialize • ทำการ Add เข้า Component Collection ใน Method Initialize GameComponent1gameComp; gameComp = newGameComponent1(this); Components.Add(gameComp);

  5. การทำงานของ Game Component • ดูใน Project Ex10_GameComponentGameLoop1

  6. การทำงานของ Game Component Main Before Game1 game = new Game1() ===================Game1 Constructor Before game.Run(); ===================Initialize ===================Before new GameComponent1(this) -------------------------------------------GameComponent1 Constructor ===================After new GameComponent1(this) ===================Before Components.Add(gameComp) ===================After Components.Add(gameComp) ===================Initialize Before Base.Initialize -------------------------------------------GameComponent1 Initialize() Before base.Initialize() -------------------------------------------GameComponent1 Initialize() After base.Initialize() ===================LoadContent ===================Initialize AferBase.Initialize ===================Update Before Base.Update -------------------------------------------GameComponent1 Update() Before base.Update() -------------------------------------------GameComponent1 Update() After base.Update() ===================Update After Base.Update ===================Draw Before Base.Draw ===================Draw After Base.Draw

  7. การทำงานของ Game Component ===================Update Before Base.Update -------------------------------------------GameComponent1 Update() Before base.Update() -------------------------------------------GameComponent1 Update() After base.Update() ===================Update After Base.Update ===================Draw Before Base.Draw ===================Draw After Base.Draw After game.Run(); ===================UnloadContent

  8. การทำงานของ Game Component 2 อัน Main Before Game1 game = new Game1() ===================Game1 Constructor Before game.Run(); ===================Initialize ===================Before new GameComponent1(this) -------------------------------------------GameComponent1 Constructor ===================After new GameComponent1(this) ===================Before Components.Add(gameComp) ===================After Components.Add(gameComp) ===================Before new GameComponent2(this) ______________________GameComponent2 Constructor ===================After new GameComponent2(this) ===================Before Components.Add(gameComp2) ===================After Components.Add(gameComp2) ดูใน Ex11_GameComponentGameLoop2

  9. การทำงานของ Game Component 2 อัน ===================Initialize Before Base.Initialize -------------------------------------------GameComponent1 Initialize() Before base.Initialize() -------------------------------------------GameComponent1 Initialize() After base.Initialize() ______________________GameComponent2 Initialize() Before base.Initialize() ______________________GameComponent2 Initialize() After base.Initialize() ===================LoadContent ===================Initialize AferBase.Initialize ===================Update Before Base.Update -------------------------------------------GameComponent1 Update() Before base.Update() -------------------------------------------GameComponent1 Update() After base.Update() ______________________GameComponent2 Update() Before base.Update() ______________________GameComponent2 Update() After base.Update() ===================Update After Base.Update

  10. การทำงานของ Game Component 2 อัน ===================Update Before Base.Update -------------------------------------------GameComponent1 Update() Before base.Update() -------------------------------------------GameComponent1 Update() After base.Update() ______________________GameComponent2 Update() Before base.Update() ______________________GameComponent2 Update() After base.Update() ===================Update After Base.Update ===================Draw Before Base.Draw ===================Draw After Base.Draw ===================Update Before Base.Update -------------------------------------------GameComponent1 Update() Before base.Update() -------------------------------------------GameComponent1 Update() After base.Update() ______________________GameComponent2 Update() Before base.Update() ______________________GameComponent2 Update() After base.Update() ===================Update After Base.Update

  11. การทำงานของ Game Component 2 อัน ===================Update Before Base.Update -------------------------------------------GameComponent1 Update() Before base.Update() -------------------------------------------GameComponent1 Update() After base.Update() ______________________GameComponent2 Update() Before base.Update() ______________________GameComponent2 Update() After base.Update() ===================Update After Base.Update ===================Draw Before Base.Draw ===================Draw After Base.Draw After game.Run(); ===================UnloadContent

  12. คำสั่งที่ใช้ในการลบ Game Component • หากมี Game Component อันไหน ที่ไม่ได้ใช้ หากต้องการทำการลบ ให้ใช้คำสั่ง • เช่น Components.Remove(<ชื่อ Component>); Components.Remove(gameComp2);

  13. DrawableGameComponent • GameComponentมีแต่ Method Update ดังนั้น • หากต้องการให้มีการควบคุมการ Draw ด้วยทางทีมพัฒนาDrawableGameComponent

  14. DrawableGameComponent • จากก่อนหน้านี้ ได้มีการใช้วิธีคำนวณ fps ตอนนี้มาทำ fps DrawableGameComponentขึ้นมา • เริ่มแรกสร้าง Project ที่ชื่อ Ex12_FPSDrawable • กด Add New Item โดยการ click ขวา ใน Solution Explorer • เลือก GameComponentแล้วตั้งชื่อว่า FPS

  15. ตัวอย่างการเปลี่ยน GameComponentเป็น DrawableGameComponent จาก public class FPS :Microsoft.Xna.Framework.GameComponent เป็น public class FPS :Microsoft.Xna.Framework.DrawableGameComponent ให้ดูใน Project ที่ชื่อว่า FPSDrawable

  16. ตัวอย่างการ add GameComponentลงใน Game1.cs • ประกาศตัวแปร ที่เป็นชื่อของ GameComponent นั้น เช่นในที่นี้ private FPS fps; เพิ่ม code ในส่วนของ Initialize หรือ Method ที่เหมาะสมแล้วแต่กรณีให้มีการเรียก instance แล้วทำการ add เข้าไป เช่น fps = new FPS(this, true, true,this.TargetElapsedTime); Components.Add(fps);

  17. การเพิ่ม Library เข้า Project • ให้ click ขวา ตามรูป • แล้วเลือก add ไปที่ Existing project ดังภาพ • เลือก Folder Project Library ที่ต้องการแล้วกด ok

  18. การเพิ่ม Library เข้า Project • ให้ click ขวา ตามรูปแล้วเลือก add Reference…

  19. การเพิ่ม Library เข้า Project • เลือก Library ที่ต้องการ ตามรูป แล้วกด ok

  20. การเพิ่ม Library เข้า Project • จากนั้นให้ทำการพิมพ์ข้อความเพื่อขอใช้ Library โดยการพิมพ์ using ตามด้วยชื่อ NameSpaceเช่น using PhotXNALibrary; • จากนั้นสามารถใช้งานได้ตามปกติต่อไป ลองดูตามตัวอย่างต่อไปในเรื่องของ SpriteAnimation

  21. Parallax Scrolling SuphotSawattiwong tohpus@hotmail.com

  22. Parallax Scrolling • การทำ Parallax Background คือการวาด Background ต่อเนื่องกันไป ให้ดูเหมือนกับว่า มี Background ที่ยาวมากแบบไร้ชอบเขต โดยหลักการจะมีการDraw Background 2 รอบเพื่อทำให้ต่อเนื่องกันไป

  23. วิธีการใช้งาน Parallax Scrolling • ก่อนอื่นให้ทำการ ประกาศตัวแปรดังต่อไปนี้ ScrollingBackgroundตัวแปร BG; เช่นScrollingBackgroundscBg; • ดูใน Ex13_ParallaxBackground • ทำการประกาศ Constructor ดังต่อไปนี้ scBg = newScrollingBackground(this); • ทำการ Add Component ดังต่อไปนี้ Components.Add(scBg);

  24. การ LoadBG • ตัวแปร ParallaxBG.Load(ชื่อไฟล์, ความกว้าง, ความยาว, ความเร็ว, FPS); โดย Load ที่ LoadContent • เช่น scBg.Load("SlideBG_01_1", graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight, 1, 45);

  25. การวาด Parallax Background • การวาด BG ทำได้ใน Method Draw ดังนี้ ตัวแปร.Draw(เวลาในเกม หรือGameTime, ตัวแปร SpriteBatch); เช่น scBg.Draw(gameTime, spriteBatch);

  26. Game State • เกมมีการทำงานหลายส่วน และหลายหน้าจอ อย่างเช่นดังตัวอย่าง • การจัดการหน้าจอ เหล่านี้จำเป็นต้องแยก state ออกจากกันเพื่อให้สะดวกในการเขียน และ debug

  27. Game State • วิธีการแบ่งGameState มีหลายวิธี • การทำGameStateแบบที่ง่ายที่สุดคือการใช้ if else หรือ switch case ในการแยก state โดยจะทำทั้งในส่วน Method Draw และ Update • ทดลองทำGameStateแบบง่ายๆ โดยเปิด Ex14_GameStateAndMenu

  28. การทำGameState • ก่อนอื่น สร้าง enumGameStateใน game1.cs เหนือ Class Game1 ดังนี้ enumGameState { MENU=0, PLAY, GAMEOVER, OPTION }

  29. การทำ GameState • ประกาศตัวแปร ดังต่อไปนี้ ใน Class Game1 • ใน Method Initialize() ให้ทำการกำหนดดังต่อไปนี้ เพื่อกำหนดให้เกมเริ่มต้นที่หน้า Menu GameStatecurrentGameState; currentGameState = GameState.MENU;

  30. การทำGameState • ในส่วน Method Update ให้เพิ่มดังต่อไปนี้ ในส่วนนี้บอกว่าหาก currentGameStateเป็น Menu ก็จะเข้าไปทำการ updateในส่วนUpdateMenuเป็นต้น switch (currentGameState) { caseGameState.MENU: UpdateMenu(gameTime); break; caseGameState.PLAY: UpdatePlay(gameTime); break; }

  31. การทำGameState • สร้าง Method UpdateMenuและ UpdatePlayดังนี้ privatevoidUpdateMenu(GameTimegameTime) { // TODO: เพิ่มส่วนการ Update หน้า Menu } privatevoidUpdatePlay(GameTimegameTime) { // TODO: เพิ่มส่วนการ Update หน้า Play }

  32. การทำGameState • เช่นกันให้ทำแบบเดียวกันกับ Draw Method switch (currentGameState) { caseGameState.MENU: DrawMenu(gameTime); break; caseGameState.PLAY: DrawPlay(gameTime); break; }

  33. การทำGameState • สร้าง Method DrawMenuและ DrawPlayดังนี้ privatevoidDrawMenu(GameTimegameTime) { // TODO: เพิ่มส่วนการ Draw หน้า Menu } privatevoidDrawPlay(GameTimegameTime) { // TODO: เพิ่มส่วนการ Draw หน้า Play }

  34. Game State • จากวิธีข้างต้น เห็นได้ชัดว่าค่อนข้างยุ่งยากและทำให้ Code ค่อนข้างซับซ้อน และในทุก Loop Update กับ Draw ต้องเช็คค่าcurrentState เพื่อเลือกทำ Method ที่ถูกต้อง มันทำให้เสียเวลา • วิธีการทำGameStateที่น่าสนใจที่ควรลองไปศึกษาและทำความเข้าใจ หากมีพื้นฐาน Programming ที่ดี http://creators.xna.com/en-US/samples/gamestatemanagement

  35. Lab7:เกมจับคู่ Card ต่างๆ ต่อไปนี้ • Card ในที่นี้ ผมให้ใช้ Card จำนวนทั้งหมด 10 ใบ โดยจะเหมือนกัน 5 คู่ • Random ตำแหน่งของ Card แต่ละใบ โดยเริ่มแรกให้คว่ำไพ่ไว้ก่อน • ให้ใช้ Mouse เลือกจับคู่ Card โดยหากจับได้การ์ดที่ไม่ตรงกัน ให้จัดการคว่ำหน้า Card เหมือนเดิม และทำการลบคะแนนไป 100 หากจับคู่ได้ ไม่ต้องวาดการ์ดคู่นั้นอีก และทำการบวกคะแนนให้ 200

  36. Matching Game

  37. Matching Game • สถานะของ Card ควรจะมีดังต่อไปนี้ • None กรณี ไม่วาด Card • Close กรณีคว่ำ Card • Open กรณีเปิด Card enumCardStatus { NONE, CLOSE, OPEN }

  38. แนวคิดการทำเกมไพ่ SuphotSawattiwong

  39. จากโจทย์การทำเกมไพ่จับคู่จากโจทย์การทำเกมไพ่จับคู่ • สิ่งที่เรารู้แน่ๆ ว่าต้องทำคือ • ต้องวาดไพ่ 10 ใบ บนหน้าจอ • ไพ่ มี 5 แบบ • แบบละ 2 ใบ ถ้าเกินจะจับคู่ไม่ได้

  40. การวาดภาพไพ่ • เนื่องจากเกมนี้เป็นเกมไพ่ ควรที่จะเริ่มจากการวาดไพ่ก่อนสิ่งที่จำเป็นกับการวาดไพ่มีอะไรบ้าง • ตำแหน่งของไพ่ทั้ง 10 ใบ เมื่อลองได้แค่นี้ ให้ทดลองประกาศ Class Card ออกมาดังนี้ class Card { public Vector2 pos; public Card(Vector2 pos) { this.pos = pos; } }

  41. การวาดภาพไพ่ • เมื่อได้ Class แล้วกลับมาที่ Game1.cs เพื่อประกาศการใช้ Array ดังนี้ • ทำการประกาศตัวแปร Texture2D สำหรับการทำหลังไพ่ดังนี้ • จัดการLoad ภาพในLoadContentดังนี้ Card [] card=new Card[10]; Texture2D backCardTexture; backCardTexture = Content.Load<Texture2D>(@"backcover");

  42. การวาดไพ่ • การวาดภาพไพ่ที่เป็น array ทำได้โดยดังนี้ • กำหนดตำแหน่งให้ Card แต่ละใบก่อน • ทำการวาด Draw Method

  43. กำหนดตำแหน่งให้ Card แต่ละใบก่อน • เนื่องจาก Card ที่กำหนดขึ้นเป็นเพียงแค่จองสมาชิก Array เท่านั้น มันไม่มีค่า หรือเป็น null อยู่นั่นเองจำเป็นต้องประกาศ instance เพื่อให้มีค่าในLoadContentดังต่อไปนี้ card[0] = new Card(new Vector2(130, 30)); card[1] = new Card(new Vector2(260, 30)); card[2] = new Card(new Vector2(390, 30)); card[3] = new Card(new Vector2(520, 30)); card[4] = new Card(new Vector2(650, 30)); card[5] = new Card(new Vector2(130, 230)); card[6] = new Card(new Vector2(260, 230)); card[7] = new Card(new Vector2(390, 230)); card[8] = new Card(new Vector2(520, 230)); card[9] = new Card(new Vector2(650, 230));

  44. ทำการวาด Draw Method • ให้ทำการวาดภาพที่ Draw Method ดังนี้ spriteBatch.Begin(); for(inti=0;i<10;i++) { spriteBatch.Draw(backCardTexture, card[i].pos, Color.White); } spriteBatch.End();

  45. จะได้ดังภาพ

  46. ชนิดของไพ่ • ในโจทย์เรามีไพ่ทั้งหมด 5 แบบ ซึ่งต้อง สุ่มเข้ามาในไพ่ 10 ใบ โดยให้ซ้ำกันแค่อย่างละ 1 คู่ • ก่อนอื่นให้ทำการกำหนดชนิดไพ่ก่อนประกาศ Class Cardดังนี้ public enumCardType { TYPE1 = 0, TYPE2, TYPE3, TYPE4, TYPE5 };

  47. ชนิดของไพ่ • แล้วให้ทำการเพิ่มและทับบรรทัดต่อไปนี้ในส่วน Constructor public Vector2 pos; public CardTypecardType; public Card(Vector2 pos, CardTypecardType) { this.pos = pos; this.cardType = cardType; }

  48. ทำการ Load หน้าไพ่ทั้ง 5แบบในLoadContent • ก่อนอื่นให้ทำการประกาศตัวแปรใน Class Game1 เป็น Texture2D[5] ดังนี้ • ทำการLoadContentดังนี้ Texture2D[] cardTexture=new Texture2D[5]; for (int i = 0; i < 5; i++) { cardTexture[i] = Content.Load<Texture2D>(@"card0" + (i + 1)); }

  49. ทำการแก้ไขการกำหนดค่าในLoadContentดังนี้ทำการแก้ไขการกำหนดค่าในLoadContentดังนี้ • เริ่มแก้ไขการประกาศ Instance ก่อนหน้า card[0] = new Card(new Vector2(130, 30), CardType.TYPE1); card[1] = new Card(new Vector2(260, 30), CardType.TYPE1); card[2] = new Card(new Vector2(390, 30), CardType.TYPE2); card[3] = new Card(new Vector2(520, 30), CardType.TYPE2); card[4] = new Card(new Vector2(650, 30), CardType.TYPE3); card[5] = new Card(new Vector2(130, 230), CardType.TYPE3); card[6] =new Card(new Vector2(260, 230), CardType.TYPE4); card[7] = new Card(new Vector2(390, 230), CardType.TYPE4); card[8] = new Card(new Vector2(520, 230), CardType.TYPE5); card[9] = new Card(new Vector2(650, 230), CardType.TYPE5);

  50. ปรับเปลี่ยนใน Draw Method • ให้ทำการปรับเปลี่ยนดังนี้ spriteBatch.Begin(); for(inti=0;i<10;i++) { spriteBatch.Draw(cardTexture[(int)card[i].cardType], card[i].pos,Color.White); } spriteBatch.End();

More Related