Shatter Screen Wipe?

Blitz3D Forums/Blitz3D Programming/Shatter Screen Wipe?

Gabriel(Posted 2003) [#1]
I've just finished my current project and it's about to go into beta. So I'm a bit bored and I figured I'd try coding something up for fun. Turned out not to be a lot of fun so far though :(

The effect I'm after is the screen shatter effect that some of the Final Fantasy games do. Probably been seen on 1001 tv programs too. I was gonna render to a texture, but I didn't think it's gonna be precise enough. I've just found JFK's ( is that Norc's new nick? ) sprite code in the archives and that should enable me to line up sprites.. will have to see how accurate that turns out to be.

Has anyone done anything like this or have a suggestion on a better way of going about things? As it's a fade, I don't suppose it matters if I lose some frames as I'm copying things around to get started.


Anthony Flack(Posted 2003) [#2]
I'm not sure what you are referring to, but an early build of Platypus used to do this effect where the screen would smash into shards and fall away, with the new screen behind it... is that what you meant? I did it in 2d, doing some tricky stuff with painting with masks...


Gabriel(Posted 2003) [#3]
Yep, that's the effect I'm after. I kinda got it stuck in my head that it would be easier to do with 3d, but if I could do it in 2d, that might actually be better in terms of memory usage. I'm open to any idea that looks good.

Paiting with masks? I'm afraid I don't have a clue about that.


Richard Betson(Posted 2003) [#4]
This is not shards but a block/shatter FX. It might get you started. :)

 ;
; Falling Tiles
; -------------
;
; (c) Richard Lawrence <richard@...;
; Version 1.1 (5th Jan 2001).
; Thanks to Mikkel Loekke for the "GetImage" function.
;
; This simple function takes whatever is on the backbuffer, breaks it
; up into a number of tiles and then proceeds to make them fall off
; the screen.
;
; Instructions: Run the program, hit any key (bar ESC) to make the
; picture explode. After its exploded, hit any key to quit.
;
; NOTE: If you're not running Blitz v1.35 then you'll need to convert
; the jpg file to bmp and modify the LoadBuffer command in the code!
;
; Licence: Feel free to use this in your own code. Some credit would be
; nice but its not essential.
;
; ----------------------------------------------------------------------


; These are the number of sqaures across and down the image should be
; broken up into. The higher the slower it is but the better it looks.
; Using 80 for ACROSS and 60 for DOWN is very nice but jitters slightly.
; Don't try 640 and 480 - it locked my laptop up!

Const ACROSS = 20  ; Its best if this value is divisible by 640
Const DOWN = 15    ; Its best if this value is divisible by 480

; Create a type square. This contains the location of the tile, its
; velocity and the image it will be showing.

Type square
	Field x,y        ; location
	Field xvel,yvel  ; velocity of movement
	Field image      ; tile image
End Type
Dim grid.square(ACROSS, DOWN)

; Set graphics mode and load image into the frontbuffer
Graphics 640,480
; NOTE! If you're not running v1.35 of Blitz then you'll need to
; covert the picture into a bmp file and edit this line!
LoadBuffer(FrontBuffer(), "BlitzLogo.bmp")

; Display the picture
WaitKey

; Make the picture fall
fall_picture()

; Wait for them to press a key
SetBuffer FrontBuffer()
Text 20,20, "Press a key to finish ..."
WaitKey

; Finish
End

; fall_picture()
; Break the screen into tiles and then make them fall off the screen

Function fall_picture()	
	; Set the buffer to that of the picture
	SetBuffer FrontBuffer()

	; Work out the size of each square
	xsize = 640/ACROSS
	ysize = 480/DOWN	
		
	; Loop through each square, first across then down
	For i = 0 To ACROSS-1
		For j = 0 To DOWN-1
			; Create a new instance
			grid(i,j) = New square
			; Grab the image at the location on the screen
			grid(i,j)\image = GetImage (i*xsize, j*ysize, (i+1)*xsize, (j+1)*ysize)
			; Store its location on the screen
			grid(i,j)\x = i*xsize;
			grid(i,j)\y = j*ysize;
			; Work out how fast and which direction the tile will drift
			; from -3 (fast left) to +3 (fast right)
			grid(i,j)\xvel = Rnd(6) - 3;
			; Work out its velocity, negative values mean that it will
			; move upwards before going down again
			grid(i,j)\yvel = -Rnd(9)
		Next
	Next

	; Set the buffer to the back one	
	SetBuffer BackBuffer()

	; Loop through drawing each tile. If its off the screen, don't
	; draw it but increase the vanished counter. When the counter
	; hits ACROSS x DOWN then all tiles have gone off the screen.
	While vanished <> (ACROSS * DOWN)
		Cls
		vanished = 0
		
		For i = 0 To ACROSS-1
			For j = 0 To DOWN-1
				; Check tile is on the screen
				If grid(i,j)\y < 640 Then
					; Increase the y's velocity by one. This simulates
					; gravity meaning that the tile will speed up
					; going downwards
					grid(i,j)\yvel = grid(i,j)\yvel + 1
					; Update the x and y co-ordinates by adding the
					; velocity values. Note xvel is not changed, the
					; tiles do not change speed from left to right
					grid(i,j)\y = grid(i,j)\y + grid(i,j)\yvel
					grid(i,j)\x = grid(i,j)\x + grid(i,j)\xvel
					; Draw it
					DrawImage grid(i,j)\image, grid(i,j)\x, grid(i,j)\y
				Else
					; Update the vanished counter
					vanished = vanished + 1
				End If
			Next 
		Next 
		Flip
	Wend
	
	; Free all memory up (image first then the type)
				
	For i = 0 To ACROSS-1
		For j = 0 To DOWN-1
			FreeImage grid(i,j)\image
			Delete grid(i,j)
		Next
	Next
End Function

; Grab an image from a set of co-ordinates.
; Provided by Mikkel Loekke.

Function GetImage(LIx1, LIy1, LIx2, LIy2)
	; Work out width and height of the section we want
	LIw=LIx2-LIx1
	LIh=LIy2-LIy1
	; Create a blank image of that width and height
	LItempimg = CreateImage(LIw,LIh)
	; Grab into this, the picture at those co-ordinates. Excessive
	; picture will be clipped
	GrabImage(LItempimg,LIx1,LIy1)
	; Return it
	Return LItempimg
End Function


L8r,


Anthony Flack(Posted 2003) [#5]
Painting with masks - I had a bunch of images with shard shapes painted on them, in 2 colours. First I copied a square of the background onto a new image, the same size as the shard tile, and painted the shard over the top, with the inside colour set to mask (transparent) so the outside colour was painted on, and the inside retained the image from the screen. Then I changed the mask colour to the outside colour, so the outside became transparent. So I ended up with an image which was an arbitrarily shaped chunk of the screen. The space behind it, on the screen, I repeated the same trick on, but in reverse, thus leaving a hole of the same shape. Repeat until the whole screen is covered. Make the shards overlap and you'll get all kinds of different shapes from just a few (I used 4) shard shapes, that all fit together perfectly.

It looked really cool, but due to what perhaps was a memory fragmentation problem, I eventually cut it from the game. Don't worry, mine was an extreme case, involving LOTS of loading and unloading graphics over an extended period of time without ever flushing out the vidRAM - you probably won't have that problem!


Gabriel(Posted 2003) [#6]
Richard : Thanks, that's exactly the type of effect I wanted. It's a great starting point to figure out the shards.

Anthony : Thanks for clearing up the mask painting. I always have problems with masks ( not sure if it's a videocard problem or a brain problem ) but I understand what you mean and I think I can use that.


Of course the perfect solution would be to combine the two. I'm gonna give that a try now. Thanks guys.


BlitzSupport(Posted 2003) [#7]
See if this is any use... it's another block-explode thing.

Just do this sorta thing with it:

Include "explosions.bb"

AppTitle "Hit SPACE..."

Graphics 640, 480, 0, 2
SetBuffer BackBuffer ()

InitExplosions ()

image = LoadImage ("blah.bmp") ; Screen-sized image...

bang.RenderedExplosion = RenderExplosion (image, 16, 16)

Repeat

	Cls

	; Note: EXPLODE_Num is a global variable containing the number of explosion particles on-screen...

	If EXPLODE_Num = 0
		DrawImage image, 0, 0
	EndIf
	
	If KeyHit (57)
		StartRenderedExplosion (bang, 0, 0, 0, 0, 0.025)
	EndIf
	
	UpdateExplosions ()
	
	Flip
	
Until KeyHit (1)

; Do this when you no longer need the pre-rendered explosion...

FreeRenderedExplosion (bang)

End



Anthony Flack(Posted 2003) [#8]
If I still had the routine I'd post it but I've been looking and I don't think I do, unfortunately. I should have donated it when I first cut it.


Beaker(Posted 2003) [#9]
This might be worth a look: Dissolver


Anthony Flack(Posted 2003) [#10]
Found it! Just need to hack it up a bit and make it a bit more friendly, and I'll post it up. Give me an hour or so.


Anthony Flack(Posted 2003) [#11]
Get it here:

http://www.blitzbasic.co.nz/codearcs/codearcs.php?code=672

(NB: it's 2d code though)


darklordz(Posted 2003) [#12]
Th eshatter effect is running a tad slow? Is that because of my vid specs. Gforce 2 MX/400


Anthony Flack(Posted 2003) [#13]
Really?

Shouldn't be. I have a geforce 2 and it's screamingly fast. Unless it's that detonator driver issue again (this is old 2d code, remember!)


Gabriel(Posted 2003) [#14]
Wow.. lots of ideas here. Thanks guys.

James : Yep, that's the right effect for sure. I wrote my own version similar to Richard's but the explosion that yours has is great.

Masterbeaker : Thanks for that. I was planning on expanding to other forms of transition when I had this figured out, and those dissolves of yours will give me some great ideas.

Anthony : Thanks for digging that out. The masked drawing operations really work great. And it flies on my GF2 as well, so it must just be a driver issue. I've gone back to the 40.72 drivers to hopefully avoid it.