views:

888

answers:

3

Hi all, I've been happily coding an opensource game for fun, but i just realized that Graphics.setColor() doesn't understand 0xAARRGGBB... I want to get a more and more transparent colour, in which I'd draw some arcs (discs). My goal was to make them shine though each other like in this image: http://kenai.com/projects/xplode (the logo there)

I know that transparency manipulation is possible with images (getRGB etc) yet this proves very slow for a game with lots of size and transparency changes...

Is there any way i could draw transparent scalable discs in J2ME, without using JSR 184 nor JSR-226? I fear that there is now "good" way to deal with it and I'll just go on without this effects, but why not ask when in need... :-/

Thanks a lot for any advice in advance.

A: 

I am not sure if you can do such a thing in a reasonably efficient manner using the Graphics class alone. Why don't you try OpenGL ES Specification for MIDP JSR 239?

Ram
+2  A: 

Transparency stuff doesn't need to be slow as long as you keep it to a minimum and stay away from very old handsets. You should also note that alpha is sometimes ignored on some implementations and sometimes quantized to ugly levels (Some motorola phones snap alpha values to the nearest 2-bit value. Bleh).

I'd be tempted to approach this as a single transparent layer superimposed onto the screen. Keep an int array the size of your screen into which you will plot your transparent pixels (int[width * height]). On each frame, make a call to Image.createRGBImage and draw that image to the screen.

As an experiment, you might first want to make sure that the alpha processing isn't going to slow you down by filling this array with a constant value and plotting that to the screen. E.g. 0x80FF0000 should blend a red tint onto the screen and you can see easily if this alpha business is going to be workable on your chosen handset, i.e you can measure how it impacts your frame rate.

Next you need to plot circles into this array. Look for Bresenham's circle drawing algorithm and rework it to plot into an int array of pixels. You might want to maintain a lookup table that has a pre-calculated radius/sqrt(2) for each radius you want to be able to plot.

Next is how to blend colours to get them to overlap. The simplest would be just to plot a colour value with alpha into the pixel. You wouldn't get colour blending with already plotted circles but it would be cheap and the circles would blend with the background.

Another method would be to ignore the colour blend but to do a simple merge on the alpha. E.g.

newColour = ((destColour & 0xFF000000) + 0x20000000) | srcColour;
/* Where source colour is of the form 0x00RRGGBB. Note: Adding 0x20 to alpha each
 * time will only work for 7 overlapping circles. */

The colour of the overlapping circle would dominate the underlying one, but the alpha would become more opaque where they overlap which would at least allow the player to see all the circles properly.

If you wanted to do an accurate colour blend then the calculations are a lot more complicated, especially if you're blending one value with alpha onto another with alpha since the colour contributions from each pixel vary with the proportion of alpha in each colour. It's not impossible but making it efficient is a pain. I'd be tempted to go for a cheaper option.

izb
Great idea, thanks! I'll write some sample code right away to test if the devices can handle such an approach.
ktoso
A: 

Instead of creating images each frame with createRGBImage() you can try using getRGB() and drawRGB()

Pavel Alexeev