Transparency Overlay

Previous topic - Next topic

bigtunacan

I am trying to do a space invaders style game and have buildings at the bottom of the screen.  When a bomb drops and hits the building I want to make a piece of it disappear.  My thought was to try to overlay a solid colored image over each section that has been destroyed and have that color set to transparent so the background will show through.  I was trying to test this with the drawrect, but this does not appear to take transparency?  Is this correct?  What are some ideas on how to do this?

Ian Price

Do you mean like the bases in Space invaders, or like Blitz (my version, shown below)?


If you mean Space Invaders, then I would create a virtual screen, make it magenta, then draw the base sprite onto that. Then use rect, setpixel or even polyvector to draw a hole in magenta on top. Then you can use this sprite as the base.

If you mean like Blitz, then simply draw each building using a series of block sprites and remove as destroyed.
I came. I saw. I played.

spacefractal

drawrect is a bad command for use for mobile use, since its can been bad implemented on some systems (like Android). I would use Polyvector instead of drawrect.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

bigtunacan

Ian,

I'm trying to do more like Space Invaders where the building takes more of a spread damage.  I am new to GLBasic; I'm not familiar with the virtual screen you are referring to?

Quote from: Ian Price on 2011-Sep-09
Do you mean like the bases in Space invaders, or like Blitz (my version, shown below)?


If you mean Space Invaders, then I would create a virtual screen, make it magenta, then draw the base sprite onto that. Then use rect, setpixel or even polyvector to draw a hole in magenta on top. Then you can use this sprite as the base.

If you mean like Blitz, then simply draw each building using a series of block sprites and remove as destroyed.

MrTAToad

A virtual screen is created using CREATESCREEN, which you can then write too and then place onto the back buffer.

If you dont want use that, the other way would be to split the building into tiles and its sprite ID is store into an array - then, if the relevant section is hit, you replace the sprite number with something else.

bigtunacan

@MrTAToad,

Thanks.  I was able to use CREATESCREEN as you suggested. I'm then using a 2 color BMP image to block out part of the original image.  For the most part this seems to work, but I need to save out the image using SAVESPRITE and reload it back it as damage continues to build up.  I notice that in the SAVESPRITE and re-load the image seems to be picking up some jaggies around the edges where it is possibly not encoding exactly right?

Here is some temporary code I created to try and test this out.
Also, I noticed that SAVESPRITE is encoding transparency as RGB(255, 0, 128) even though the default color for transparency when loading is RGB(128, 0, 255)

Code (glbasic) Select

FUNCTION tmp_foo:
CREATESCREEN 0, 13, 128,128
// Use screen for all output
USESCREEN 0
   DRAWSPRITE buildings.index, 0, 0
   DRAWSPRITE red_square.index, red_square.xpos, red_square.ypos

  // Switch back to the window
          SAVESPRITE "Media/gfx/foobar.bmp", 13
USESCREEN -1
ENDFUNCTION

MrTAToad

You usually use SETTRANSPARENCY when re-loading sprites that have been saved using SAVESPRITE...

Ian Price

#7
You don't need to save and load the bitmap.

Code (glbasic) Select

SETSCREEN 640,480,0

GLOBAL press, x, y, j, k

// Create virtual screen
CREATESCREEN 1,999,640,480

// Draw random coloured buildings on virtual sprite
USESCREEN 1
 
FOR n=0 TO 640 STEP 32

DRAWRECT n,640,32,RND(320)-480,RGB(RND(255),RND(255),RND(255))
 
NEXT

// Use visible screen for all future drawing
USESCREEN -1

WHILE TRUE

// Background colour (pink)
DRAWRECT 0,0,640,480,RGB(255,128,128)

PRINT "PRESS SPACE TO DAMAGE CITY",10,10

PRINT "PRESS LEFT/RIGHT TO SCROLL CITY",10,30

// Press SPACE to place random damage on the city
IF KEY(57) AND press=0

USESCREEN 1

j=RND(640)
k=RND(480)

// Cut holes in sprite 999
DRAWRECT j,k,16,16,RGB(255,0,128)

USESCREEN -1

press=5
ENDIF

// Reduce repeated key presses
IF press>0 THEN DEC press

// Scroll city
IF KEY(203) THEN DEC x
IF KEY(205) THEN INC x

// Draw city sprite
DRAWSPRITE 999,x,y

SHOWSCREEN

WEND


:)
I came. I saw. I played.

bigtunacan

@MrTAToad,

Agreed; that is what I'm doing.  It is working now.  I was just commenting on it because it caused me a bit of trouble at first.  I found it a little odd that the transparent area of a BMP is being colored differently with SAVESPRITE than the default transparency color; in fact it is the R & B values have been flipped between the two.  I was wondering if this was intended behavior or really a mistake in the original code base?  Although to change it now would probably cause problems for existing applications; I do think it would be worth noting something like this in the GLBasic documentation however...

@Ian

I agree if I were trying to just blot out a rectangular area there would be no need to save and re-load the image, however what I'm actually trying to achieve is blotting out a radial area from the point of impact; I could try doing that with a custom polygon, but I felt it was easier to implement by drawing a 2 tone sprite centered at the location of impact.  I believe that necessitates the save and re-load since only 1 color can be transparent at a time.  If there is a way to do this without saving and re-loading I would be interested in hearing about it; I don't believe the sample you provided using DRAWRECT would work in this situation though.

@Anyone reading...

Currently I'm just working on this on PC, but my long term goal is iOS and Android; so I do have some concern with whether SAVESPRITE will work on iOS and Android as I don't know what those allow in terms of writing back to the device.  Can someone confirm this functionality works ok on those devices?

Thanks!

Ian Price

#9
I only provided a DRAWRECT solution because it was a basic principle and showing how you could apply the requested effect - itIt also clearly demonstrated the "virtual screen". I did say that you could use several effects to make a hole including DRAWRECT, SETPIXEL and POLYVECTOR.

You never stated that you wanted a circular effect - in fact
QuoteI was trying to test this with the drawrect, but this does not appear to take transparency?
and your code states "red_square" If you want a circular crater, then use POLYVECTOR. It's MUCH more efficient than any other drawing method and certainly MUCH faster than saving a .BMP and then reloading it.

In my code you can just replace the DRAWRECT with a simple POLVECTOR function and it would work as required.
I came. I saw. I played.

bigtunacan

@Ian,

Good point; my original post probably wasn't as clear on what my desired end result was.  I have gotten it to work now using the a 2 tone image that I load and re-save.  I had considered the poly vector; which may well be faster as you pointed out.  Honestly; I'm not really liking the visual results anyway for this particular affect.  I sent back over to the artist that I'm working with to see if he can provide some updated artwork and I think I will end up trying out more of a block sprite method like you have suggested in your original post.