Home All Groups Group Topic Archive Search About
Author
14 Oct 2005 3:32 PM
ian
I've written a game engine, everything works fine, but I'd like to speed
up collision detection.
My current approach is as follows:
Find any sprites who's rect's intersect. AND the intersecting section of
the masks of the two touching sprites, use getpixel API call to check
for any coloured pixels.
It works fine, but I can't help feeling it's not optimal. What I was
thinking was perhaps using copymem to paste the BM into a fixed sized
array, or perhaps point a fixed size array at the BM and iterate through
that way. Has anyone had any experience of this? Matt Curland details
some techniques to achieve the latter, but I don't know what a BM looks
like in memory.

Second, I experimented with selectobject(newHDC, existingBM) in an
attempt to reuse the same Bitmap across a large number of sprites, but
it then renders only one sprite. Is there anyway to achieve such
sharing?

Cheers


*** Sent via Developersdex http://www.developersdex.com ***

Author
14 Oct 2005 6:30 PM
Jeff Johnson [MVP: VB]
"ian" <nospam@devdex.com> wrote in message
news:ejef1RN0FHA.3188@TK2MSFTNGP14.phx.gbl...

> I've written a game engine, everything works fine, but I'd like to speed
> up collision detection.

Have you considered asking in microsoft.public.vb.winapi.graphics? Might get
a better response.
Author
14 Oct 2005 6:42 PM
ian
> Have you considered asking in microsoft.public.vb.winapi.graphics?
Might get
a better response.

Didn't know there was one, cheers :)



*** Sent via Developersdex http://www.developersdex.com ***
Author
14 Oct 2005 9:29 PM
Mike D Sutton
> I've written a game engine, everything works fine, but I'd like to speed
> up collision detection.
> My current approach is as follows:
> Find any sprites who's rect's intersect. AND the intersecting section of
> the masks of the two touching sprites, use getpixel API call to check
> for any coloured pixels.
> It works fine, but I can't help feeling it's not optimal. What I was
> thinking was perhaps using copymem to paste the BM into a fixed sized
> array, or perhaps point a fixed size array at the BM and iterate through
> that way. Has anyone had any experience of this? Matt Curland details
> some techniques to achieve the latter, but I don't know what a BM looks
> like in memory.

The easiest way of improving the performance of collision detection to
simplify what it's checking for, in the simplest case just rectangular or
circular/elliptical areas are enough to achieve adequate collision detection
and are a lot quicker to detect.  If you decide you really do need per-pixel
collision detection then presumably you're using both a mask and colour
Bitmap for each of your sprites (if not and you're currently using a
transparent colour in the main sprite bitmap then I would highly recommend
pre-calculating a 1-BPP DDB mask, it will greatly improve rendering
performance.)
To find out whether the sprites collided or not you can create a new 1-BPP
buffer for collision rectangle (i.e. the intersection of the two sprites),
blit the first mask to it using the SrcCopy ROP, then the second on-top of
that using the SrcAnd ROP.  This will have the effect of only leaving white
pixels where both masks are white which should be nice and quick to check
for.  If you're using a 1-BPP DDB for your temporary buffer then you can use
the GetDIBits() API call to retrieve the entire buffer (or if you prefer you
can get a scan-line at a time, not sure if this would really speed up
performance in the long run though) and scan for any non-0 bytes.  If you're
using a 1-BPP DIB for your collision buffer then you have direct access to
the image data and can simply point a VB array at it, there's more
information on this in the GDI article on my site.
As soon as you find a non-0 value then you know the two sprites have
collided and can stop walking the rest of the buffer, you may also want to
keep the collision buffer around rather than re-creating it every time if
performance is really critical.  You would need to re-create it if the
collision area is larger than the existing buffer, but presumably for the
most part it's going to be a pretty small area (unless the sprites are very
large and/or are moving at very high speeds.)  As always with this kind of
thing you'll need to weigh up performance with memory use, since keeping
this buffer around is going to keep memory and GDI objects allocated.

> Second, I experimented with selectobject(newHDC, existingBM) in an
> attempt to reuse the same Bitmap across a large number of sprites, but
> it then renders only one sprite. Is there anyway to achieve such
> sharing?

DDB's can only be selected into a single DC at a time, so I'd suggest that
you're probably not de-selecting the Bitmap from the DC after the first
sprite is done drawing with it.  Try something along these lines instead:

'***
Dim hOldBMP As Long

hOldBMP = SelectObject(newHDC, existingBM)

' Drawing code here

Call SelectObject(newHDC, hOldBMP)
'***

Hope this helps,

    Mike


- Microsoft Visual Basic MVP -
E-Mail: ED***@mvps.org
WWW: Http://EDais.mvps.org/
Author
14 Oct 2005 10:19 PM
ian
Mike, that's perfect, I'm doing exactly as you've suggested, with a 1
bit mask and colour sprite, but hadn't seen GetDIBits before. I
considered circle detection, and I think I'll add it Tomorrow as an
option. Per pixel is optional at the moment as well, as I fully agree
with you when you say rect/circle is generally sufficient.
I'm slightly embarassed I didn't consider reselecting the BM for each
sprite each draw. It sounds so obvious now you've said it, but then so
do Post It notes :) I'll refactor my code to pool discreet BM's and
select from that pool each draw. It should tie in nicely with my current
design which allows a sprite to inherit from a parent and a  group
sprite. It allows me to do fun things like have a squadron of 20
sprites, 10 of which inherit behaviour from one parent and 10 from
another, while still reacting as one team. Anyway I'm waffling. /zip

Many thanks

Ian












*** Sent via Developersdex http://www.developersdex.com ***