矩形碰撞是設計2D遊戲一開始需要知道的最基礎的碰撞偵測的方法,利用bounding box的方法將圖片的大小包住,甚至可以更仔細的指出圖片中圖案的4面大小,但是通常會以圖片的大小為主,因為使用上較方便,將兩個要碰撞的圖片去檢查他們是否發生交集,是的話就表示碰到,不是的話則表示沒有碰到,當然這樣的碰撞相對於像點偵測的發方會較不準確,之前有提到過像點偵測的做法,往後也會在用程式來解說實際地設計方法。
此範例是參考了XNA開發者俱樂部裡的Collision Series 1: 2D Rectangle Collision這個範例,將裡面的程式碼再加以簡化,只是比較單純的移動人物去碰障礙物看會不會發生碰撞而已,碰到的話畫面會變成紅色,沒有的話則是淡藍色。
01 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedBlockStart.gif)
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 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedBlockStart.gif)
...{
16
public class Game1 : Microsoft.Xna.Framework.Game
17 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
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 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
27 public Game1()
28 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
29
graphics = new GraphicsDeviceManager(this);
30
Content.RootDirectory = "Content";
31
}
32 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
33 protected override void Initialize()
34 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
35
base.Initialize();
36
blockpos = new Vector2(0, 0);
37
personpos = new Vector2(50,0);
38
}
39 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
40 protected override void LoadContent()
41 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
42
spriteBatch = new SpriteBatch(GraphicsDevice);
43
block = Content.Load<Texture2D>("Block");
44
person = Content.Load<Texture2D>("Person");
45 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
46
}
47 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
48 protected override void UnloadContent()
49 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
50 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
51
}
52 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
53 protected override void Update(GameTime gameTime)
54 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
55
KeyboardState keyboard = Keyboard.GetState();
56
if (keyboard.IsKeyDown(Keys.Up))
57 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
58
personpos = new Vector2(personpos.X, personpos.Y - movespeed);
59
}
60
if (keyboard.IsKeyDown(Keys.Down))
61 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
62
personpos = new Vector2(personpos.X, personpos.Y + movespeed);
63
}
64
if (keyboard.IsKeyDown(Keys.Left))
65 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
66
personpos = new Vector2(personpos.X - movespeed,personpos.Y);
67
}
68
if (keyboard.IsKeyDown(Keys.Right))
69 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
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 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
79 base.Update(gameTime);
80
}
81 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
82 protected override void Draw(GameTime gameTime)
83 ![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/ExpandedSubBlockStart.gif)
...{
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位置、有多寬、有多高四個參數。
![](http://www.dotblogs.com.tw/Providers/BlogEntryEditor/FCKeditor/editor/dialog/InsertCode/codeimages/InBlock.gif)
Rectangle(
int X,
int Y,
int Width,
int Height);
74~77則是判斷兩圖片的框框是否有碰撞到,Rectangle型態提供了Intersects這個成員函數,裡面只需要輸入你要跟哪個Rectangle型態的變數看是否有交集的發生即可做判斷。
84~87利用一開始宣告的布林型態的變數去判斷是否有碰撞到,有的話畫面則變成紅色,沒有的話則是藍色。
![](https://dotblogsfile.blob.core.windows.net/user/sonic10690/0812/2008122212218873.JPG)
因為是使用圖片矩形來看是否有交集,故這樣算碰撞到,雖然人並未碰到障礙物
![](https://dotblogsfile.blob.core.windows.net/user/sonic10690/0812/2008122212229559.JPG)
必須要在障礙物矩形外才會不算碰撞到
88~91將兩張圖片實際的畫上去螢幕上面,Draw函數必須在Begin和End成員函數之間。
最後附上此範例的專案檔:boundbox.rar