views:

141

answers:

7

I'm quite new to the world of 2D-Engines. I figured out how to load images and display those as sprites and stuff, but theres one question that bugs me. For instance, when a "rocket" hits an object it will deal damage to it and leave a crater behind. I'd like to have the crater shown on that object. That would require "skipping" some of the pixels of that image when rendering, doesn't it? My question is, how would you do such a thing? What data strcture would you use to save this? How to display a "broken" sprite?

+2  A: 

For some situations, you can simply draw another sprite on top of the original sprite. Alternatively, you can switch between different sprites depending on the state of the object.

Brian Rasmussen
+3  A: 

Create a sprite sheet.

This will contain all the spirites your object, in this case the rocket. Some of these images would be of the rocket smashing into many pieces, fire etc...

Then when your object hits, you play the collision animation. Your method would technically work, but it's overkill. Using a sprite sheet is simple, rather than drawing a massive image, you just draw a portion of the sheet, and to play the animation increment in the X an Y axis of the sheet. This naturally requires the sheet to be layed out even, but it's not too much work.

Finglas
A: 

Thanks for your answers, but both of you probably misunterstood me (it's quite hard to explain). The problem is displaying the crater itself "in" the sprite, not the animation or something. Objects do not get destroyed on hit, only altered. For example, a sprite in the form of a planet gets hit by a rocket: It won't get destroyed, but a crater is left behind --> something of that planet is now missing. I want to display the sprite without that missing part. I can't draw another sprite on top of the original sprite because it's meant to be highly flexible, one object could get hit by serveral rockets leaving craters of different size, even craters in craters.

Roman
A: 

Slow, but probably fast enough.

public static void Fill(this Texture2D t, Func<int, int, Color> perPixel)
        {
            var data = new Color[t.Height * t.Width];
            for (int y = 0; y < t.Height; y++)
                for (int x = 0; x < t.Width; x++)
                {
                    data[x + (y * t.Width)] = perPixel(x, y);
                }
            t.SetData(data);
        }
Bengt
A: 

I was working on something like this on a mobile Java game, a worms/scorched earth clone (actually based on GunBound).

You don't "skip" the pixels in order to leave a crater. You change the pixels in your planet's bitmap, so the crater is now a permanent part of your planet. I assume you know all about bitmaps, blitting transparent, and hit testing.

To create a crater I used a circle-fill algorithm and filled the "explosion area" with the background or transparent color.

So when doing hit-testing you have to do it twice. A bounding-box hit test for speed, then a per-pixel hit test when then bounding boxes overlap.

EnderWiggin
A: 

I see you have tagged this with XNA, so assume that is your API (though this answer could well be applied to any OpenGL/D3d approach with appropriate calls). If you want to do this in an elegant fashion, I suggest using a temporary RenderState. You would switch to the new RenderState and draw your original background texture, then draw crater sprites over the top (you can modify the AlphaSourceBlend and AlphaDestinationBlend properties of the RenderState to create the subtractive effect you are looking for).

Once you have finished drawing, you can retrieve the RenderState as a texture easily using the GetTexture() function.

Keep in mind that if you are changing the blend modes, your SpriteBatch should be performing in the "immediate" mode (I forget the XNA term, but the one where it doesn't do ordering of sprites for efficiency) else it will be reset unexpectedly.

peppy