Discuss Scratch

peng-scratch
New Scratcher
2 posts

question about animation when changing the sequence of costumes and wait()

forever
next costume
wait (0.1) secs
end

forever
wait (0.1) secs
next costume
end

When I try use these two blocks to make animation, the speed of sprite's movement seems different. why do these two scipts have different running time?

Last edited by peng-scratch (Oct. 22, 2018 12:02:58)

MystreyTurtle96
Scratcher
100+ posts

question about animation when changing the sequence of costumes and wait()

In the first script, you change the costume, then wait. In the second, you wait then change the costume. When you put these two together, there's a slight gap of time in between the two, which really drives some people crazy. Keep all of these scripts in the same order and it should be fine.
deck26
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

MystreyTurtle96 wrote:

In the first script, you change the costume, then wait. In the second, you wait then change the costume. When you put these two together, there's a slight gap of time in between the two, which really drives some people crazy. Keep all of these scripts in the same order and it should be fine.
That doesn't explain the difference though.
Zizzle8383
Scratcher
100+ posts

question about animation when changing the sequence of costumes and wait()

deck26 wrote:

MystreyTurtle96 wrote:

In the first script, you change the costume, then wait. In the second, you wait then change the costume. When you put these two together, there's a slight gap of time in between the two, which really drives some people crazy. Keep all of these scripts in the same order and it should be fine.
That doesn't explain the difference though.

say this

when green flag clicked
forever
wait (0.1) secs
next costume
end

you see the 0.1 gap comes in before the switch, making the project really start 0.1 secs after it really should,
aka
first script is 0.1 secs behind

second script is 0.1 seconds aka correct.

because the wait block does it's job before the rest of the script


like a song


wait 1 beat then continue vs
continue then wait 1 beat.
even if scratches frames are very fast, its all down to how you order your blocks.
Zizzle8383
Scratcher
100+ posts

question about animation when changing the sequence of costumes and wait()

and for the original, its how scratch processes blocks, try walking then waiting
and a friend waiting then walking.
deck26
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

Zizzle8383 wrote:

deck26 wrote:

MystreyTurtle96 wrote:

In the first script, you change the costume, then wait. In the second, you wait then change the costume. When you put these two together, there's a slight gap of time in between the two, which really drives some people crazy. Keep all of these scripts in the same order and it should be fine.
That doesn't explain the difference though.

say this

when green flag clicked
forever
wait (0.1) secs
next costume
end

you see the 0.1 gap comes in before the switch, making the project really start 0.1 secs after it really should,
aka
first script is 0.1 secs behind

second script is 0.1 seconds aka correct.

because the wait block does it's job before the rest of the script


like a song


wait 1 beat then continue vs
continue then wait 1 beat.
even if scratches frames are very fast, its all down to how you order your blocks.
That only explains a difference in the first 0.1 seconds as far as I can see though. One version might be one beat behind the other but both would surely work the same otherwise - the sound wouldn't stutter or anything..

This presumably has something to do with when Scratch refreshes the screen but I don't think anyone has properly explained why the movement looks different (not just the sprites not moving at the same time).
DerpyHead0
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

I CAN EXPLAIN
ok on any loop you see this:
forever
...
end
but because people seem to not understand that normally it can do something instantly, forever blocks secretly work like this in scratch:
forever
wait ((1)/(30)) secs
...
end
(or maybe the wait is after)
anyways if you put a wait on a forver block, the above is cancelled, but it either only cancells when at the end or start, too lazy to test sorry
if you run the project in turbo mode, the loop wait goes away.
deck26
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

DerpyHead0 wrote:

I CAN EXPLAIN
ok on any loop you see this:
forever
...
end
but because people seem to not understand that normally it can do something instantly, forever blocks secretly work like this in scratch:
forever
wait ((1)/(30)) secs
...
end
(or maybe the wait is after)
anyways if you put a wait on a forver block, the above is cancelled, but it either only cancells when at the end or start, too lazy to test sorry
if you run the project in turbo mode, the loop wait goes away.
Still not convinced I'm afraid. If we expand the forever loop we effectively get

wait (0.1) secs
next costume
wait (0.1) secs
next costume
wait (0.1) secs
next costume
etc (ignoring starting effects so assuming this is after a few cycles)

If you view it that way then adding an additional wait for the forever loop just appears before or after the wait in the code making it a longer wait but otherwise no obvious reason for the sprite's costume changes to look any different.

