Room/scene fadeout issues

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

Post Reply
User avatar
Foxley
Metal Slime
Posts: 832
Joined: Sat Nov 09, 2013 5:54 pm

Room/scene fadeout issues

Post by Foxley »

I'm trying to do a simple screen fade out by having every sprite slice (the backdrop and object/NPC sprites) in global variable "currentroom" 's slice collection do a dissolve animation before that room slice is freed. However, I get an error "waitfordissolve: invalid slice handle 0" when changing rooms from the starting room, or the game freezes completely when moving into any other room after that. Maybe I'm not getting that container properly, or maybe the loop has problems... or something else?

Code: Select all

script, screen fade out, begin
	variable (sl)
	
	hourglass (on)
	sl := first child (first child(currentroom)) #The only child of each slice collection is a container that holds the
	while(sl) do (                               #backdrop and sprites, I'm trying to get the first child of that container
		if (slice is sprite(sl)) then (
			dissolve sprite (sl, dissolve:random scatter, 80, 0, false, false)
			if (sl == last child (currentroom)) then (break)
			else (sl := next sibling(sl))
		)
	)
	wait for dissolve (sl)
end	
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

There are a number of problems there.
First of all, you wrote

Code: Select all

while(sl) do (...)
wait for dissolve (sl)
Notice that the while loop exits if sl is equal to 0, which gives you the error. If it hit the "break" it wouldn't trigger the error, but it would just be easier to write "wait (80)" there.

And in fact, it can't hit the break, because you wrote "last child (currentroom)" when you meant to write "last child (first child (currentroom))".

Actually, you should not write "if (sl == last child(...)) then (break)". The while loop would stop after the last child, which causes "next sibling" to return false.

The next problem is that if there is even a single child slice that isn't a sprite, then the "sl := next sibling(sl)" line is never reached, and the script enters an infinite loop. If it enters an infinite loop, then waiting for a couple seconds and pressing a key will cause a message to come up.

Finally, you're setting the "automatic" argument to "dissolve sprite" to false, meaning it won't actually animate, it'll just be frozen in place completely non-dissolved.

Here's a fixed script

Code: Select all

script, screen fade out, begin
   variable (sl)
   
   hourglass (on)
   sl := first child (first child(currentroom)) #The only child of each slice collection is a container that holds the
   while(sl) do (                               #backdrop and sprites, I'm trying to get the first child of that container
      if (slice is sprite(sl)) then (
         dissolve sprite (sl, dissolve:random scatter, 80)
      )
      sl := next sibling(sl)
   )
   wait (80)
end 
User avatar
Foxley
Metal Slime
Posts: 832
Joined: Sat Nov 09, 2013 5:54 pm

Post by Foxley »

OK cool, thanks. It's working now. Only problem is, it seems to work on the background sprite but not other sprites. I think this is because other sprites are children of containers or rectangles... Any suggestions on how to get those in there as well?
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

If you want to visit every slice in a tree, writing a recursive script is the simplest solution.

Code: Select all

# Dissolve every sprite slice which is a descendant of "parent"
script, fade out all sprites, parent, dissolve type, dissolve length, begin
   if (slice is sprite(parent)) then (
     dissolve sprite(parent, dissolve type, dissolve length)
   )
   variable (sl)
   sl := first child(parent)
   while (sl) do (
      fade out all sprites(sl, dissolve type, dissolve length)
      sl := next sibling(sl)
   )
end 

script, screen fade out, begin  
   hourglass (on)
   fade out all sprites(currentroom, dissolve:random scatter, 80)
   wait (80)
end 
User avatar
Foxley
Metal Slime
Posts: 832
Joined: Sat Nov 09, 2013 5:54 pm

Post by Foxley »

I'm confused... Are you able to run a script within itself? I'm seeing "fade out all sprites" inside of itself.
User avatar
Foxley
Metal Slime
Posts: 832
Joined: Sat Nov 09, 2013 5:54 pm

Post by Foxley »

In any case, I've got it working exactly how I want it now, thanks a lot for the help.

Here's the working code:

Code: Select all

script, screen fade, which, ticks, begin

	switch (which) do (
		case (out) do (fade out all sprites (currentroom, dissolve:random scatter, ticks))
		case (in) do (fade in all sprites (currentroom, dissolve:random scatter, ticks))
	)
	wait (ticks)
end 


script, fade out all sprites, parent, dissolve type, dissolve length, begin
   if (slice is sprite(parent)) then (
     dissolve sprite(parent, dissolve type, dissolve length)
   )
   variable (sl)
   sl := first child(parent)
   while (sl) do (
      fade out all sprites(sl, dissolve type, dissolve length)
      sl := next sibling(sl)
   )
end

script, fade in all sprites, parent, dissolve type, dissolve length, begin
   if (slice is sprite(parent)) then (
     dissolve sprite(parent, dissolve type, dissolve length, 0, true)
   )
   variable (sl)
   sl := first child(parent)
   while (sl) do (
      fade in all sprites(sl, dissolve type, dissolve length)
      sl := next sibling(sl)
   )
end
This way I can just do "screen fade (out, 50)" or "screen fade (in, 20)". The number argument is the ticks for the wait, and also the ticks for the dissolve. I can put this in my "change room" script like this:

Code: Select all

script, change room, room, begin
	
	clear text
	reset hud tags
	hourglass (on)
	screen fade (out, 40)
	free slice (currentroom)
	currentroom := load slice collection(room)
	currentroomID := room
	update scene objects
	screen fade (in, 20)
	hourglass (off)

end
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Yes, it's known as recursion. Any script can run any other script, but there's a limit to how many times you can recurse (currently 128). Recursion is another method of iterating, like while and for loops.
User avatar
Foxley
Metal Slime
Posts: 832
Joined: Sat Nov 09, 2013 5:54 pm

Post by Foxley »

I thought that in coding it'd be something along the lines of an infinity mirror or dividing by zero. That's good to know, though.
Post Reply