| 
 
| 
|  Author | Topic: sprite collisions  (Read 972 times) |  |  
| 
| 
| leslie griffin Guest
 
 | 
|  | sprite collisions « Thread started on: Dec 30th, 2009, 10:54pm »
 |  |  is there any collision detction embedded in bbc basic or do i write my own routines..thx...
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| admin Administrator
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 1145
 
 | 
|  | Re: sprite collisions « Reply #1 on: Dec 31st, 2009, 08:31am »
 |  |  Quote:
 | | is there any collision detection embedded in bbc basic | 
 | 
 SPRITELIB doesn't contain any collision detection code (it has been suggested before, but nobody's implemented it AFAIK).  I don't know about GFXLIB; you would need to ask its author.
 
 Richard.
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| David Williams Developer
 
 member is offline
 
  
 meh
 
 
 
  
 Gender:
  Posts: 452
 
 | 
|  | Re: sprite collisions « Reply #2 on: Dec 31st, 2009, 09:58am »
 |  |  on Dec 31st, 2009, 08:31am, Richard Russell  wrote:
 | | SPRITELIB doesn't contain any collision detection code (it has been suggested before, but nobody's implemented it AFAIK).  I don't know about GFXLIB; you would need to ask its author. 
 Richard.
 | 
 | 
 
 GFXLIB provides quite a few routines intended for bitmap (sprite) collision detection.
 
 http://www.bb4w-games.com/gfxlib/gfxlib.html
 
 
 Regards,
 David.
 --
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| admin Administrator
 
 
 member is offline
 
  
 
 
 
 
  
 
 Posts: 1145
 
 | 
|  | Re: sprite collisions « Reply #3 on: Dec 31st, 2009, 10:34am »
 |  |  Quote:
 | | GFXLIB provides quite a few routines intended for bitmap (sprite) collision detection. | 
 | 
 I looked on http://www.bb4w-games.com/gfxlib/reference.html, but couldn't see any routine names which immediately suggested a collision-detection function.  Which are they?
 
 Richard.
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| David Williams Developer
 
 member is offline
 
  
 meh
 
 
 
  
 Gender:
  Posts: 452
 
 | 
