Thread: 2d Collision using Directx

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    30

    2d Collision using Directx

    Hey everyone,

    I am currently implementing the darkGDK library for creating a basic 2D game.

    USING:
    Microsoft Visual C++ 2008 Express
    DirectX SDK 2009 (August)
    DarkGDK

    I actually can't figure out how to get my game to run without using Debug->Start Debugging because when I successfully make the release build, I only get a black screen....


    ANYHOW, on to the point.

    The collision detection for DarkGDK is not really that great unless you want to use blocks as sprites. I would like to get help on using DirectX (Sprite Collision Masks i think) to create "Pixel Perfect" collisions.

    SCREENSHOTS OF PROGRESS:
    http://i39.tinypic.com/bj7fbo.png
    http://i41.tinypic.com/2up9xr4.png


    I do have full movement of character and working animations

    and yes, the little guy is Link

  2. #2
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    I have a "pixel perfect" detection algo. It is written in allegro but the concepts should be simple to port to a direct x context.

    Code:
    struct BoundingBox
    {
        int top;
        int bottom;
        int left;
        int right;
    };
    Code:
    #include <algorithm>
    #include "Collision.h"
    
    bool CCollisionDetection::DetectBoundingBox(const CSprite &spriteOne, const CSprite &spriteTwo)
    {
    	//
    	//Grab the bounds of the sprites
    	//
    	const BoundingBox &boundOne = spriteOne.Bounds();
    	const BoundingBox &boundTwo = spriteTwo.Bounds();
    
    	//if the left is greater than the right no collison
    	if(boundOne.left > boundTwo.right){
    		return false;
    	}//if
    
    	//if the right is less than the left no collision
    	if(boundOne.right < boundTwo.left){
    		return false;
    	}//if
    
    	//if the bottom is less than the top no collision
    	if(boundOne.bottom < boundTwo.top){
    		return false;
    	}//if
    
    	//if the top is greater than the bottom no collision
    	if(boundOne.top > boundTwo.bottom){
    		return false;
    	}//if
    
    	//if all the checks failed that means they are colliding
    	return true;
    }
    
    bool CCollisionDetection::DetectPixelPerfect(const CSprite &spriteOne, const CSprite &spriteTwo)
    {
    	//Cannot preform collision detection on a non active sprite
    	if(!spriteOne.IsActive() || !spriteTwo.IsActive()){
    		return false;
    	}//if
    
    	//Preform bounding box collision to save the waste of cpu on collision that are not close
    	if(!DetectBoundingBox(spriteOne, spriteTwo)){
    		return false;
    	}//if
    
    	//
    	//Grab the sprite's bounds
    	//
    	const BoundingBox& boundOne = spriteOne.Bounds();
    	const BoundingBox& boundTwo = spriteTwo.Bounds();
    
    	//Grab the sprite's images
    	const CBitmap& imageOne = spriteOne.Image();
    	const CBitmap& imageTwo = spriteTwo.Image();
    
    	//
    	//Grab both sprite bitmask colors.
    	//
    	int spriteOneBitmask = imageOne.MaskColor();
    	int spriteTwoBitmask = imageTwo.MaskColor();
    
    	//
    	//Grab the min and max y overlap
    	//
    	int minY = std::max(boundOne.top, boundTwo.top);
    	int maxY = std::min(boundOne.bottom, boundTwo.bottom);
    
    	//
    	//Grab the min and max x overlap
    	//	
    	int minX = std::max(boundOne.left, boundTwo.left);
    	int maxX = std::min(boundOne.right, boundTwo.right);
    
    	for(int currentY = minY; currentY < maxY; currentY++){
    		//
    		//Grab the x adjustments for grabbing the proper place in the image.
    		//
    		int spriteOneYAdjustedPixel = currentY - boundOne.top;
    		int spriteTwoYAdjustedPixel = currentY - boundTwo.top;
    
    		for(int currentX = minX; currentX < maxX; currentX++){
    			//
    			//Grab the position x adjustments for grabbing the proper place in the image.
    			//
    			int spriteOneXAdjustedPixel = currentX - boundOne.left;
    			int spriteTwoXAdjustedPixel = currentX - boundTwo.left;
    
    			//Get the current pixel for the first sprite
    			int spriteOneCurrentPixel = imageOne.GetPixel(spriteOneXAdjustedPixel, spriteOneYAdjustedPixel);
    
    			//Get the current pixel for the second sprite
    			int spriteTwoCurrentPixel = imageTwo.GetPixel(spriteTwoXAdjustedPixel, spriteTwoYAdjustedPixel);
    
    			//Special Case: If both pixel at the current position are not the mask color of the
    			//image then they are overlapping. Return true to the caller.
    			if(spriteOneCurrentPixel != spriteOneBitmask && spriteTwoCurrentPixel != spriteTwoBitmask){
    				return true;
    			}//if
    		}//for
    	}//for
    	return false;
    }
    Woop?

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    30
    cool, thanks!

    Looking through the code now....i've never used allegro but I might be able to convert over to directx. I have seen other examples and they were quite different.

    see here

    p.s. what is the code for you header file?
    Last edited by dhardin; 03-30-2010 at 10:42 PM. Reason: didn't want to 2x post

  4. #4
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    I have never really worked with direct x sprites or textures before.

    But the key points were the logic. There are a couple of lines that should be replaced by direct x objects. The mask pixel color, the bounding box, etc.

    But that two level loop is really where the magic happens.
    Woop?

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    30
    yeah, i figured i'd need some kind of loop like that. I was gonna write mine from scratch and store the mask for the sprite in a 2d array. Then somehow, get the detection to work from there...but I know I have to lock the current animation frame before I detect a collision because the little guy is always moving

  6. #6
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Here is the header file
    Code:
    #ifndef collision_h
    #define collision_h
    #include "Sprite.h"
    
    class CCollisionDetection
    {
    public:
    	static bool DetectBoundingBox(const CSprite &spriteOne, const CSprite &spriteTwo);
    	static bool DetectPixelPerfect(const CSprite &spriteOne, const CSprite &spriteTwo);
    };
    
    #endif//collision_h
    Woop?

  7. #7
    Registered User
    Join Date
    Dec 2009
    Posts
    30
    Thanks, my eyes are getting tired though and I should probably wait till morning before I can think clearly :\

    But thanks for all your help, I'm still confused on all the different examples I've seen for "Pixel Perfect" collisions. Although I know there are going to be many different methods of doing this, I think I will try to go with the one that I understand the most :b

    Thanks again, I'll PM you if I have any questions regarding your code

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Directx 9 2D
    By ybobjoe in forum Game Programming
    Replies: 5
    Last Post: 11-18-2009, 10:09 PM
  2. 2D in directX
    By fighter92 in forum Game Programming
    Replies: 6
    Last Post: 01-25-2009, 11:23 AM
  3. 2D pixel perfect collision detection
    By Warlax in forum Game Programming
    Replies: 0
    Last Post: 06-22-2006, 07:39 AM
  4. Pixel perfect 2D collision detection with Allegro
    By Warlax in forum C++ Programming
    Replies: 1
    Last Post: 06-21-2006, 02:14 PM
  5. 2d collision and image structure
    By valis in forum Game Programming
    Replies: 6
    Last Post: 11-20-2005, 10:28 PM