Jump to content
  • Advertisement
Sign in to follow this  
nullsquared

SDL false cpllision detection

This topic is 4814 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all! I have a weird problem with collision detection. I got this header file called SDL_Colide.h, and it defines a function for collision detection... The function takes in 6 parameters(the SDL_Surfaces*, and the x and y positions of the two SDL_Surfaces*). It does the y < x && x < x2(i bet its not exactly that, its just that I dont have it open right now) kind of stuff. Then I use the func. to test if mario1 SDL_Surface* collides with the enemy, and it works fine. But then I let mario duck(mario1down). I use the same coordinates as mario1 for mario1down, but since mario1down is 18x14 and mario1 is 18x27, I just add 13(the difference) to the height variable to DRAW the mario1down surface. But then, when I do the same thing to check for collisions, the func. looks like takes in height, not (height + 13)... Heres the function in the header:
[source language="cpp"]
int SDL_Collide(SDL_Surface *as , int ax , int ay , SDL_Surface *bs , int bx , int by)
{
	/*Box A;
	Box B;*/

	/*a - bottom right co-ordinates*/
	int ax1 = ax + as->w - 1;
	int ay1 = ay + as->h - 1;
	
	/*b - bottom right co-ordinates*/
	int bx1 = bx + bs->w - 1;
	int by1 = by + bs->h - 1;

	/*check if bounding boxes intersect*/
	if((bx1 == ax) || (ax1 == bx))
		return 0;
	if((by1 == ay) || (ay1 == by))
		return 0;


/*Now lets make the bouding box for which we check for a pixel collision*/

	/*To get the bounding box we do
	    Ax1,Ay1_____________
		|		|
		|		|
		|		|
		|    Bx1,By1_____________
		|	|	|	|
		|	|	|	|
		|_______|_______|	|
			|    Ax2,Ay2	|
			|		|
			|		|
			|____________Bx2,By2

	To find that overlap we find the biggest left hand cordinate
	AND the smallest right hand co-ordinate

	To find it for y we do the biggest top y value
	AND the smallest bottom y value

	Therefore the overlap here is Bx1,By1 --> Ax2,Ay2

	Remember	Ax2 = Ax1 + SA->w
			Bx2 = Bx1 + SB->w

			Ay2 = Ay1 + SA->h
			By2 = By1 + SB->h
	*/

	/*now we loop round every pixel in area of
	intersection
		if 2 pixels alpha values on 2 surfaces at the
		same place != 0 then we have a collision*/
	int inter_x0 = SDL_COLLIDE_MAX(ax,bx);
	int inter_x1 = SDL_COLLIDE_MIN(ax1,bx1);

	int inter_y0 = SDL_COLLIDE_MAX(ay,by);
	int inter_y1 = SDL_COLLIDE_MIN(ay1,by1);

	for(int y = inter_y0 ; y <= inter_y1 ; y++)
	{
		for(int x = inter_x0 ; x <= inter_x1 ; x++)
		{
			if((SDL_TransparentPixel(as , x-ax , y-ay))/*compute offsets for surface*/
			&& (SDL_TransparentPixel(bs , x-bx , y-by)))/*before pass to SDL_TransparentPixel*/
				return 1;
		}
	}
}

I use code::blocks. IDK why I said that, but it might help(?). I check for the function to return 1 if theres a collision, PLEASE tell me if I'm wrong, cuz my project is pretty messed up and I want to fix it. I'm doing it as a hobby, and its the only thing thats interesting. Oh yeah, heres the .cpp file code:
[source language="cpp"]
#include <windows.h>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include "SDL_collide.h"

SDL_Surface *screen;
void Draw(int, int, SDL_Surface*);

