[Index page]
[Download source code]
Dream come true XNA (7)-Collision Detection
Author: webabcd
Introduction
XNA: Collision Detection
- Collision Detection Algorithm Using AABB (Axis Aligned Bounding Box)
- Use the Rectangle class to implement the Collision Detection Algorithm
Example
1. AABB algorithm Demo (press the N key on the keyboard to load this Demo)
Component/Collision/AABB. cs
/** AABB-Axis Aligned Bounding Box * the so-called Axis Aligned means that the Box body is parallel to the world Axis, and each side of the Box body (2D) or the surface (3D) is parallel to a coordinate axis (vertical) ** this Demo is used to demonstrate whether two elves have collided with each other through the AABB algorithm */using System; using System. collections. generic; using System. linq; using Microsoft. xna. framework; using Microsoft. xna. framework. audio; using Microsoft. xna. framework. content; using Microsoft. xna. framework. gamerServices; using Microsoft. xna. framework. graphics; Using Microsoft. xna. framework. input; using Microsoft. xna. framework. media; namespace XNA. component. collision {public class AABB: Microsoft. xna. framework. drawableGameComponent {// SpriteBatch _ spriteBatch; // sprite object Texture2D _ sprite; // Vector2 _ systemSpritePosition = new Vector2 (600,300 ); // The speed of the genie (controlled by the system), unit: bytes number/each frame int _ systemSpriteSpeed = 6; // The sprite position (User-controlled) Vector2 _ userSpritePos Ition = Vector2.Zero; // sprite speed (User-controlled), unit: number of workers/int _ userSpriteSpeed = 6 per frame; // whether a collision has occurred bool _ collided = false; public AABB (Game game): base (game) {} public override void Initialize () {base. initialize ();} protected override void LoadContent () {_ spriteBatch = new SpriteBatch (Game. graphicsDevice); _ sprite = Game. content. load <Texture2D> ("Image/Son");} public override void Update (GameTime gameTime) {// If the system-controlled genie is in conflict with the user-controlled genie, stop the animation if (! CheckCollision () {calcSystemSpritePosition (); calcUserSpritePosition ();} else {_ collided = true;} base. update (gameTime) ;}/// <summary> /// check whether the system-controlled genie has collided with the user-controlled genie (through the AABB algorithm) /// </summary> /// <returns> whether the two elves have collided </returns> private bool CheckCollision () {/** the box is parallel to the world axis, at the same time, each side (2D) or surface (3D) of the box body is parallel to a coordinate axis * The AABB box is surrounded by a Max coordinate and a Min coordinate, the algorithm is as follows */Vector2 systemSpriteMin = new Vector2 (_ systemSpritePosition. x, _ systemSpritePosition. y); Vector2 systemSpriteMax = new Vector2 (_ systemSpritePosition. X + _ sprite. width, _ systemSpritePosition. Y + _ sprite. height); Vector2 userSpriteMin = new Vector2 (_ userSpritePosition. x, _ userSpritePosition. y); Vector2 userSpriteMax = new Vector2 (_ userSpritePosition. X + _ sprite. width, _ userSpritePosition. Y + _ sprite. height); if (systemSpriteMin. X <= userSpriteMax. X & systemSpriteMin. Y <= userSpriteMax. Y & systemSpriteMax. x> = userSpriteMin. X & systemSpriteMax. y> = userSpriteMin. y) return true; return false;} // calculate the location of the User-controlled genie private void calcUserSpritePosition () {KeyboardState keyboardState = Keyboard. getState (); if (keyboardState. isKeyDown (Keys. left) & _ userSpritePosition. x> = 0) _ userSpritePosition. x-= _ userSpriteSpeed; if (keyboardState. isKeyDown (Keys. right) & _ userSpritePosition. X <= Game. window. clientBounds. width-_ sprite. width) _ userSpritePosition. X + = _ userSpriteSpeed; if (keyboardState. isKeyDown (Keys. up) & _ userSpritePosition. y> = 0) _ userSpritePosition. y-= _ userSpriteSpeed; if (keyboardState. isKeyDown (Keys. down) & _ userSpritePosition. Y <= Game. window. clientBounds. height-_ sprite. height) _ userSpritePosition. Y + = _ userSpriteSpeed;} // the location of the computing system-controlled genie private void calcSystemSpritePosition () {// The system-controlled genie performs a reciprocating movement in the Y axis direction _ systemSpritePosition. Y + = _ systemSpriteSpeed; if (_ systemSpritePosition. y> Game. window. clientBounds. height-_ sprite. height | _ systemSpritePosition. Y <0) _ systemSpriteSpeed * =-1;} public override void Draw (GameTime gameTime) {if (_ collided) Game. graphicsDevice. clear (Color. indianRed); else Game. graphicsDevice. clear (Color. cornflowerBlue); // draws sprite _ spriteBatch at the specified position. begin (); _ spriteBatch. draw (_ sprite, _ systemSpritePosition, Color. red); // plot the spriteBatch controlled by the system. draw (_ sprite, _ userSpritePosition, Color. white); // draw the user-controlled spriteBatch. end (); base. update (gameTime );}}}
2. Rectangle-based collision detection Demo (press the keyboard O key to load this Demo)
Component/Collision/RectangleCollision. cs
/** This Demo is used to demonstrate the collision detection algorithm through the Rectangle class */using System; using System. collections. generic; using System. linq; using Microsoft. xna. framework; using Microsoft. xna. framework. audio; using Microsoft. xna. framework. content; using Microsoft. xna. framework. gamerServices; using Microsoft. xna. framework. graphics; using Microsoft. xna. framework. input; using Microsoft. xna. framework. media; namespace XNA. component. collision {pu Blic class RectangleCollision: Microsoft. xna. framework. drawableGameComponent {// SpriteBatch _ spriteBatch; // sprite object Texture2D _ sprite; // Vector2 _ systemSpritePosition = new Vector2 (600,300 ); // The speed of the genie (controlled by the system), in the unit of bytes/each frame int _ systemSpriteSpeed = 6; // The sprite position (User-controlled) Vector2 _ userSpritePosition = Vector2.Zero; // The sprite speed (User-controlled). Unit: number of workers/int _ userSpriteSpeed = 6 per frame; // whether a collision bool _ coll has occurred Ided = false; public RectangleCollision (Game game): base (game) {} public override void Initialize () {base. initialize ();} protected override void LoadContent () {_ spriteBatch = new SpriteBatch (Game. graphicsDevice); _ sprite = Game. content. load <Texture2D> ("Image/Son");} public override void Update (GameTime gameTime) {// if the system-controlled genie is in conflict with the user-controlled genie, stop the animation if (! CheckCollision () {calcSystemSpritePosition (); calcUserSpritePosition ();} else {_ collided = true;} base. update (gameTime) ;}/// <summary> /// check whether the system-controlled genie has collided with the user-controlled genie (with the help of the Rectangle class) /// </summary> /// <returns> whether the two elves have collided </returns> private bool CheckCollision () {Rectangle systemSpriteRect = new Rectangle (int) _ systemSpritePosition. x, (int) _ systemSpritePosition. y, _ sprite. width, _ sprite. height); Rectangle userSpriteRect = new Rectangle (int) _ userSpritePosition. x, (int) _ userSpritePosition. y, _ sprite. width, _ sprite. height); if (systemSpriteRect. intersects (userSpriteRect) return true; return false;} // calculate the location of the User-controlled genie private void calcUserSpritePosition () {KeyboardState keyboardState = Keyboard. getState (); if (keyboardState. isKeyDown (Keys. left) & _ userSpritePosition. x> = 0) _ userSpritePosition. x-= _ userSpriteSpeed; if (keyboardState. isKeyDown (Keys. right) & _ userSpritePosition. X <= Game. window. clientBounds. width-_ sprite. width) _ userSpritePosition. X + = _ userSpriteSpeed; if (keyboardState. isKeyDown (Keys. up) & _ userSpritePosition. y> = 0) _ userSpritePosition. y-= _ userSpriteSpeed; if (keyboardState. isKeyDown (Keys. down) & _ userSpritePosition. Y <= Game. window. clientBounds. height-_ sprite. height) _ userSpritePosition. Y + = _ userSpriteSpeed;} // the location of the computing system-controlled genie private void calcSystemSpritePosition () {// The system-controlled genie performs a reciprocating movement in the Y axis direction _ systemSpritePosition. Y + = _ systemSpriteSpeed; if (_ systemSpritePosition. y> Game. window. clientBounds. height-_ sprite. height | _ systemSpritePosition. Y <0) _ systemSpriteSpeed * =-1;} public override void Draw (GameTime gameTime) {if (_ collided) Game. graphicsDevice. clear (Color. indianRed); else Game. graphicsDevice. clear (Color. cornflowerBlue); // draws sprite _ spriteBatch at the specified position. begin (); _ spriteBatch. draw (_ sprite, _ systemSpritePosition, Color. red); // plot the spriteBatch controlled by the system. draw (_ sprite, _ userSpritePosition, Color. white); // draw the user-controlled spriteBatch. end (); base. update (gameTime );}}}
OK
[Download source code]