Posted: 22nd Jan 2003 2:36
That snippet use memblocks to calculate real pixel collision between 2 sprites .
It can :
- use differents sized sprites
- is compatible DBv1(+Darkmatter) and DBPro
- send back how many pixels are overlaped.


Rem
Rem 2D-Sprites Real Pixel Collisions Detection
Rem

Rem
Set Display Mode 320,240,16
Sync rate 25 : 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

Rem Beginning of the main loop . . .
Repeat
cls 0

Rem Calculate demo sprite movements . . .
xpos=xpos+rightkey()-leftkey()
ypos=ypos+downkey()-upkey()
if xpos320-32 then xpos=320-32
if ypos240-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)

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)
_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(yp1+ys1) or yp2xp1
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=fct_Get_pixel_color(_memblock1,xloop+xstart1,yloop+ystart1)
_pix2=fct_Get_pixel_color(_memblock2,xloop+xstart2,yloop+ystart2)
if _pix10 and _pix20 then _PIXEL=_PIXEL+1
next xloop
next yloop
Delete memblock _memblock1
Delete memblock _memblock2
Endif
Endif
EndFunction _PIXEL
Rem
Function Fct_Get_Pixel_Color(_memblock,xpos,ypos)
_RESULT=0
Rem Get pixel only if memblock exist !
if memblock exist(_memblock)=1
_xs=memblock dword(_memblock,0) : _ys=memblock dword(_memblock,4)
_dp=memblock dword(_memblock,8) : _pixsize=_dp/8
Rem Get pixel only if coordinates are valids !
if xpos>0-1 and xpos0-1 and ypos-1 and _Adress
Posted: 22nd Jan 2003 2:39
oops sorry . . .
I always get problem when posting that forum !!!!

+ Code Snippet
Rem
Rem 2D-Sprites Real Pixel Collisions Detection
Rem

Rem
Set Display Mode 320,240,16
Sync rate 25 : 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

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)

  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)
  _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)
      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=fct_Get_pixel_color(_memblock1,xloop+xstart1,yloop+ystart1)
          _pix2=fct_Get_pixel_color(_memblock2,xloop+xstart2,yloop+ystart2)
          if _pix1<>0 and _pix2<>0 then _PIXEL=_PIXEL+1
         next xloop
       next yloop
      Delete memblock _memblock1
      Delete memblock _memblock2
     Endif
   Endif
 EndFunction _PIXEL
Rem
Function Fct_Get_Pixel_Color(_memblock,xpos,ypos)
  _RESULT=0
  Rem Get pixel only if memblock exist !
  if memblock exist(_memblock)=1
    _xs=memblock dword(_memblock,0) : _ys=memblock dword(_memblock,4)
    _dp=memblock dword(_memblock,8) : _pixsize=_dp/8
    Rem Get pixel only if coordinates are valids !
    if xpos>0-1 and xpos<_xs
      if ypos>0-1 and ypos<_ys
        _Adress=12+(ypos*_xs*_pixsize)+(xpos*_pixsize)
        if _Adress>-1 and _Adress<(get memblock size(_memblock)-_pixsize)
          if _dp=8 then _RESULT=memblock byte(_memblock,_Adress)
          if _dp=16 then _RESULT=memblock word(_memblock,_Adress)
          if _dp=32 then _RESULT=memblock dword(_memblock,_Adress)
         endif
       Endif
     Endif
   endif
 Endfunction _RESULT
Posted: 22nd Jan 2003 18:24
Here is a new release !
Faster and that can use 1 more parameter : _MODE
_MODE=0 only check if there is pixel collision
_MODE=1 count how many pixels are overlaped by collision.

+ Code Snippet
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
Posted: 24th Jan 2003 17:55
Thanks freddix, excellent work - If it is posted on RGT (I am pretty sure it is) I'll send some kudos your way
Posted: 24th Jan 2003 20:13
thanks
Posted: 11th Feb 2003 7:36
Thanks very much man,

I been looking for a solution to that problem for a long time now - see my post in

http://www.realgametools.net/forums/index.php?board=13;action=display;threadid=9366

I asked that question 31st oct last year and gave up hope.

Thanks again, you may just have made DB pro worth buying.