XNA-矩形碰撞Rectangle Collision(程式範例)

XNA中簡單的矩形碰撞的方法

    矩形碰撞是設計2D遊戲一開始需要知道的最基礎的碰撞偵測的方法,利用bounding box的方法將圖片的大小包住,甚至可以更仔細的指出圖片中圖案的4面大小,但是通常會以圖片的大小為主,因為使用上較方便,將兩個要碰撞的圖片去檢查他們是否發生交集,是的話就表示碰到,不是的話則表示沒有碰到,當然這樣的碰撞相對於像點偵測的發方會較不準確,之前有提到過像點偵測的做法,往後也會在用程式來解說實際地設計方法。

    此範例是參考了XNA開發者俱樂部裡的Collision Series 1: 2D Rectangle Collision這個範例,將裡面的程式碼再加以簡化,只是比較單純的移動人物去碰障礙物看會不會發生碰撞而已,碰到的話畫面會變成紅色,沒有的話則是淡藍色。

01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using Microsoft.Xna.Framework;
05 using Microsoft.Xna.Framework.Audio;
06 using Microsoft.Xna.Framework.Content;
07 using Microsoft.Xna.Framework.GamerServices;
08 using Microsoft.Xna.Framework.Graphics;
09 using Microsoft.Xna.Framework.Input;
10 using Microsoft.Xna.Framework.Media;
11 using Microsoft.Xna.Framework.Net;
12 using Microsoft.Xna.Framework.Storage;

13
14 namespace boundbox
15 {
16     public class Game1 : Microsoft.Xna.Framework.Game
17     {
18         GraphicsDeviceManager graphics;
19         SpriteBatch spriteBatch;
20         Texture2D block;
21         Texture2D person;
22         Vector2 blockpos;
23         Vector2 personpos;
24         int movespeed=3;
25         bool personHit = false;
26
27         public Game1()
28         {
29             graphics = new GraphicsDeviceManager(this);
30             Content.RootDirectory = "Content";
31         }

32
33         protected override void Initialize()
34         {
35             base.Initialize();
36             blockpos = new Vector2(0, 0);
37             personpos = new Vector2(50,0);
38         }

39
40         protected override void LoadContent()
41         {
42             spriteBatch = new SpriteBatch(GraphicsDevice);
43             block = Content.Load<Texture2D>("Block");
44             person = Content.Load<Texture2D>("Person");
45
46         }

47
48         protected override void UnloadContent()
49         {
50
51         }

52
53         protected override void Update(GameTime gameTime)
54         {
55             KeyboardState keyboard = Keyboard.GetState();
56             if (keyboard.IsKeyDown(Keys.Up))
57             {
58                 personpos = new Vector2(personpos.X, personpos.Y - movespeed);
59             }

60             if (keyboard.IsKeyDown(Keys.Down))
61             {
62                 personpos = new Vector2(personpos.X, personpos.Y + movespeed);
63             }

64             if (keyboard.IsKeyDown(Keys.Left))
65             {
66                 personpos = new Vector2(personpos.X - movespeed,personpos.Y);
67             }

68             if (keyboard.IsKeyDown(Keys.Right))
69             {
70                 personpos = new Vector2(personpos.X + movespeed,personpos.Y);
71             }

72             Rectangle personRectangle = new Rectangle((int)personpos.X,(int)personpos.Y,person.Width,person.Height);
73             Rectangle blockRectangle =new Rectangle((int)blockpos.X, (int)blockpos.Y,block.Width, block.Height);
74             if (personRectangle.Intersects(blockRectangle))
75                 personHit = true;
76             else
77                 personHit = false;
78
79             base.Update(gameTime);
80         }

81
82         protected override void Draw(GameTime gameTime)
83         {
84             if (personHit == true)
85                 GraphicsDevice.Clear(Color.Red);
86             else
87                 GraphicsDevice.Clear(Color.CornflowerBlue);
88             spriteBatch.Begin();
89             spriteBatch.Draw(block,blockpos,Color.White);
90             spriteBatch.Draw(person,personpos,Color.White);
91             spriteBatch.End();
92             base.Draw(gameTime);
93         }

94     }

95 }

    程式一開始的20和21行宣告存放圖片的物件,而Texture2D此種型態裡面有Width和Height的成員變數可以方便我們知道該圖片的寬和高各是多少。

    22~23行主要是宣告存放兩張圖片的位置,Vector2此種型態裡面有提供X和Y的成員變數,分別代表X和Y的位置,以方便我們使用。

    24行宣告移動圖片的速度為3。

    25行是宣告一個布林型態的變數去判斷是否有碰撞到。

    36~37指定兩圖片一開始的位置為(0,0)與(50,0)的位置。

    43~44將圖片載入進來,用變數block和person存起來。

    55~71則是運用鍵盤操控person這張圖片,鍵盤的上下左右代表著person圖片上下左右的移動,而每移動的單位為3,就是一開始所宣告movespeed的變數。

    72~73則是宣告兩張圖片的框框大小,運用來看是否有碰撞到,使用到Rectangle這種型態,裡面需要輸入X位置、Y位置、有多寬、有多高四個參數。

Rectangle(int X,int Y,int Width,int Height);

    74~77則是判斷兩圖片的框框是否有碰撞到,Rectangle型態提供了Intersects這個成員函數,裡面只需要輸入你要跟哪個Rectangle型態的變數看是否有交集的發生即可做判斷。

    84~87利用一開始宣告的布林型態的變數去判斷是否有碰撞到,有的話畫面則變成紅色,沒有的話則是藍色。

因為是使用圖片矩形來看是否有交集,故這樣算碰撞到,雖然人並未碰到障礙物

必須要在障礙物矩形外才會不算碰撞到

    88~91將兩張圖片實際的畫上去螢幕上面,Draw函數必須在Begin和End成員函數之間。

最後附上此範例的專案檔:boundbox.rar