Skip to main content

[JAVA2D] Pixel collision in games with 2D api

4 replies [Last post]
Anonymous

Hello list.

Okay, here's the situation: I'm writing a 2D game with pixel collision
in Java. My current design has a graphics front-end, and a "physics
frame" which is a non-displaying buffer the same size as the graphics
region. Each character that the user sees is mapped to a "shadow" in
the physics frame -- a two-bit representation of the character for the
purposes of collision detection. (The two bits signify different parts
of the character -- some pixels are 'collision' pixels, some are
'attack' pixels, and some are both).

Each frame, the physics system walks through the characters and renders
each one onto the physics frame, checking for collisions. Every object
rendered in this way should be able to collide with every other object,
and identify both objects in any collision. I won't ever need to have
more than 16 separately colliding objects at any one time.

I believe the way I want to do this is to render the physics frame in a
32-bit-depth graphics buffer object of some sort, allocate two
different bits for each object, and keep a record of which bits
correspond to which object so that when a collision occurs, I can "look
back" and find out what object set that bit. Each iteration of the loop
would involve shifting the two-bit bitmap to the next free slot, then
transferring it using XOR onto the physics frame. To check for
collisions, I can then do a pixel-by-pixel comparison of the region on
the frame to the shifted bitmap in memory -- anywhere that the bits
don't match, XOR them to find out what's different, and look up those
bits in the record to find out the object I collided with.

Phew.

Now, what I want to know, is how you would go about doing this in Java,
using fast BitBlt routines. I have been digging through awt's
Graphics2D and GraphicsConfiguration, swing's ImageIcon, etc., but
there's just a sheer number of classes that I cannot wrap my mind
around what I need and what I can ignore.

So if someone could help me out -- how do I create a region that I can
do some low-level, fast blt'ing to? Or, if you have a better idea on
how I should implement my physics that takes better advantage of Java,
some ideas about that would be good too.

Thank you,

Lincoln Quirk

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jim Graham

Hi Lincoln,

One of the problems you may run into is that we only have routines that
handle image formats that we recognize, whether accelerated or not. Thus,
if you create some kind of custom 32-bit format you would end up causing us
to invoke our general custom-format routines which use all of the
high-level pixel getting and setting method calls in Raster and
BufferedImage. You would do better to do the blits yourself in that case.

So, if you want to stick with a built-in format, you would be best off with
INTEGER_RGB which only has 24 bits to work with. If you use INTEGER_ARGB
you then run into the strange way that we manipulate alpha in our XOR
routines which does not do what you might expect. It might be possible to
work around that, but I would avoid it if you can.

Another thing to consider is that if you use a format that is hardware
accelerated then the pixel readback will be *VERY* slow on many platforms.
If you plan to search for collision pixels I would recommend using a
software surface since the readback from a hardware surface will more than
offset any performance gains you get in drawing the figures.

Someone else mentioned using bounding boxes first as a collision detection
technique and then only use bitmaps if you need them. If you do it that
way then you are always doing a detection between A and B and you only
really need 2 bits (one for A's body and one for B's weapon) and could use
a byte format such as ByteGray. A software XOR of byte images should be
pretty fast, especially since it is only needed when the bounding boxes
collide...

...jim

--On Tuesday, July 13, 2004 10:56 PM -0400 Lincoln Quirk

wrote:

> Hello list.
>
> Okay, here's the situation: I'm writing a 2D game with pixel collision
> in Java. My current design has a graphics front-end, and a "physics
> frame" which is a non-displaying buffer the same size as the graphics
> region. Each character that the user sees is mapped to a "shadow" in
> the physics frame -- a two-bit representation of the character for the
> purposes of collision detection. (The two bits signify different parts
> of the character -- some pixels are 'collision' pixels, some are
> 'attack' pixels, and some are both).
>
> Each frame, the physics system walks through the characters and renders
> each one onto the physics frame, checking for collisions. Every object
> rendered in this way should be able to collide with every other object,
> and identify both objects in any collision. I won't ever need to have
> more than 16 separately colliding objects at any one time.
>
> I believe the way I want to do this is to render the physics frame in a
> 32-bit-depth graphics buffer object of some sort, allocate two
> different bits for each object, and keep a record of which bits
> correspond to which object so that when a collision occurs, I can "look
> back" and find out what object set that bit. Each iteration of the loop
> would involve shifting the two-bit bitmap to the next free slot, then
> transferring it using XOR onto the physics frame. To check for
> collisions, I can then do a pixel-by-pixel comparison of the region on
> the frame to the shifted bitmap in memory -- anywhere that the bits
> don't match, XOR them to find out what's different, and look up those
> bits in the record to find out the object I collided with.
>
> Phew.
>
> Now, what I want to know, is how you would go about doing this in Java,
> using fast BitBlt routines. I have been digging through awt's
> Graphics2D and GraphicsConfiguration, swing's ImageIcon, etc., but
> there's just a sheer number of classes that I cannot wrap my mind
> around what I need and what I can ignore.
>
> So if someone could help me out -- how do I create a region that I can
> do some low-level, fast blt'ing to? Or, if you have a better idea on
> how I should implement my physics that takes better advantage of Java,
> some ideas about that would be good too.
>
> Thank you,
>
> Lincoln Quirk
>
> =========================================================================
> ==
> To unsubscribe, send email to listserv@java.sun.com and include in the
> body
> of the message "signoff JAVA2D-INTEREST". For general help, send email to
> listserv@java.sun.com and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Jim

