question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

point towards + movement will oscillate sprite's direction

See original GitHub issue

Expected Behavior

Sprite keeps its direction when the mouse is not moved.

Actual Behavior

When point towards mouse-pointer is followed by move 10 steps, the sprite direction will oscillate even if the mouse position is not changed.

Steps to Reproduce

oscillating_direction

Use this project to try it out.

Operating System and Browser

  • Scratch Desktop Windows 10
  • Firefox on Windows 10
  • Chromium on Linux

So, looks like an engine rather than a UI issue.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
towerofnixcommented, Jun 9, 2019

I agree that decreasing the “move 10 steps” to “move 0.1 steps” doesn’t fix the issue, though, so you might be rights about the floating point/precision issues when step size is small. But I think for step size = 10, this is how it should be.

It’s still always going to oscillate, and with good reason. Suppose the sprite were exactly 10 units away in distance, to the right (and that the mouse is not moving for our demonstration). It will point towards the mouse (leftwards), then move towards it 10 units. Now the sprite is at the exact same position as the mouse (at least for our demo). Now, the next frame, it is going to point “towards” the mouse. Of course, since it is already at the mouse position, there is no correct value for “towards” here, but Scratch defines the result to be the sprite pointing in direction 90 (rightwards). Thus, exactly at the script defines, the sprite will move 10 steps – to the right. Upon the next frame, we are exactly where we started: 10 units away from the mouse, to the right. It points left and repeats the process all over again: oscillating.

Accordingly, this pattern arises from any distance traveled, no matter what, provided the script “forever: point towards mouse, move N steps” - even a fractional value less than 1. Even if the position does not visibly change (a change so small might not), the direction will still change, because internally the sprite is still oscillating between the exact position of the mouse and slightly to the right.

Of course, since “move N steps” moves it forwards in the direction the sprite is pointing, it would still overshoot exactly as @joker314 described above most of the time, because the sine/cosine values generally wouldn’t add up to integer values (and be exactly equal to the mouse position). This results in the oscillation not being exactly left-right (overshooting means it’ll be ahead of the sprite in the direction it was facing as it moved). But even if the sprite’s position weren’t fractional (e.g. you used “go to x: (round (x position)) y: (round (y position))” after moving), you would still end up with the oscillation, left-right as I described above.

There is a way to avoid this behavior, although it involves changing the script; naturally, with that script, the behavior is inherent. Here’s one example solution:

"forever: if distance to mouse > 10, point towards mouse and move 10 steps; else, go to mouse"

Because the sprite only changes direction and moves forwards once it is more than 10 units away, it does not oscillate when it is closer, instead going directly to the mouse position and staying in the same direction (no “point towards mouse” in the else branch).

The other option is to use a “smooth” movement script, like so:

"forever: point towards mouse, move 0.50 * distance to mouse"

You’ll notice, if you use this script, the sprite will seemingly pause when it becomes very close to the mouse (within a pixel distance), and will stay in the same direction. This is because the sprite is still getting closer to the mouse, but the distance it moves is so small doesn’t change what’s apparent on the screen. If the mouse stays still for long enough, eventually JavaScript’s decimal precision will fail and the sprite’s distance will become equal to zero. (It’s worth noting that this precision is more accurate than Scratch’s monitors display, if you show the monitors for x/y position: the position of the sprite becomes equal to the position of the mouse slightly later than the monitor reports them as apparently equal.) At this point, the sprite faces right, as defined by Scratch when the distance is zero, like I mentioned earlier. If you prefer the “smooth” movement of this script, you can work around that by combining with the first example script; if the distance is less than 1, go directly to sprite, and do not change direction.

(edit: typo!)

0reactions
TheLogFathercommented, Jun 10, 2019

TBH, this kind of thing is actually a great opportunity for teaching kids one of the most important aspects of coding…

Learning to carefully work through your code under various scenarios, to figure out what it is you’ve actually told the computer to do (rather than how you expect it to behave), can be really critical in some situations.

The code may work the vast majority of the time in exactly the way you expect. But simply missing, or failing to test for, some (even very rare) edge/corner-case (such as not dealing with some not-as-expected sensor-reading situation) is the kind of thing that can lead to loss of your spacecraft (e.g. Mars Polar Lander), or leaving your super-advanced ‘smart’ warship crippled in the water for several hours (e.g. USS Yorktown), or your radiation therapy machine overdosing & killing patients (e.g. Therac-25), or your autonomous vehicle not noticing a cyclist, or your 737 crashing…

Makes you think, though – I mean, as software complexity is increasing so rapidly these days, and as there’s more & more reliance on machine-learning (where we don’t really know ‘how it does it’), you do start to wonder how it can be possible to thoroughly test it all, and how smart it is to deploy it so widely in potentially life-critical situations.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Oscillating Sprite Movement in XNA
You need to move the sprite relative to a center point. To do this, create an offset and alter the position of Y...
Read more >
Movement & Direction - Snap! Wiki - Miraheze
The direction (angle) is where the sprite points at. 90 is right, 270/-90 is left, 180 is down, and 0 is up. Motion...
Read more >
Pointing towards movement (article) - Khan Academy
And when we say "point in the direction of movement," what we are really saying is “rotate according to the velocity vector.” Velocity...
Read more >
How To Have Sprite Face Direction Of Movement In Unity
Have your sprite based player flip when changing movement directions and manage it properly regardless of how the character spawns into the ...
Read more >
Advanced Game Development Using Scratch 3.0 - Instructables
1. For the most part, Scratch is really flexible allowing you to add different components to your project as you go. But it's...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found