Routine for making a sprite dissolve?

BlitzPlus Forums/BlitzPlus Programming/Routine for making a sprite dissolve?

hockings(Posted 2005) [#1]
Hi All,
I'm trying to replicate an effect from an old game but am drawing a blank on a good way to do it (all the ways I can think of would require loads of code or stupidly large amounts of memory).

The original effect had a sprite of about 16x16 (Commodore 64 days) that would have a few random pixels change colour rapidly then change to black. A few of the non-black pixels would then change colour and go black, and then a few more, and so on until the sprite had been erased. The selection of which pixels to erase was random each time.

Has anyone got any good ideas on how I'd implement this effect, particularly with a much larger sprite?

Thanks!
Shane


aab(Posted 2005) [#2]
Well, i suppose you mean for realtime use
(eg 60 frames per second while user is moving a character about or something),

Otherwise you could just loop through after using LockBuffer() and WritedPixelFast()'ing. (On general sized images seems to take the same time as getting the LockedPixels() bank and Peeking and Poking it)

eg of use (not to do what you ask but to write a colour to every pixel)
img=Loadimage(....)
buf=Imagebuffer(img)
w=Imagewidth(img)
h=Imageheight(img)

LockBuffer(buf)
For u=0 to w
	For v=0 to h
		WritePixelFast ... ;depending on your desires.
	Next
Next
Unlockbuffer(buf)

But that would be slow..
I assume that you already know the above well (and ive wasted some time) but if so, all i can think of is:

Making a list of images during loading times that have a mask, and are each drawn with some dots randomly during this time (in the way mentioned above): it wouldnt affect the user during this time as the game would be doing some loading routines and not actually 'playing'.
So say you made a list of random images each 512,512 or something similar: you could just Tileimage random ones of them on over time. (Setbuffer(imb=buffer(img)) so Tileimage draws to the image) Big problem..It would only do for the first part as there would be alot of leftover spaces.
And if you wanted the pixels to fade from their random colour to black, and not just 'black out', id be lost as to how to do it in any good timeframe in Blitz.





Zster(Posted 2005) [#3]
First set up a function to go through your image and count how many non black pixels you have. Then assign them each to an array. Then travel through that array 10 at a time fading them out to a predeterminined palette (stored in an array). The travel is determined by a prime number greater than the amount of pixels (you can look these up on the internet) various primes look different and you can make the formula more random (forgotten how at the moment) but you can look it up. The example is quick and tries to show it but I think you need to extend the palette to at least 32 and have them fade slowly to get a decent effect. Hope it helps

eg

[/code]
Graphics 320,240,32,2
sprite=CreateImage(16,16)
SetBuffer ImageBuffer(sprite)
Rect 2,5,11,5,1
Rect 5,2,5,11,1
count=0
arraycount=0

Dim cp(10);the amount of pixels we want picked at a time


SetBuffer ImageBuffer(sprite)
LockBuffer ImageBuffer(sprite)
For nx=0 To 15
For ny=0 To 15
temp=ReadPixelFast(nx,ny)
If temp=$FF000000;which is black FF is the alpha value
Else
count=count+1
EndIf
Next
Next
UnlockBuffer

;once you know the number
;arrays used for speed
Dim fadex(count)
Dim fadey(count)



SetBuffer ImageBuffer(sprite)
LockBuffer ImageBuffer(sprite)

For ny=0 To 15
For nx=0 To 15
temp=ReadPixelFast(nx,ny)
If temp=$ff000000
Else
fadex(arraycount)=nx
fadey(arraycount)=ny
arraycount=arraycount+1
If arraycount=4
;Stop
EndIf
EndIf
Next
Next
UnlockBuffer

;setupfast fade palette
;you may want to change to rand(100-(n*8),255-(n*8))
;so later colours are darker
Dim palette(16)
For n=1 To 15
r=Rand(100,255)
g=Rand(100,255)
b=Rand(100,255)
palette(n)=r Shl 16 + g Shl 8 + b
Next
palette(16)=$ff000001;last colour black

;now To test
pixel=Rand (84); random starting pixel must call this before function starts

For time=0 To 600
If time>120 ;wait 2 seconds then disolve
If totalcount<84
SetBuffer ImageBuffer (sprite)
LockBuffer ImageBuffer (sprite)
;now here the random bit what you need is a prime
;number greater than the number of pixels you're going
;to cycle through in this case 89 (you can look these
;up on the internet it works better with non uniform shapes
;85 pixels in this image

If palcount=0 ;this makes sure all pixels are faded out
;before selecting the next 10 pixels
For n=0 To 9
cp(n)=pixel
pixel=pixel+103
While pixel>84;greater than pixel number
pixel=pixel-85
Wend
Next
palcount=1
Else
For n=0 To 9
WritePixelFast(fadex(cp(n)),fadey(cp(n)),palette(palcount))
Next
palcount=palcount+1
If palcount=17
totalcount=totalcount+10
palcount=0
EndIf
EndIf
UnlockBuffer
EndIf
EndIf


SetBuffer BackBuffer()
Text 0,0,count
DrawImage sprite,100,100
Flip

Next
[/code]


Kevin_(Posted 2005) [#4]
Crickey! That sure is a slow way to do it. Why not create some images the same size as your sprite with missing pixels then animate them. OK, more memory needed for the extra images but it will be fast enough especially if you want to disolve lots of sprites.


hockings(Posted 2005) [#5]
Thanks for the replies guys, they're certainly much appreciated! I'll have to think about the prime number thing to get it sorted in my head...
Considering that it's a remake of an old platformer (Henry's House) and there's not exactly heaps of graphics going on, I think the overhead of doing randomness will be worth it (especially when I want to map it to the correct animation frame for the character. Using image animation for disolves would mean X (number of animation frames) * Y (Number of disolve frames) images which means lots of frames for even a small sprite!)

The other way I had suggested was to have each pixel as a type (X,Y,Color), put the types in an array, shuffle the array, then blank out the pixels going through the array. I'm not sure which will give the best result in speed or performance but I'll give them all a go.

Again, thanks all very much for taking the time to respond!
Shane
(Look out for the game this relates to - Henry's House - coming to Retro Remakes sometime in the next month hopefully!)


Zster(Posted 2005) [#6]
The demo was more to show the effect nothing stops you from using it to prerender some images although I don't think the overhead is large at all so realtime use is not out of the question. The method above causes pattern randomness to get a true random looking disolves using primes see
http://www.developer.com/tech/article.php/10923_3496381_3
it's in C++ the principles are the same