Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Masking

Hello!

I need help, I'd like to know, in your opinion, what would be the best way to make a masking script?
For those who don't know what masking are, here's an exemple.
First of all, you need a bitmap to be masked:
http://img127.imageshack.us/img127/2880/exemple1bh5.png[/IMG]

You also need another bitmap which defines what part of the first bitmap will be masked:
http://img131.imageshack.us/img131/9850/maskic8.png[/IMG]
The section in white starts transparent, the red circle defines what will be visible from the first bitmap.

The result will be:
http://img127.imageshack.us/img127/9831/exemple2mv4.png[/IMG]

Applied on a map, for exemple:
http://img83.imageshack.us/img83/1572/resultrg4.png[/IMG]

Another good exemple, the X-Ray from Super Metroid:
http://www.nintendomaniacs.com/images/u ... _scope.png[/IMG]http://metroid.homestead.com/files/pictures/super/visors.jpg[/IMG]

I thought i could use the get_pixel method but it's to slow for larger pictures. It gives me a "Script is hanging" error every times.
So, I need help! Does someone have any idea on how to do it?

Thanks!

-Dargor
 

Mac

Member

I think the best way to do this would be with an event, give it two pages and make one apply when hit with the beam in the case of Metroid, this would require a fair amount of scripting as you would have to create a view range that would activate it.
 
Interesting problem, let me think of it...

EDIT : I found nothing. Sprite.blend_type won't be useful here...
My personal recommendation, if you don't want to use get/set_pixel (can be improved with a recursive blt, by the way) is to use an external binary. Imagemagick is quite perfect for the job. The only downside (beside the size) is that there will be a flashing terminal when executed, but I think there's ways to prevent it from being displayed.
 
I'll take a look at Imagemagick, it sounds interesting.
But I'll try something which should prevent the script from hanging.

First of all, I'll get the x/y/width/height of the mask bitmap.

I will then use src_rect.set(x,y,width,height) on the source bitmap so it will be resized to the same size of the mask bitmap (and should also be placed at the same x/y specified by the mask sprite). It will reduce the number of pixels to get/set.

I'll use a specific color to determine the transparent and the mask zone (probably black & white) so when a pixel is white on the mask sprite, it will be transparent (alpha 0) on the source sprite. Obviously the mask sprite will always be invisible.

I wonder what will happen when updated, lol. I hope it will not hang once again.

What do you think about it?

EDIT: Hey, aren't transitions working like this? I mean, aren't they setting the screen opacity or visibility depending on the pixel's shade?
 
As PNG is RGBA (notice the alpha channel), you could use the latter to create non-binary masks but blending masks as well.

After you have used src_rect.set, you should find the optimum way to draw masked bitmap.

If the mask is a circle/ellipse, the optimal algorithms are well known : http://enchantia.com/software/graphapp/doc/tech/ellipses.html

If you want to do something more complex, you might read in advance the number of same 'color' pixels, and use blt after, it might be less cost intensive than set_pixel. And start from an empty bitmap instead of trying to remove the transparent parts (due to the probable shape of your mask)

Example :
0010001 read 0010, blt 1, read 001, blt 1
0111011 read 01110, blt 111, read 11, blt 11
0010100 read 0010, blt 1, read 10, blt 1, read 0

But imagemagick is waaay faster and powerful.
 
Umm... Instead of making all that tiring pixel codes, why not making a dummy image with only the alpha layers defined? Like, in areas you want to erase just make the pixel?s alpha equal to 255. It?s easy to do png files with transparency defined in Photoshop (and even in other programs). Then, load the normal bitmap, the mask bitmap and blt the two
Code:
bitmap = RPG::Cache.picture("bitmap")
mask = RPG::Cache.picture("mask")
x = y = 0
bitmap.blt(x, y, mask, mask.rect)

And surely, if you want to do that with sprites, it will be a whole different thing...
 
The problem is, if I recall well, blt doesn't act on the RGBA values : it works on the RGB values, and blend depending on the Alpha channel.

For example, a fully transparent picture blt'ed on another one will do nothing.

EDIT : I'm not so sure, in fact, but can't test right now. It wouldn't solve the problem anyway, as you couldn't make a zone not to be copied, so the mask would completely "erase" the picture : if alpha is 255, the area will be transparent, if alpha is 0, the area will be black.
 
And surely, if you want to do that with sprites, it will be a whole different thing...

Can't I simply use sprite.bitmap?

I tried the get/set pixel and src_rect.set methodes and it works fine but it's incredibly slow when I update it. I'll try with the blt methode but I think rataime's right.

EDIT:
Linkin_T method won't work, as it will just take the rectangle from the "mask", not the alpha values.

I have my answer. :)
 
I'm not sure what this "get_pixel" method is, but if big images are a problem, why can't you just set up a bunch of smaller images.

The metroid games used tiles like everything else of the age and everything that you could use that x-ray on was just two-layed tiles. So, why not set up 32x32 tiles, just like the tile map, and use the "get_pixel" system or whatever?

I might have another idea, but I'll have to do some research first.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top