Hey guys so im making a 2d game in GDK and before everything i need to have a 2d collision system working, ive seen quite a few different ones and i think Freedix's system is what im looking for(
http://forum.thegamecreators.com/?m=forum_view&t=4826&b=6)
So here is his code.
Rem
Rem 2D-Sprites Real Pixel Collisions Detection
Rem
Rem
Set Display Mode 320,240,16
Sync rate 0 : Sync on : Sync : Sync
Rem Load 2 images to make sprites.
Load image "gfx\sprite1.bmp",1,1
Load image "gfx\sprite2.bmp",2,1
Rem Default sprites position on screen
xpos=0 : ypos=0
xpos2=160-16 : ypos2=100-16
_mode=1
Rem Beginning of the main loop . . .
Repeat
cls 0
Rem Calculate demo sprite movements . . .
xpos=xpos+rightkey()-leftkey()
ypos=ypos+downkey()-upkey()
if xpos<0 then xpos=0
if xpos>320-32 then xpos=320-32
if ypos<0 then ypos=0
if ypos>240-32 then ypos=240-32
Rem Display sprites . . .
Sprite 1,xpos,ypos,1
Sprite 2,xpos2,ypos2,2
Rem Calculate sprite collision . . .
_PIXELS=Fct_Sprite_Pixel_Collision(1,2,_mode)
Rem Display result . . .
Set cursor 0,0 : ink rgb(255,255,255),0
if _PIXELS>0 then print "Pixel collision detected !!!" else print "No pixel collision . . ."
if _PIXELS>0 then print _PIXELS," pixels are common to both sprites"
print "FPS : ",screen fps()
Sync
Until Spacekey()=1
For boucle=1 to 2
Hide sprite boucle
Delete Sprite boucle
delete image boucle
Next Boucle
End
Function FCT_Sprite_Pixel_Collision(_sprite1,_sprite2,_mode)
_PIXEL=-1 : _CHECK=1
_memblock1=1 : _memblock2=2
Rem Check only if both sprites exists . . .
if sprite exist(_sprite1)=1 and sprite exist(_sprite2)=1
Rem Get Sprite #1 datas . . .
xp1=sprite x(_sprite1) : yp1=sprite y(_sprite1)
xs1=sprite width(_sprite1) : ys1=sprite height(_sprite1)
Rem Get Sprite #2 datas . . .
xp2=sprite x(_sprite2) : yp2=sprite y(_sprite2)
xs2=sprite width(_sprite2) : ys2=sprite height(_sprite2)
set cursor 0,64
print xp1," ",yp1," ",xs1," ",ys1
print xp2," ",yp2," ",xs2," ",ys2
Rem Now Collisions will be detected only if Sprite 1 and Sprite 2 are 1 overlaped
if xp2>(xp1+xs1) or xp2<(xp1-xs2) then _CHECK=0
if yp2>(yp1+ys1) or yp2<(yp1-ys2) then _CHECK=0
Rem If sprites are overlaped then we make collision . ..
if _CHECK=1
Print "Calculate if collision exist . . ."
_PIXEL=0
Rem Create 2 memblock in order to read sprites datas . . .
Make Memblock from image _memblock1,sprite image(_sprite1)
Make Memblock from image _memblock2,sprite image(_sprite2)
_dp1=memblock dword(_memblock1,8) : _pixsize1=_dp1/8
_dp2=memblock dword(_memblock2,8) : _pixsize2=_dp2/8
Rem We check for the box to read in both sprites . . .
if xp2>xp1
xstart1=xp2-xp1 : xstart2=0 : xchecksize=xs1-xstart1
else
xstart2=xp1-xp2 : xstart1=0 : xchecksize=xs2-xstart2
endif
if yp2>yp1
ystart1=yp2-yp1 : ystart2=0 : ychecksize=ys1-ystart1
else
ystart2=yp1-yp2 : ystart1=0 : ychecksize=ys2-ystart2
endif
Rem Now we make a loop to check all pixels . . .
for yloop=0 to ychecksize
for xloop=0 to xchecksize
_pix1=0 : _pix2=0
xpos=xloop+xstart1 : ypos=yloop+ystart1
if xpos>-1 and xpos<xs1
if ypos>-1 and ypos<ys1
_Adress=12+(ypos*xs1*_pixsize1)+(xpos*_pixsize1)
if _Adress>-1 and _Adress<(get memblock size(_memblock1)-_pixsize1)
if _dp1=16 then _pix1=memblock word(_memblock1,_Adress)
if _dp1=32 then _pix1=memblock dword(_memblock1,_Adress)
endif
Endif
Endif
xpos=xloop+xstart2 : ypos=yloop+ystart2
if xpos>-1 and xpos<xs2
if ypos>-1 and ypos<ys2
_Adress=12+(ypos*xs2*_pixsize2)+(xpos*_pixsize2)
if _Adress>-1 and _Adress<(get memblock size(_memblock2)-_pixsize2)
if _dp2=16 then _pix2=memblock word(_memblock2,_Adress)
if _dp2=32 then _pix2=memblock dword(_memblock2,_Adress)
endif
Endif
Endif
if _pix1<>0 and _pix2<>0 then _PIXEL=_PIXEL+1
if _PIXEL>0 and _MODE=0
xloop=xchecksize : yloop=ychecksize
Endif
next xloop
next yloop
Delete memblock _memblock1
Delete memblock _memblock2
Endif
Endif
EndFunction _PIXEL
Rem
and below is What ive converted it to.
//I DECLARED THESE as globals
int xpos = 0;
int ypos = 0;
int xpos2 = 160-16;
int ypos2 = 100-16;
int mode = 1;
//make this Return a bool yes collision or no collision
//Originally created for db Pro *Freddix*
int sprite_Collision(int spriteA, int spriteB, int _mode)
{
int PIXEL=-1;
int _CHECK=1;
int _memblock1=1; int _memblock2=2;
//Check only if both sprites exists . . .
if (dbSpriteExist(spriteA)==1 && dbSpriteExist(spriteB)==1)
{
// Get Sprite #1 data . . .
int xp1=dbSpriteX(spriteA);
int yp1=dbSpriteY(spriteA);
int xs1=dbSpriteWidth(spriteA);
int ys1=dbSpriteHeight(spriteA);
// Rem Get Sprite #2 data . . .
int xp2=dbSpriteX(spriteB);
int yp2=dbSpriteY(spriteB);
int xs2=dbSpriteWidth(spriteB);
int ys2=dbSpriteHeight(spriteB);
dbSetCursor( 0, 64);
char xP[100];
sprintf_s ( xP, 200, "xp1 %i yp1 %i xs1 %i ys1 %i", xp1, yp1, xs1, ys1);
dbText (100,450, xP);
char xPSec[100];
sprintf_s ( xPSec, 200, "xp2 %i yp2 %i xs2 %i ys2 %i", xp2, yp2, xs2, ys2);
dbText (100,500, xPSec);
// Now Collisions will be detected only if Sprite 1 && Sprite 2 are 1 overlaped
if (xp2>(xp1+xs1) || xp2<(xp1-xs2)) _CHECK=0;
if (yp2>(yp1+ys1) || yp2<(yp1-ys2)) _CHECK=0;
// If sprites are overlaped then we make collision . ..
if (_CHECK==1)
{
dbPrint("Calculate if collision exists . . .");
PIXEL=0;
// Create 2 memblock in order to read sprites datas . . .
dbMakeMemblockFromImage(_memblock1, dbSpriteImage(spriteA));
dbMakeMemblockFromImage(_memblock2, dbSpriteImage(spriteB));
int _dp1=dbMemblockDword (_memblock1, 8);
int _pixsize1=_dp1/8;
int _dp2=dbMemblockDword(_memblock2, 8);
int _pixsize2=_dp2/8;
int xstart2;
int xstart1;
int xchecksize;
// We check for the box to read in both sprites . . .
if (xp2>xp1)
{
xstart1=xp2-xp1;
xstart2=0;
xchecksize=xs1-xstart1;
}
else
{
xstart2=xp1-xp2;
xstart1=0;
xchecksize=xs2-xstart2;
}
int ystart1;
int ystart2;
int ychecksize;
if (yp2>yp1)
{
ystart1=yp2-yp1;
ystart2=0;
ychecksize=ys1-ystart1;
}
else
{
ystart2=yp1-yp2;
ystart1=0;
ychecksize=ys2-ystart2;
}
// Now we make a loop to check all pixels . . .
for (int yloop=0; yloop < ychecksize; yloop++)
{
for (int xloop=0; xloop < xchecksize; xloop++)
{
int _pix1=0;
int _pix2=0;
int _Adress;
xpos=xloop+xstart1;
ypos=yloop+ystart1;
if (xpos>-1 && xpos<xs1)
{
if (ypos>-1 && ypos<ys1)
{
_Adress=12+(ypos*xs1*_pixsize1)+(xpos*_pixsize1);
if (_Adress>-1 && _Adress<(dbGetMemblockSize(_memblock1)-_pixsize1))
{
if (_dp1==16) _pix1=dbMemblockWord(_memblock1,_Adress);
if (_dp1==32) _pix1=dbMemblockDword(_memblock1,_Adress);
}
}
}
xpos=xloop+xstart2;
ypos=yloop+ystart2;
if (xpos>-1 && xpos<xs2)
{
if (ypos>-1 && ypos<ys2)
{
_Adress=12+(ypos*xs2*_pixsize2)+(xpos*_pixsize2);
if (_Adress>-1 && _Adress<(dbGetMemblockSize(_memblock2)-_pixsize2))
{
if (_dp2==16) _pix2=dbMemblockWord(_memblock2,_Adress);
if (_dp2==32) _pix2=dbMemblockDword(_memblock2,_Adress);
}
}
}
if (_pix1!=0 && _pix2!=0) PIXEL = PIXEL+1;
if (PIXEL>0 && _mode==0)
{
xloop=xchecksize;
yloop=ychecksize;
}
}
}
dbDeleteMemblock(_memblock1);
dbDeleteMemblock(_memblock2);
}
}
return PIXEL;
}
So my problem is that in my version as soon as
"dbPrint("Calculate if collision exists . . .");"
displays and _CHECK = 1 then the movement sprite gets reset to their original position.
If you could help me make this work that would be greatly appreciated.
Thanks
EDIT:Never mind i found a way of converting the code using Frame's DarkBASIC Pro to DarkGDK Converter, although it had a few errors the modifications necessary were very few, here's Freddix's 2d pixel perfect collision system for Dark gdk.
int sprite_Collision ( int _sprite1, int _sprite2, int _mode )
{
int _pixel = 0;
int _check = 0;
int _memblock1 = 0;
int _memblock2 = 0;
int xp1 = 0;
int yp1 = 0;
int xs1 = 0;
int ys1 = 0;
int xp2 = 0;
int yp2 = 0;
int xs2 = 0;
int ys2 = 0;
int _dp1 = 0;
int _pixsize1 = 0;
int _dp2 = 0;
int _pixsize2 = 0;
int xstart1 = 0;
int xstart2 = 0;
int xchecksize = 0;
int ystart1 = 0;
int ystart2 = 0;
int ychecksize = 0;
int yloop = 0;
int xloop = 0;
int _pix1 = 0;
int _pix2 = 0;
int xpos = 0;
int ypos = 0;
int _adress = 0;
_pixel = -1;
_check = 1;
_memblock1 = 1;
_memblock2 = 2;
// Check only if both sprites exists . . .
if ( dbSpriteExist( _sprite1 ) == 1 && dbSpriteExist( _sprite2 ) == 1 ) {
// Get Sprite #1 datas . . .
xp1 = dbSpriteX( _sprite1 );
yp1 = dbSpriteY( _sprite1 );
xs1 = dbSpriteWidth( _sprite1 );
ys1 = dbSpriteHeight( _sprite1 );
// Get Sprite #2 datas . . .
xp2 = dbSpriteX( _sprite2 );
yp2 = dbSpriteY( _sprite2 );
xs2 = dbSpriteWidth( _sprite2 );
ys2 = dbSpriteHeight( _sprite2 );
dbSetCursor( 0, 64 );
char xP[100];
sprintf_s ( xP, 200, "xp1 %i yp1 %i xs1 %i ys1 %i", xp1, yp1, xs1, ys1);
dbText (100,450, xP);
char xPSec[100];
sprintf_s ( xPSec, 200, "xp2 %i yp2 %i xs2 %i ys2 %i", xp2, yp2, xs2, ys2);
dbText (100,500, xPSec);
// Now Collisions will be detected only if Sprite 1 and Sprite 2 are 1 overlaped
if ( xp2 > ( xp1 + xs1 ) || xp2 < ( xp1 - xs2 ) ) {
_check = 0;
}
if ( yp2 > ( yp1 + ys1 ) || yp2 < ( yp1 - ys2 ) ) {
_check = 0;
}
// If sprites are overlaped then we make collision . ..
if ( _check == 1 ) {
dbPrint("Calculate if collision exists . . .");
_pixel = 0;
// Create 2 memblock in order to read sprites datas . . .
dbMakeMemblockFromImage( _memblock1, dbSpriteImage( _sprite1 ) );
dbMakeMemblockFromImage( _memblock2, dbSpriteImage( _sprite2 ) );
_dp1 = dbMemblockDword( _memblock1, 8 );
_pixsize1 = _dp1 / 8;
_dp2 = dbMemblockDword( _memblock2, 8 );
_pixsize2 = _dp2 / 8;
// We check for the box to read in both sprites . . .
if ( xp2 > xp1 ) {
xstart1 = xp2 - xp1;
xstart2 = 0;
xchecksize = xs1 - xstart1;
}
else {
xstart2 = xp1 - xp2;
xstart1 = 0;
xchecksize = xs2 - xstart2;
}
if ( yp2 > yp1 ) {
ystart1 = yp2 - yp1;
ystart2 = 0;
ychecksize = ys1 - ystart1;
}
else {
ystart2 = yp1 - yp2;
ystart1 = 0;
ychecksize = ys2 - ystart2;
}
// Now we make a loop to check all pixels . . .
for ( yloop = 0; yloop <= ychecksize; yloop++ ) {
for ( xloop = 0; xloop <= xchecksize; xloop++ ) {
_pix1 = 0;
_pix2 = 0;
xpos = xloop + xstart1;
ypos = yloop + ystart1;
if ( xpos > -1 && xpos < xs1 ) {
if ( ypos > -1 && ypos < ys1 ) {
_adress = 12 + ( ypos * xs1 * _pixsize1 ) + ( xpos * _pixsize1 );
if ( _adress > -1 && _adress < ( dbGetMemblockSize( _memblock1 ) - _pixsize1 ) ) {
if ( _dp1 == 16 ) {
_pix1 = dbMemblockWord( _memblock1, _adress );
}
if ( _dp1 == 32 ) {
_pix1 = dbMemblockDword( _memblock1, _adress );
}
}
}
}
xpos = xloop + xstart2;
ypos = yloop + ystart2;
if ( xpos > -1 && xpos < xs2 ) {
if ( ypos > -1 && ypos < ys2 ) {
_adress = 12 + ( ypos * xs2 * _pixsize2 ) + ( xpos * _pixsize2 );
if ( _adress > -1 && _adress < ( dbGetMemblockSize( _memblock2 ) - _pixsize2 ) ) {
if ( _dp2 == 16 ) {
_pix2 = dbMemblockWord( _memblock2, _adress );
}
if ( _dp2 == 32 ) {
_pix2 = dbMemblockDword( _memblock2, _adress );
}
}
}
}
if ( _pix1 != 0 && _pix2 != 0 ) {
_pixel = _pixel + 1;
}
if ( _pixel > 0 && _mode == 0 ) {
xloop = xchecksize;
yloop = ychecksize;
}
}
}
dbDeleteMemblock( _memblock1 );
dbDeleteMemblock( _memblock2 );
}
}
return _pixel;
}