|  | Re: sprite collisions « Reply #4 on: Dec 31st, 2009, 6:56pm »
 |  |  on Dec 31st, 2009, 10:34am, Richard Russell  wrote:
 
 The GFXLIB routines intended for, or oriented towards, collision detection, rely on reading the alpha byte of certain 32-bpp (RGBA) background pixels, or testing if a specified bit is set in the alpha byte. The current publicly available version of GFXLIB (version 1.1.00) provides the following routines for setting or reading alpha values or testing single alpha bits:
 
 ReadAlphaChannel -- Reads alpha value at specified (X,Y) test position
 PlotTestACBit -- Plots a bitmap *and* tests if a specified alpha bit is set
 PlotScaleSetACBit -- Plots a scaled bitmap at the same time as setting a specified bit in the alpha byte of overwritten background pixels
 PlotPScaleSetACBit  -- Practically identical to previous, except remaining alpha bits are preserved (this routine's probably superfluous)
 PlotScaleTestACBit  -- Plots a scaled bitmap and tests if a specified bit is set in the alpha byte of at least one overwritten background pixel
 TestPixelACBit -- Tests if a specified alpha bit is set in a pixel at position (X,Y)
 ShapeTestACBit -- Uses non-zero-valued pixels of a bitmap as a collision mask, similar to PlotTestACBit except nothing actually plotted
 ScaleShapeTestACBit -- Similar to previous, but for scaled collision masks
 
 The forthcoming version 1.3 will include these additional related routines:
 
 PlotSetACBit -- Plots a bitmap and sets specified bit in alpha byte of any overwritten background pixels
 PlotSetACBit2 -- Doesn't plot 'visible' pixels, but sets specified alpha bit based on non-zero-valued pixels of an 8-bpp mask bitmap
 PlotSetACBit3 -- Similar as previous, except uses a 32-bpp mask
 PlotScaleSetACValue -- Plots a scaled bitmap, setting alpha bytes of overwritten pixels to some specified value
 PlotRotateSetACValue -- Similar, but for rotated bitmaps
 PlotRotateSetACBit -- ...for rotated bitmaps
 
 There are a few more to come.
 
 Correct use of these routines allows for fast, pixel-perfect (or at least sufficiently accurate) collision detection.
 
 
 Here's a program which demonstrates the basic use of  the routine ReadAlphaChannel (this should run if GFXLIB v1.1.00 is installed):
 
 Code:
       REM. Demonstrate use of ReadAlphaChannel
      REM. Should be compatible with GFXLIB version 1.1.0
      
      M% = 3 : HIMEM = LOMEM+M%*&100000
      MODE 8 : OFF
      INSTALL @lib$+"GFXLIB" : PROCAutoInit32
      
      REM. Set bit 0 in the alpha byte of every non-zero pixel in
      REM. the pre-defined 64x64 32-bpp 'demo' bitmap
      REM. (This rather tedious preparatory step isn't necessary in
      REM. GFXLIB v1.3 or later)
      dispVars.bmBuffAddr% = demoBm32%
      dispVars.bmBuffW% = 64
      dispVars.bmBuffH% = 64
      SYS GFXLIB_PlotOR, dispVars{}, demoBm32%, 64, 64, 0, 0, 1<<24
      SYS GFXLIB_QuickSetDispVars, dispVars{}, dibSectionAddr%
      
      REM. Set up structured array of sprite object params
      numObjs% = 100
      DIM obj{( numObjs%-1 ) active%, x%, y%, xv%, yv%}
      
      REM. Define initial sprite positions and velocities
      FOR I% = 0 TO numObjs%-1
        obj{( I% )}.active% = TRUE
        obj{( I% )}.x% = RND(640 - 64)
        obj{( I% )}.y% = RND(512 - 64)
        obj{( I% )}.xv% = RND(3)-2
        obj{( I% )}.yv% = RND(3)-2
      NEXT I%
      
      *REFRESH OFF
      
      REPEAT
        SYS GFXLIB_Clr, dispVars{}, &000040
        
        MOUSE X%, Y%, B%
        X% DIV= 2 : Y% DIV= 2
        
        REM. Draw active objects and update their positions
        FOR I% = 0 TO numObjs%-1
          IF obj{( I% )}.active% THEN
            SYS GFXLIB_Plot, dispVars{}, demoBm32%, 64, 64, obj{(I%)}.x%, obj{(I%)}.y%
            obj{(I%)}.x% += obj{( I% )}.xv%
            obj{(I%)}.y% += obj{( I% )}.yv%
            IF obj{(I%)}.x% < 0 OR obj{(I%)}.x% > 640-64 THEN obj{( I% )}.xv% *= -1
            IF obj{(I%)}.y% < 0 OR obj{(I%)}.y% > 512-64 THEN obj{( I% )}.yv% *= -1
          ENDIF
        NEXT I%
        
        REM. If left mouse button pressed, then read the alpha channel value
        REM. at the mouse position (X%,Y%)
        IF B% = 4 THEN
          SYS GFXLIB_ReadAlphaChannel, dispVars{}, X%, Y% TO V%
          
          REM. If V%<>0 then there's a 'collision', so which object is it?
          IF V% <> 0 THEN
            FOR I% = 0 TO numObjs%-1
              IF obj{( I% )}.active% THEN
                IF X% >= obj{(I%)}.x% THEN
                  IF Y% >= obj{(I%)}.y% THEN
                    IF X% < obj{(I%)}.x%+64 THEN
                      IF Y% < obj{(I%)}.y%+64 THEN
                        
                        REM. de-activate object
                        obj{( I% )}.active% = FALSE
                        
                      ENDIF
                    ENDIF
                  ENDIF
                ENDIF
              ENDIF
            NEXT I%
          ENDIF
        ENDIF
        
        REM. Update screen / program window
        SYS "InvalidateRect", @hwnd%, 0, 0
        PROCWait(4)
        *REFRESH
      UNTIL FALSE
 
 
 
 And here's one to demonstrate PlotTestACBit:
 
 Code:
       REM. Demonstrate use of PlotTestACBit
      REM. Should be compatible with GFXLIB version 1.1.0
      
      M% = 3 : HIMEM = LOMEM+M%*&100000
      MODE 8 : OFF
      INSTALL @lib$+"GFXLIB" : PROCAutoInit32
      
      REM. Set bit 0 in the alpha byte of every non-zero pixel in
      REM. the pre-defined 64x64 32-bpp 'demo' bitmap
      REM. (This rather tedious preparatory step isn't necessary in
      REM. GFXLIB v1.3 or later)
      dispVars.bmBuffAddr% = demoBm32%
      dispVars.bmBuffW% = 64
      dispVars.bmBuffH% = 64
      SYS GFXLIB_PlotOR, dispVars{}, demoBm32%, 64, 64, 0, 0, 1<<24
      SYS GFXLIB_QuickSetDispVars, dispVars{}, dibSectionAddr%
      
      REM. Set up structured array of sprite object params
      numObjs% = 100
      DIM obj{( numObjs%-1 ) active%, x%, y%, xv%, yv%}
      
      REM. Define initial sprite positions and velocities
      FOR I% = 0 TO numObjs%-1
        obj{( I% )}.active% = TRUE
        obj{( I% )}.x% = RND(640 - 64)
        obj{( I% )}.y% = RND(512 - 64)
        obj{( I% )}.xv% = RND(3)-2
        obj{( I% )}.yv% = RND(3)-2
      NEXT I%
      
      *REFRESH OFF
      
      REPEAT
        SYS GFXLIB_Clr, dispVars{}, &000040
        
        MOUSE X%, Y%, B%
        X% DIV= 2 : Y% DIV= 2
        
        REM. Draw active objects and update their positions
        FOR I% = 0 TO numObjs%-1
          IF obj{( I% )}.active% THEN
            SYS GFXLIB_Plot, dispVars{}, demoBm32%, 64, 64, obj{(I%)}.x%, obj{(I%)}.y%
            obj{(I%)}.x% += obj{( I% )}.xv%
            obj{(I%)}.y% += obj{( I% )}.yv%
            IF obj{(I%)}.x% < 0 OR obj{(I%)}.x% > 640-64 THEN obj{( I% )}.xv% *= -1
            IF obj{(I%)}.y% < 0 OR obj{(I%)}.y% > 512-64 THEN obj{( I% )}.yv% *= -1
          ENDIF
        NEXT I%
        
        REM. Draw collision test bitmap, checking if alpha bit 0 is set in
        REM. any overwritten background pixels
        SYS GFXLIB_PlotTestACBit, dispVars{}, demoBm32%, 64, 64, X%, Y%, 0 TO V%
        
        REM. If V%<>0 then there's a collision
        IF V% <> 0 THEN
          FOR I% = 0 TO numObjs%-1
            IF obj{( I% )}.active% THEN
              IF X% >= obj{(I%)}.x%-64 THEN
                IF Y% >= obj{(I%)}.y%-64 THEN
                  IF X% < obj{(I%)}.x%+64 THEN
                    IF Y% < obj{(I%)}.y%+64 THEN
                      
                      REM. de-activate object
                      obj{( I% )}.active% = FALSE
                      
                    ENDIF
                  ENDIF
                ENDIF
              ENDIF
            ENDIF
          NEXT I%
        ENDIF
        
        REM. Update screen / program window
        SYS "InvalidateRect", @hwnd%, 0, 0
        PROCWait(4)
        *REFRESH
      UNTIL FALSE
       
 
 The compiled executables can be downloaded from here:
 
 http://www.bb4w-games.com/bb4wprogs/collisiondetection.zip
 
 
 For what it's worth, much of the (generally accurate) bitmap collision detection in my recent game "Crystal Hunter II" was achieved using some of the above-mentioned routines, so they do actually work!
 
 
 Regards,
 
 David.
 --
 
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| David Williams Developer
 
 member is offline
 
  
 meh
 
 
 
  
 Gender:
  Posts: 452
 
 | 
|  | Re: sprite collisions « Reply #5 on: Dec 31st, 2009, 10:22pm »
 |  |  Another example:
 
 http://www.bb4w-games.com/bb4wprogs/plottestalphabit_example.zip
 
 The GFXLIB routine PlotSetAlphaBit is used to draw the 480x128 "GFXLIB" graphic, at the same time setting (quite arbitrarily) bit 5 in the alpha byte of any overwritten background pixel.
 
 Then PlotTestAlphaBit is used to draw the colourful 48x48 disc sprite, whilst also checking if bit 5 is set in the alpha byte of any background pixel overwritten by the disc.  If bit 5 is found to be set at least once, then the red border appears.
 
 Source program below (unfortunately, it requires the as-yet unavailable GFXLIB v1.3 to run it).
 
 
 Regards,
 David.
 --
 
 
 Code:
       REM. PlotTestAlphaBit // Example
      REM.
      REM. Demonstrate use of PlotTestAlphaBit
      REM.
      REM. Parameters:  dispVars{}, bmAddr, bmW, bmH, x, y
      REM.
      REM. PlotTestAlphaBit is an external GFXLIB module
      
      
      REM. Make 3MB of RAM available for this program
      
      M% = 3
      HIMEM = LOMEM + M%*&100000
      
      
      REM. Invoke display mode 8 (dimensions: 640x512)
      
      MODE 8 : OFF
      
      
      REM. Install and initialise GFXLIB core library
      
      INSTALL @lib$ + "GFXLIB13"
      PROCInitGFXLIB
      
      
      REM. Install and initialise required modules
      
      INSTALL @lib$ + "GFXLIB_modules\PlotTestAlphaBit" : PROCInitModule
      INSTALL @lib$ + "GFXLIB_modules\RGBSwap"          : PROCInitModule
      INSTALL @lib$ + "GFXLIB_modules\PlotSetAlphaBit"  : PROCInitModule
      INSTALL @lib$ + "GFXLIB_modules\RectangleOR"      : PROCInitModule
      
      
      REM. Load the graphics
      REM. (they'll be converted to the required 32bpp format by PROCLoadBMP)
      
      PROCLoadBMP( @lib$ + "GFXLIB_media\bg2_640x512x24.BMP", bg%, 0 )
      PROCLoadBMP( @lib$ + "GFXLIB_media\gfxlib_480x128x8.BMP", gfxlib%, 0 )
      PROCLoadBMP( @lib$ + "GFXLIB_media\disc1_48x48x32.BMP", disc%, 0 )
      
      SYS GFXLIB_RGBSwap%, gfxlib%, 480, 128, 2
      
      REPEAT
        
        MOUSE X%, Y%, B%
        
        X% DIV= 2
        Y% DIV= 2
        
        SYS GFXLIB_BPlot%, dispVars{}, bg%, 640, 512, 0, 0
        SYS GFXLIB_PlotSetAlphaBit%, dispVars{}, gfxlib%, 480, 128, (640-480)DIV2, (512-128)DIV2, 5
        SYS GFXLIB_PlotTestAlphaBit%, dispVars{}, disc%, 48, 48, X%-24, Y%-24, 5 TO R%
        
        IF R% <> 0 THEN
          SYS GFXLIB_RectangleOR%, dispVars{}, 0, 0, 640, 16, &FF0000
          SYS GFXLIB_RectangleOR%, dispVars{}, 0, 512-16, 640, 16, &FF0000
          SYS GFXLIB_RectangleOR%, dispVars{}, 0, 0, 16, 512, &FF0000
          SYS GFXLIB_RectangleOR%, dispVars{}, 640-16, 0, 16, 512, &FF0000
        ENDIF
        
        REM. Update the screen / program window
        
        PROCdisplay
      UNTIL FALSE
      
 
 
 |  
| 
|  |  Logged |  
 |  |  |  
| 
| 
| David Williams Developer
 
 member is offline
 
  
 meh
 
 
 
  
 Gender:
  Posts: 452
 
 | 
|  | Re: sprite collisions « Reply #6 on: Jan 3rd, 2010, 9:42pm »
 |  |  We haven't heard back from the OP yet, so perhaps this means I've done a pretty good job at confusing the heck out of him?
  
 Anyway...
 
 The demo program linked-to below shows one idea for implementing collision detection that may work under certain circumstances.
 
 In the demo, when a 'baddy' sprite is plotted, the array index for that baddy is stored in the alpha byte of all background pixels overwritten by the baddy sprite.  So, if the array index is 44, then 44 gets stored in the alpha byte of overwritten background pixels.  Then when it's time to do some collision detection, reading the alpha value (using, say, GFXLIB_ReadAlphaValue) of a background pixel at some position (X,Y) will give either zero (no collision), or the array index of a baddy. So this is a fast, direct and accurate way of doing collision detection.
 
 http://www.bb4w-games.com/bb4wprogs/invaders.zip -- (91 Kb)
 
 Use the Z and X keys to move left and right respectively, and press Enter to fire fireballs at the descending aliens.
 
 This will probably be my last word on this matter, unless someone wishes to discuss it further.
 
 
 David.
 
 |  
| 
|  |  Logged |  
 |  |  |  
 |