| Reply | « Previous Thread | Next Thread » |
|
I'm using multiple Image classes, with transparency, to provide layers in my series 40 game. I'm having trouble animating on my sprite layer; the sprite smears itself across the Image as it moves.
The problem is that I can't erase the Image/layer in between sprite paints. That is, I can't re-fill the Image with transparent pixels. I can erase to white but of course my background layer becomes occluded. static final int COLOR_TRANSPARENT = 0x00FFFFFF; // // Create a transparent Image to serve as sprite layer // Image spriteLayer = DirectUtils.createImage(width, height, COLOR_TRANSPARENT); .... // // Erase sprite layer, then redraw sprite in new location // g = spriteLayer.getGraphics(); dg = DirectUtils.getDirectGraphics(g); dg.setARGBColor(COLOR_TRANSPARENT); g.fillRect(0, 0, width, height); // <-- this does nothing // // The fillRect() should have cleared my layer to transparent // but it didn't have any effect. My old sprite is still there. // I thought I could use DirectGraphics to set the color to transparent, then fillRect() and it would "just work." But apparently it just skips the fillRect(), which I guess makes sense if my pen color is transparent. How can I erase/fill with transparency? Thanks. |
|
skelleher
I thought I could use DirectGraphics to set the color to transparent, then fillRect() and it would "just work." But apparently it just skips the fillRect(), which I guess makes sense if my pen color is transparent It works perfectly just as it should, fills rectangle of Graphics conext with a transparent color. Imagine the whole procedure: 1. There was some background 2. You painted sprite over it CHANGING color of some pixels, not painting somehow OVER them 3. Then you try to paint over it with invisible color. Of course it doesn't change anything If you want to restore screen as it was before your sprite, you should preserve previous picture somehow: either by knowing how to repaint just this small part of the screen, or storing this small screen part somewhere and then copying it back. |
|
What I'm doing for the time being is following the MIDP 2.0 model. I'm creating a "layer" that is just the size of the sprite itself, and moving the entire layer to new x,y as the sprite moves. Every sprite is its own layer, and the entire display is erased to white and then redrawn completely from frame to frame. /shrug/
So this way, I'm never redrawing the sprite on a sprite layer - I'm drawing the sprite once and just moving the whole layer and then repainting the entire screen. I don't really like it conceptually, but it works. |
|
Sorry, I thought you were talking about MIDP 1.
I haven't done any project for NIDP 2 yet. Hence, I can only advise you something general like chicking that you are subclussing Sprite, not generic Layer. |
|
Sorry - I _am_ developing for MIDP 1.0. :-) I meant that I am writing my own Layer and Sprite classes which basically are API-compatible with MIDP 2.0. Why go in the wrong direction, right?
|
|
Then, please reread my post. If you are painting all your layers on the same canvas without full repainting, then.. then reread :) , I believe it actually answers your question.
|
|
Thanks DoctorDwarf, you were exactly right.
I was unaware of the getPixels()/drawPixels() routines, which do allow me to read a piece of the screen and then restore it later. Very useful. I have to use TYPE_USHORT_4444_ARGB for this - do people just hard-code that and assume all series 40/60 phones will support it? Standard practice? When I do a getNativePixelFormat() it returns TYPE_USHORT_444_RGB which is "safe" but useless for transparency. Thanks again. |
|
Actually I'd still like to erase a region with transparent pixels at runtime, and even drawPixels() can't do that for me.
Example: I create a transparent Image on wich I draw the current score and other HUD data. I make this the top layer of my game, with the sprites and such beneath it. When I update, I need to erase the score from the layer, and redraw the new score. I can't erase those drawn pixels. I can't save the transparent pixels in an array and then use drawPixels() to restore them. I thought calling drawPixels() with transparency=false (ignore transparency) would copy the raw pixels into the image. But no, it simply drops the transparency bits, turing 0x0FFF into 0xFFF. short pixels = new short[w * h]; // // Fill array with transparent pixels // for (int i = 0; i < pixels.length; i++) { pixels[i] = 0x0FFF; } // // Draw the pixels into the layer, effectively erasing it // dg.drawPixels(pixels, false, 0, 128, 0, 0, 128, 128, 0, DirectGraphics.TYPE_USHORT_4444_ARGB); This "ignores" the transparency bits all right -- it fills the destination with 0xFFF instead of 0x0FFF! So I get a white Image instead of a transparent one. Is modifying the raw pixels just not possible in MIDP 1.0? It bugs me that the "raw" drawPixels() still supports transparency semantics. It should just copy the numbers. |
|
skelleher
I have to use TYPE_USHORT_4444_ARGB for this - do people just hard-code that and assume all series 40/60 phones will support it? Standard practice? There is somewhere in documentation list of formats that MUST be supported by any Series40/Series60 phones. I am not completely sure, but I think TYPE_USHORT_4444_ARGB is one of those formats. Even the only mandatory with transparency. Check it from docs and post result here :) Actually I'd still like to erase a region with transparent pixels at runtime Hei, you changed some meaninful bits (not only ones responsible for transparency) on Canvas, right? How would you ask it to "remember" its previous stage? Lets have a closer look: 1.I create a transparent Image on wich I draw the current score and other HUD data. I make this the top layer of my game, with the sprites and such beneath it. Ok, now on your 2 dimensional canvas some color bits changed to bits from scores image. You remember, that there are no actual layers in MIDP 1.0, just simple matrix of pixels, dont you? 2. When I update, I need to erase the score from the layer, and redraw the new score. I thought calling drawPixels() with transparency=false (ignore transparency) would copy the raw pixels into the image. But no, it simply drops the transparency bits, turing 0x0FFF into 0xFFF Why would it? Where would it get those raw pixels? You overwritten them. Should drawPixels() somehow magically realize before which paint() there were raw pixels, and after which there are new ones? You requested to paint something invisible, you painted nothing. Please, understand that in fact there is no such a thing as transparent pixels on a Canvas. There should be something visible all the time, phone screen shows some color all the time. Transparency is applied in the process of painting a new image over existing canvas, not later. |
|
P.S.
To simplify your issues people invented MIDP 2.0 layers idea :) In MIDP 1.0 you have to implement this functiuonality by yourself. |
|
> You requested to paint something invisible, you painted
> nothing. Yes that's the problem - I want a method putPixels(), instead of drawPixels(), that knows nothing of "transparency" and just lets me edit the bits. I want to write directly to the bits in the Image to create transparent pixels by hand. This would be trivial in C/C++. > Please, understand that in fact there is no such a thing as > transparent pixels on a Canvas. There should be something > visible all the time, phone screen shows some color all the time. Correct - there are no transparent pixels on a Canvas. But there are transparent pixels in the Image before it is drawn to the Canvas. I am drawing on the Image, and it is the Image I want to erase. I should be able to Image.getPixels()/putPixels() to turn pixels off and on at will before drawing them to the Canvas. :-) I guess I have to use crude methods until I move to MIDP 2.0. A series 40 can't support multiple 128x128 layers anyway - not enough heap memory. Thanks, Sean |
| Reply | « Previous Thread | Next Thread » |
| Thread Tools | Search this Thread |
|---|---|