That sounds complicated. Why not use bounding boxes as a rough first
shot at collision detection and then use a finer grain approach when the
bounding boxes collide. Using video memory for collision detection does
not seem like a good idea to me.

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Keith Lea

If you're targeting JDK 1.5, you can use an accelerated BufferedImage
instantiated from a GraphicsConfiguration (with the
createCompatibleImage method), which is stored in memory but also cached
in your video card's VRAM. I'm not sure what "blting" is, but
BufferedImage probably provides the fastest and easiest way to copy
image data to other BufferedImages and to the screen.

If you need JDK 1.4 compatibility, you should use VolatileImage,
probably backed by a BufferedImage (which is not, in 1.4, stored in
VRAM). VolatileImages are stored in VRAM like 1.5's accelerated
BufferedImage.

(You could also use VolatileImage in 1.5, but for most applications it's
not worth the extra code required when BufferedImage is mostly just as
fast.)

-Keith

Lincoln Quirk wrote:
> So if someone could help me out -- how do I create a region that I can
> do some low-level, fast blt'ing to? Or, if you have a better idea on
> how I should implement my physics that takes better advantage of Java,
> some ideas about that would be good too.
>
> Thank you,
>
> Lincoln Quirk

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Chet Haase

Keith's right on the general ideas of Volatile vs. BufferedImage
acceleration, but let me correct/clarify some of the details:

- GraphicsConfiguration.createCompatibleImage() will create a
VRAM-cached accelerated copy of the BufferedImage and you will
benefit from hardware acceleration as available on 1.4. This was
not something new in 1.5, but has been there since 1.5. Other
"managed image" APIs that create this acceleratable cached version
of the image include Component.createImage(w,h) and (I think)
Toolkit.loadImage()/(new ImageIcon()).getImage().

- New in 1.5 is the ability to get a managed image from _any_ image
creation method, including new BufferedImage(w, h, type). Same
acceleration functionality as described above, but now you don't
have to call particular APIs to get that capability.

- The main reason for dealing with VolatileImages is if you need/want
rendering _to_ the image to be accelerated, or if you will be modifying
the image frequently but still want copies from the image to be accelerated.
A common case for this is back buffers; the Swing back buffer is a
VolatileImage.
Otherwise, managed images (as described above) are way less hassle but
have the
same benefits of fast copies (Blts).

For more nitty gritty details on BufferedImage and VolatileImage objects
and random acceleration tips, check out the BufferedImage and VolatileImage
blogs on javadesktop.org.

Chet.

Keith Lea wrote:

> If you're targeting JDK 1.5, you can use an accelerated BufferedImage
> instantiated from a GraphicsConfiguration (with the
> createCompatibleImage method), which is stored in memory but also cached
> in your video card's VRAM. I'm not sure what "blting" is, but
> BufferedImage probably provides the fastest and easiest way to copy
> image data to other BufferedImages and to the screen.
>
> If you need JDK 1.4 compatibility, you should use VolatileImage,
> probably backed by a BufferedImage (which is not, in 1.4, stored in
> VRAM). VolatileImages are stored in VRAM like 1.5's accelerated
> BufferedImage.
>
> (You could also use VolatileImage in 1.5, but for most applications it's
> not worth the extra code required when BufferedImage is mostly just as
> fast.)
>
> -Keith
>
> Lincoln Quirk wrote:
>
>> So if someone could help me out -- how do I create a region that I can
>> do some low-level, fast blt'ing to? Or, if you have a better idea on
>> how I should implement my physics that takes better advantage of Java,
>> some ideas about that would be good too.
>>
>> Thank you,
>>
>> Lincoln Quirk
>
>
> ===========================================================================
>
> To unsubscribe, send email to listserv@java.sun.com and include in the
> body
> of the message "signoff JAVA2D-INTEREST". For general help, send
> email to
> listserv@java.sun.com and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".