Closed deader69 closed 5 years ago
Sigh.
Those warp
blocks actually slow down redrawing, because they force Snap to redraw after every warp
invocation, whereas if you just leave them out Snap would not. As far as I can tell not a single of those warp
blocks has any positive effect, certainly not a single one of them speeds up anything. You can safely take them all out.
Also, stuff like wait 0.1 secs
doesn't do anything helpful at all, you can take those blocks out.
In fact, if you take out all of those "optimizations" your project works just as you probably want it to work (flicker-free redraw). Check it out:
I totally understand about not wanting to use rings with beginners. The great thing is you don't have to. Instead you yourself can use rings to make a new control structure for your kids to use, let's call it tell
:
this block makes another sprite named name do whatever is inside the C-shaped slot.
here's how to make it (see, you can use rings, your kids don't have to):
This block lets you write "redraw" invokations in a single pass, like this:
And it's very easy to use. You can make this block, export it as a blocks-module, and share it with your kids.
But, see, you don't even have to do this, because your project simply works as intended if you don't try to optimize it :-)
Yes, I was only using the warp blocks to break a long sequence into four groups, one for each limb. I wasn't trying to optimize, just 'chunk' things together visually. I just didn't expect a negative side effect, that's all. I shall refrain from abusing the warp blocks in the future!
As for the 'wait milliseconds' code... that's not an optimization attempt. Just the opposite: I'm trying to make the code run at a consistent rate across all platforms. I want it to run SLOWER on fast machines, so that I get a (nearly) consistent rate of motion.
Snap! runs significantly slower on my laptop than it does on our ChromeBoxes. So what's fun and playable on my machine is too fast and crazy for others. It's unplayable on faster machines.
One way to solve that problem is to write everything as a function of 'T', time, like a physics equation. Everything moves relative to some delta-T between frames. Thus the physical 'simulation' is completely independent of the rendering frame rate.
That's the proper, academic solution... but it's asking a lot of kids to understand and code that way.
Another solution is to run at a fixed, known frame rate. That's the way old console and arcade games were coded, knowing that the monitor refreshes at 30hz or 60hz, you just try to get everything done before the next Vsync. If not, everything starts moving at half-speed, very noticeably.
It's a really difficult problem, pros and cons to each approach. I'm not sure the best way to program this in Snap!... I'm trying to slow the 'forever' loops down to running a (nearly) consistent X frames per second, by adding a wait at the bottom.
Otherwise... I'll have to make every argument to every 'move' command be a function of 'current milliseconds'. Internally, the high-level Snap! blocks like 'glide to over seconds' are doing just that.
Anyway, for the yoyo_ants game, I can consider "wait_milliseconds' to be just a global 'speed' parameter, that changes from level to level.
Hope that all makes sense! I'm still learning this 'simple' language. :-)
Jens, I don't mean to keep 'bugging' you with my ants, but... here's another example/bug that illustrates the frame rate render sync problem.
This is an older version, you'll notice the only 'wait' is inside the ants code. If you REMOVE that wait (or set it to 0.0), you'll see that the ants "skate" instead of "walk".
Maybe the forever loop is running TWICE between renders... so it's doing TWO 'next costumes' between rendered frames... so the ants "skate", never showing the other frame.
Putting the 'wait' in makes it render the two-frame animation cycle properly.
I thought every 'forever' would have an implicit yield at the bottom (or somewhere), to allow other forever loops to run.
Do you SEE the walk versus skate problem on YOUR machine? (It's hard to see on my slower laptop, but obvious on our Chrome Boxes).
Another fascinating observation is that every clone is making A COPY of the block script.
I know because if you add/remove that bottom 'wait' while the app is running, subsequently cloned ants will either "walk" or "skate".
So the code is not statically 'compiled' once and shared amoung all instances, it's DUPLICATED, right?
What about a global delay variable that could be adjusted depending on platform? On a slow machine it could be 0; on a fast machine it could be 0.1. Just stick in [wait (delay)] by the drawing commands.
@deader69 @bb010g please, set your preferences to "prefer smooth animations" when creating interactive multi-sprite games that you want to run the same on every computer. The scheduling is then taken care of by Snap (I seem to remember pointing this out a couple of days ago...)
@bb010g adding a global delay variable is exactly what I did.
But really, just locking down the frame rate to a constant fps is all that's needed, Which is exactly what 'prefer smooth animations' does: Makes every morph run at 30 fps.
You can grep 'frameRate' and 'fps' in *.js to find the relevant bits of code. Every/any morph can set it's own fps too, for efficiency or responsiveness: bubbleHelp runs at only 2 fps, for example, while BouncerMorph runs at 50 fps.
In other words... do what Jens says! :-)
http://snap.berkeley.edu/snapsource/snap.html#present:Username=deader-tcssm&ProjectName=body_BUG_redraw_warp_flicker
This character's limbs flicker. They're drawn with pen commands, inside the 'redraw' sprite.
The flicker goes away if you remove the 'warp' blocks, which I (mis)used for clarity, to divide the script into four sections, one for each limb.
Jens, you'll recognize this is the same project as before, which you fixed with a 'redraw' method defined inside each sprite of each limb. That solution worked great, but I decided using 'ringify' and 'run' was too complex for my 9 year old beginners... and I realized that I no longer needed separate Sprite objects for each limb anyway, since we replaced their bitmaps with pen commands.
So I consolidated all limb drawing to one point inside the 'redraw' sprite. Much simpler for my students to understand. It works fine, except when I put those 'warp' statements in.
If you NEST the warps, it'll also be fine, flicker-free. Does 'warp' somehow do an implicit 'wait'? I don't understand why it would cause flickering, I would think it'd be semantically equivalent.