int main(int, char**)
{
    srand(time(NULL));
    
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
    atexit(SDL_Quit);
    
    Mix_OpenAudio(25000, AUDIO_S16, 2, 6414);
    
    SDL_Surface *Win;
    Win = IMG_Load("win.bmp");
    if (Win == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
    
    int width3 = 700, height3 = 268;
    SDL_Surface *GameOver;
    GameOver = IMG_Load("gameover.bmp");
    if (GameOver == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
    
    Mix_Music *bgSound;
    bgSound = Mix_LoadMUS("mario1.mid");
    if (bgSound == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load music!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }

    screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    if (screen == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to set screen!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
        
    SDL_Surface *bg;
    bg = IMG_Load("bg.bmp");
    if (bg == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
    
    int width2 = 700, height2 = 395, random = rand() % 100;    
    int width4 = width2, height4 = height2, random2 = rand() % 100;
    SDL_Surface *enemy;
    enemy = IMG_Load("enemy.bmp");
    if (enemy == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
    
    int height = 383, width = 1;
    SDL_Surface *mario1;
    mario1 = IMG_Load("mario1.bmp");
    if (mario1 == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
        
    SDL_Surface *mario2;
    mario2 = IMG_Load("mario2.bmp");
    if (mario2 == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
        
    SDL_Surface *mario1down;
    mario1down = IMG_Load("mario1down.bmp");
    if (mario1down == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
        
    SDL_Surface *mario2down;
    mario2down = IMG_Load("mario2down.bmp");
    if (mario2down == NULL)
    {
        MessageBox(NULL, "ERROR: Unable to load bitmap!", "ERROR", MB_OK | MB_ICONERROR);
        return 0;
    }
        
    bool MARIO1 = true, 
         MarioJump = false, 
         MarioDown = false, 
         MoveAble = true,
         falling = false;
    
    SDL_SetColorKey(mario1, SDL_SRCCOLORKEY, SDL_MapRGB(mario1->format, 0, 255, 255));
    SDL_SetColorKey(mario2, SDL_SRCCOLORKEY, SDL_MapRGB(mario2->format, 0, 255, 255));
    SDL_SetColorKey(mario2down, SDL_SRCCOLORKEY, SDL_MapRGB(mario2down->format, 0, 255, 255));
    SDL_SetColorKey(mario1down, SDL_SRCCOLORKEY, SDL_MapRGB(mario1down->format, 0, 255, 255));
    SDL_SetColorKey(enemy, SDL_SRCCOLORKEY, SDL_MapRGB(enemy->format, 0, 255, 255));
    SDL_SetColorKey(GameOver, SDL_SRCCOLORKEY, SDL_MapRGB(GameOver->format, 0, 255, 255));
    SDL_SetColorKey(Win, SDL_SRCCOLORKEY, SDL_MapRGB(GameOver->format, 0, 255, 255));
        
    Mix_PlayMusic(bgSound, -1);

    Uint8* keys;
    int start;
    bool isRunning = true;
    
    while(isRunning)
    {
        start = SDL_GetTicks();
        
        SDL_Event event;
        SDL_PollEvent(&event);

        switch (event.type)
        {
            case SDL_QUIT:
                isRunning = false;
            break;
            case SDL_KEYDOWN:
                 switch (event.key.keysym.sym)
                 {
                     case SDLK_ESCAPE:
                         isRunning = false;
                     break;
                 }
            break;
        }
        
        keys = SDL_GetKeyState(NULL);
        
        if (keys[SDLK_DOWN])
        {
            MarioDown = true;
            MoveAble = false;
        }
        if (keys[SDLK_UP] && MoveAble)
        {
            MarioJump = true;
        }
        if (keys[SDLK_LEFT] && MoveAble) 
        { 
            if (width > 0)
                width -= 5;
                
            MARIO1 = false;
        }
        if (keys[SDLK_RIGHT] && MoveAble) 
        { 
            if ((width + 18) < 800)
                width += 5;
                
            MARIO1 = true;
        }
        
        SDL_FillRect(screen, 0, 0);
        Draw(0, 0, bg);
        
        Draw(width3, height3, Win);
        if (SDL_Collide(mario1, width, height, Win, width3, height3) == 1)
        {
            Draw(350, 200, GameOver);
            SDL_Flip(screen);
            SDL_Delay(2000);
            
            SDL_FreeSurface(bg);
            SDL_FreeSurface(mario1);
            SDL_FreeSurface(mario2);
            SDL_FreeSurface(mario1down);
            SDL_FreeSurface(mario2down);
            SDL_FreeSurface(enemy);
            SDL_FreeSurface(GameOver);
            SDL_FreeSurface(Win);
        
            Mix_FreeMusic(bgSound);
            Mix_CloseAudio();
            return 0;
        }
        
        if (MarioJump == false)
        {
            if (MARIO1)
            {
                if (MarioDown == true)
                {
                    Draw(width, (height + 13), mario1down);
                    MarioDown = false;
                    MoveAble = true;
                }
                else
                    Draw(width, height, mario1);
            }
            else
            {
                if (MarioDown == true)
                {
                    Draw((width - 1), (height + 12), mario2down);
                    MarioDown = false;
                    MoveAble = true;
                }
                else
                    Draw(width, height, mario2);
            }
        }
        else
        {
            if (height > 301 && falling == false)
            {
                height -= 5;
                
                if (MARIO1 && MoveAble)
                    Draw(width, height, mario1);
                else if (MoveAble)
                    Draw(width, height, mario2);
            }
            else
            {
                falling = true;
                if (height < 381)
                {
                    height += 5;
                    
                    if (MARIO1 && MoveAble)
                        Draw(width, height, mario1);
                    else if (MoveAble)
                        Draw(width, height, mario2);
                }
                else
                {       
                    MarioJump = false;
                    falling = false;
                }
            }
            if (MARIO1)
                Draw(width, height, mario1);
            else
                Draw(width, height, mario2);
        }
        
        Draw(width2, (height2 - random), enemy);
        
        if (MarioDown == false)
        {
            if (SDL_Collide(mario1, width, height, enemy, width2, (height2 - random)) == 1)
            {
                Draw(350, 200, GameOver);
                SDL_Flip(screen);
                SDL_Delay(2000);
                
                SDL_FreeSurface(bg);
                SDL_FreeSurface(mario1);
                SDL_FreeSurface(mario2);
                SDL_FreeSurface(mario1down);
                SDL_FreeSurface(mario2down);
                SDL_FreeSurface(enemy);
                SDL_FreeSurface(GameOver);
                SDL_FreeSurface(Win);
            
                Mix_FreeMusic(bgSound);
                Mix_CloseAudio();
                return 0;
            }
        }
        else
        {
            if (SDL_Collide(mario1down, width, (height + 13), enemy, width2, (height2 - random)) == 1)
            {
                Draw(350, 200, GameOver);
                SDL_Flip(screen);
                SDL_Delay(2000);
                
                SDL_FreeSurface(bg);
                SDL_FreeSurface(mario1);
                SDL_FreeSurface(mario2);
                SDL_FreeSurface(mario1down);
                SDL_FreeSurface(mario2down);
                SDL_FreeSurface(enemy);
                SDL_FreeSurface(GameOver);
                SDL_FreeSurface(Win);
            
                Mix_FreeMusic(bgSound);
                Mix_CloseAudio();
                return 0;
            }
        }
        
        width2 -= 2;
        
        if (width2 <= 0)
        {
            random = rand() % 100;
            width2 = 700;
        }
        
        Draw(width4, (height4 - random2), enemy);
        
        if (MarioDown == false)
        {
            if (SDL_Collide(mario1, width, height, enemy, width4, (height4 - random2)) == 1)
            {
                Draw(350, 200, GameOver);
                SDL_Flip(screen);
                SDL_Delay(2000);
                
                SDL_FreeSurface(bg);
                SDL_FreeSurface(mario1);
                SDL_FreeSurface(mario2);
                SDL_FreeSurface(mario1down);
                SDL_FreeSurface(mario2down);
                SDL_FreeSurface(enemy);
                SDL_FreeSurface(GameOver);
                SDL_FreeSurface(Win);
            
                Mix_FreeMusic(bgSound);
                Mix_CloseAudio();
                return 0;
            }
        }
        else
        {
            if (SDL_Collide(mario1down, width, (height + 13), enemy, width2, (height2 - random)) == 1)
            {
                Draw(350, 200, GameOver);
                SDL_Flip(screen);
                SDL_Delay(2000);
                
                SDL_FreeSurface(bg);
                SDL_FreeSurface(mario1);
                SDL_FreeSurface(mario2);
                SDL_FreeSurface(mario1down);
                SDL_FreeSurface(mario2down);
                SDL_FreeSurface(enemy);
                SDL_FreeSurface(GameOver);
                SDL_FreeSurface(Win);
            
                Mix_FreeMusic(bgSound);
                Mix_CloseAudio();
                return 0;
            }
        }
        
        width4 -= 3;
        
        if (width4 <= 0)
        {
            random2 = rand() % 100;
            width4 = 700;
        }
        
        SDL_Flip(screen);
        
        while ((SDL_GetTicks() - start) < 33);
    }
    
    SDL_FreeSurface(bg);
    SDL_FreeSurface(mario1);
    SDL_FreeSurface(mario2);
    SDL_FreeSurface(mario1down);
    SDL_FreeSurface(mario2down);
    SDL_FreeSurface(enemy);
    SDL_FreeSurface(GameOver);
    SDL_FreeSurface(Win);

    Mix_FreeMusic(bgSound);
    Mix_CloseAudio();
    return 0;
}

void Draw(int x, int y, SDL_Surface *sprite)
{
    SDL_Rect source;
    SDL_Rect dest;

    source.x = 0;
    source.y = 0;
    source.w = sprite->w;
    source.h = sprite->h;

    dest.x = x;
    dest.y = y;
    dest.w = source.w;
    dest.h = source.h;

    SDL_BlitSurface(sprite, &source, screen, &dest);

    return;
}

Thanks a lot! As said before, it works for mario standing up, but it works like mario standing up when hes ducked... LOL, so if you have any suggestions, tell me. Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!