Fast Moving Blast and Shockwave

BlitzMax Forums/BlitzMax Programming/Fast Moving Blast and Shockwave

I'm trying to get the effect of a fast moving blast after a bomb goes off (on a 2D shooter). The "fireball is not a problem, but drawing the shockwave is causing me grief.

I'm drawing a white circle (filled) that alpha blends to nothing as it gets bigger and then over-drawing it in black 30 pixels smaller. This looks about right, but my background behind the black suffers by disappearing.

Making the circles blend or transparent means the effect is lost...

Any suggestions? Is there an XOR blend mode?

Wouldn't it look better if you used a PNG image? That way you could soften the edges.

@gfk and just scale it to the size I need?

Here is a rough example of the effect I am trying to obtain, (press space to create the explosion), but if you draw background stuff, it gets wiped out.

Graphics 640 , 480

Global list:TList = CreateList() 
Global item:TSprite
Global active% = False

Repeat
	SetClsColor( 0 , 0 , 0 ) 
	Cls
	For item = EachIn list
		item.update() 
	Next
	If Not(active) And KeyDown(KEY_SPACE) Then
		DebugLog "Explode"
		New TShockwave.Create( 10, 600)
		New TBlast.Create( 3, 400 )
		active=True
	End If
	For item = EachIn list
		item.draw()
	Next
	Flip
Until KeyHit(KEY_ESCAPE) Or AppTerminate() 


Type TSprite
	Field size#
	Field speed#
	Field range#
	Method Create( sp%, rg% ) 
		speed = sp
		range = rg
		ListAddLast( list , Self ) 
	End Method
	Method update() 
		size:+ speed
	End Method
	Method draw() ; End Method
End Type
	
Type TBlast Extends TSprite
	Method draw()
		SetColor( 255 , 0 , 0) 
		SetAlpha( 1.0 - (size / range) ) 
		SetBlend(ALPHABLEND)
		SetHandle(size / 2 , size / 2)
		DrawOval( GraphicsWidth()/2, GraphicsHeight()/2, size,size )
		If size > range Then
			list.remove(Self) 
			active = False
		End If
	End Method
End Type

Type TShockwave Extends TSprite
	Method draw()
	Local inner# = size - 30
		'# White
		SetColor( 255 , 255 , 255 ) 
		SetAlpha( 1.0-(size/range) )
		SetBlend(ALPHABLEND)
		SetHandle(size / 2 , size / 2)
		DrawOval( GraphicsWidth()/2, GraphicsHeight()/2,size,size )
		'# Black
		SetColor( 0,0,0 ) 
		SetAlpha( 1.0 )
		SetHandle(inner/2,inner/2)
		DrawOval( GraphicsWidth()/2, GraphicsHeight()/2,inner,inner )
		'#
		If size > range Then list.remove(Self)
	End Method
End Type


@gfk and just scale it to the size I need?
Yep. It'll pixelate a bit when you scale it up a lot, but if you're decreasing the alpha at the same time then it shouldn't matter so much.

@GLK: Just tried it out, and it looks fine. Many thanks.

Just tried this and worked fine, although I would say that a colour cycle for the central and outer blast would be cool e.g. inner white->yellow->orange->red, outer white->yellow

Just my $0.02 worth!

NB: Value varies depending upon local exchange rate!

Scare:
You can do that color cycle he mentions above by making the PNG image white, and then using SetColor before you blit it to modify the color.

@Merx: I've actually done that in the final result.

What I did was:

Stored the colour as an integer starting at white ($FFFFFF)
Then I slowly shifted the bits left forcing the colour to go red and eventually to black.

Shift must be a number between 0 (White) and 24 (Black).

red = (colour shl shift) shr 16
green = (colour shl shift) shr 8 & $000000FF
blue = (colour shl shift) & $000000FF
setcolour(red,green,blue)
drawimage(image,x,y)