BBC BASIC for Windows
« sprite collisions »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 10:58pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: sprite collisions  (Read 972 times)
leslie griffin
Guest
xx 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...
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
--
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: sprite collisions
« Reply #4 on: Dec 31st, 2009, 6:56pm »

on Dec 31st, 2009, 10:34am, Richard Russell wrote:
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.


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.
--
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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
      
 


User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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? embarassed

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.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls