矩形碰撞是設計2D遊戲一開始需要知道的最基礎的碰撞偵測的方法,利用bounding box的方法將圖片的大小包住,甚至可以更仔細的指出圖片中圖案的4面大小,但是通常會以圖片的大小為主,因為使用上較方便,將兩個要碰撞的圖片去檢查他們是否發生交集,是的話就表示碰到,不是的話則表示沒有碰到,當然這樣的碰撞相對於像點偵測的發方會較不準確,之前有提到過像點偵測的做法,往後也會在用程式來解說實際地設計方法。
此範例是參考了XNA開發者俱樂部裡的Collision Series 1: 2D Rectangle Collision這個範例,將裡面的程式碼再加以簡化,只是比較單純的移動人物去碰障礙物看會不會發生碰撞而已,碰到的話畫面會變成紅色,沒有的話則是淡藍色。
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 boundbox15
{16
public class Game1 : Microsoft.Xna.Framework.Game17
{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(“Block”);44
person = Content.Load(“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
else77
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
else87
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
- 本文固定链接: http://www.wy182000.com/2009/02/16/xna-矩形碰撞rectangle-collision程式範例/
- 转载请注明: wy182000 于 Studio 发表