I'm sure @TheLogFather will be able to explain it more fully.

TheLogFather
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

In the second one Scratch does a screen refresh at the end of each pass of the loop (when not in turbo mode) because something just changed on-screen (the costume).

In the first case the refresh happens during the wait (because the change was just before it), and it *doesn't* need to refresh at the end of the loop (because nothing has changed in the last frame).

That means each pass in the second case is ~1/30th sec longer than the first case.

Hope that makes sense & clears it up!




BTW, I'll note that if you add another loop somewhere else in the project like this:
forever
move (0) steps
end
…and that's running at the same time as one of your two original loops (and running in a sprite that's not hidden), then your two cases will run at (pretty much) the same speed.

That's because the above new loop makes Scratch do a refresh at every yield point of all concurrent loops.
EDIT: actually, thinking about it, I'm not entirely sure what I've said just above (with the new concurrent loop added) is correct. –It may be that Scratch still doesn't bother to count it as a script yield when it reaches the end of a loop straight after a wait block…? (Depends how it deals with the end of the wait.) Would need testing to be sure…


Having said that, using the wait block isn't a good way to do stuff like this…

Since Scratch runs at ~30fps rate (when not in turbo mode), and since that includes checks of the wait block time (to see if its time is up), and since there's always other stuff going on in the computer that can delay when the browser gets chance to allow Flash to run more Scratch do its checks of such wait times, it means it's quite likely the “wait 0.1 secs” will actually wait for somewhat longer than 0.1s – and it'll be a bit different each time.

That means you shouldn't rely on wait blocks for timing things to try to synchronise them across sprites/clones (or even different loops in the same sprite/clone).

Instead, if you want to synchronise things happening in Scratch, the best way to do it is to use the timer (as long as you're allowing a refresh every frame, i.e. not doing stuff in non-refresh – Scratch has a bug at the moment that means the timer doesn't work correctly if there are loops running without refresh – a better alternative is to use “days since 2000”), and use broadcasts to tell different sprites/clones to do things at a specific time/interval.

Last edited by TheLogFather (Oct. 25, 2018 10:00:05)

deck26
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

TheLogFather wrote:

In the second one Scratch does a screen refresh at the end of each pass of the loop (when not in turbo mode) because something just changed on-screen (the costume).

In the first case the refresh happens during the wait (because the change was just before it), and it *doesn't* need to refresh at the end of the loop (because nothing has changed in the last frame).

That means each pass in the second case is ~1/30th sec longer than the first case.

Hope that makes sense & clears it up!



So you could view it as the first one getting a free refresh during the wait but the second one has to do the refresh separately at the end of the loop?
TheLogFather
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

So you could view it as the first one getting a free refresh during the wait but the second one has to do the refresh separately at the end of the loop?
Yes, exactly.

(BTW, I think DerpyHead0 probably had the right idea in mind in that post. –The part about the 1/30s pause being “cancelled” by the wait… I mean, it's not quite the same as always having a wait of 1/30s at the end of a loop, since it's really just a pause until the next refresh happens, which could be due very soon after the last block within the loop has finished if there was enough work done that it already lasted nearly 1/30th sec. But if the running scripts have done pretty much nothing in that pass up till that point then it's practically like a 1/30s wait.)

Of course, all of this is without turbo mode (again, as DerpyHead0 noted). –If it's done with turbo then I suspect the difference will be reduced, since Scratch will not bother to do the refresh so much at the end of the loop in the second case. (That's what turbo mode does – it only tells Flash to do a screen refresh if it's been nearly 1/30th sec since the previous refresh. Compared to non-turbo where it always does refresh after all concurrent loops reach their yield points – as long as there was a [potential] change on-screen.)

Last edited by TheLogFather (Oct. 25, 2018 11:34:27)

deck26
Scratcher
1000+ posts

question about animation when changing the sequence of costumes and wait()

Thanks. I was sure it had something to do with screen refreshes and was happy to believe others (like @DerpyHead0) might understand it but their explanations weren't getting through the mist for me.
peng-scratch
New Scratcher
2 posts

question about animation when changing the sequence of costumes and wait()

thx a lot! i think it understandable for me.
roblox_player58
Scratcher
3 posts

question about animation when changing the sequence of costumes and wait()

repeat (20)
move (50) steps

end

Powered by DjangoBB