Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Cutting bitmaps into separate bitmaps.

This thread is locked; no one can reply to it. rss feed Print
Cutting bitmaps into separate bitmaps.
Gnamra
Member #12,503
January 2011
avatar

Let me clarify what I mean by cutting bitmaps into separate bitmaps. Say you have drawn a boss, and the player is equipped with a laser. With this laser the player will be able to cut off parts of the boss, slicing the boss with the laser.

The cutting part is easy, but how would you identify the part that was cut off and store that part in a different object with a new bitmap containing the cut off arm.

Example:

Player cuts off the boss' arm, because of magic the arm is still functional and it will continue shooting, bouncing all over the place and making a mess off everything due to the recoil of the gun.

Could anyone perhaps suggest a way to do this? Or perhaps you know of a site that touches on the subject.

Edit: I think I might have solved it, if anyone is interested I can post the solution when it's done and if it works.

Jeff Bernard
Member #6,698
December 2005
avatar

I would probably do something like this:

#SelectExpand
1 // pseudo-code 2class Boss { 3 vector<BossBodyPart> parts; 4 void update() { parts.all.update(); } 5 void draw() { parts.all.draw(); } // perhaps draw is sorted somehow 6 void hit(where) { parts.all.hit(where); } 7} 8 9class BossBodyPart { 10 BossBodyPart parent; 11 int hp; 12 Bitmap bitmap; 13 void update() { 14 if (hp > 0) { 15 if (!parent) { // body part has been detached 16 flailAround(); 17 } else { // body part is still attached 18 positionRelativeToParent(); 19 } 20 attackOrWhatever(); 21 } 22 } 23 void draw() { 24 if (hp > 0) { // maybe you still want to draw the lifeless body part 25 bitmap.draw(); 26 } 27 } 28 void hit(where) { 29 if (where overlaps me) { 30 hp -= damage; 31 if (shouldDetach) { 32 parent = null; 33 } 34 } 35 } 36}

Basically, this boss character is actually a composite of characters. The characters can only move if their root isn't attached to anything (parent == null), so in the initial state, maybe the Boss's torso would be unparented and his arms/legs/head would attach to the torso. This way, I wouldn't need to worry about storing body parts in new objects, since they were in separate body parts from the start.

Also they would have been separate bitmaps to begin with.

Additional logic may be needed in places (like if you wanted some body parts to not be hittable until others have been separated). It may be beneficial to have separate child classes for each of your different body parts, as well.

EDIT-- Unless you meant arbitrary cutting, which case this isn't a very good solution.

--
I thought I was wrong once, but I was mistaken.

Gnamra
Member #12,503
January 2011
avatar

Yepp, I meant arbitrary cutting. I think I've got it sorted though.

Jeff Bernard
Member #6,698
December 2005
avatar

So what's the solution you thought up? It's not a problem I've thought of much (personally I think the pre-defined cuts potentially has more benefits, ensuring that every cut is a good cut), but I guess for part identification, I might have some pre-defined masks of common body parts. Then when a part is cut-off, try and match the part to one of the masks. There's probably a better way than that, though, like some sort of heuristic counting area/curves in the body part.

--
I thought I was wrong once, but I was mistaken.

Gnamra
Member #12,503
January 2011
avatar

I haven't had the time to work much on it yet, but I found the equation for the line and used that equation to find where the line hits the bitmap, and where it comes out.

That was how far I got when I did the testing, I might do some more today.

After finding the two points, you can use one of those to create a new bitmap and copy the information on either side of the two points. It's easiest when it's a clear cut and you end up with rectangles on both sides of the line, since you wont have any excess information being copied.

To be clear, I'll be using the point that is furthest away from the side the other point is closest to and use that point to copy out a rectangle of the bitmap.

I've attached a png of a bitmap where the line is a bit slanted(if that's the correct word).

As you can see, the copying will copy more than we want, but we can easily draw a rectangle over that area we don't want to use and then make it transparent. We then have the cut off part stored in a new bitmap ready to be used.

We also do the same to the original bitmap, make the "cut off" part transparent. I was thinking about just using al_draw_filled_rectangle and al_draw_filled_triangle and then al_convert_mask_to_alpha using the color I drew the triangle and rectangles with. But I suspect there might be a better way to do it. I don't know if you can use al_map_rgba with the primitives?

But in summary, figure out the points using the equation of the line. Determine if the line is slanted which will result in excess information being copied and make the excess area transparent. Then make the "cut off" area of the original bitmap transparent.

I'm sorry if my explanation was a bit convoluted, English isn't my first language so it's a bit hard to explain.

Edit: On the image, I was going to use the width and hight to explain something, but I didn't. You can ignore those.

Edgar Reynaldo
Member #8,592
May 2007
avatar

I think you can still draw a transparent area with the primitives if you just set the right blending mode.

int oldop = 0;
int oldsrc = 0;
int olddest = 0;
al_get_blender(&oldop , &oldsrc , &olddest);
al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO);

/// Draw transparent bits here

// clean up when done
al_set_blender(oldop , oldsrc , olddest);

And yeah, use al_map_rgba(0,0,0,0) to write transparent black.

Go to: