Bug found when a sprite follows a sprite

As seen in the following game, I have two sprites at opposite corners from each other. The top left sprite follows the bottom right sprite at a speed of 100px/ms. When the moving sprite stops, I expected that their x,y locations would be the same, but there are ever so slightly off. To test whether the sprite was still moving, I checked the velocities instead; which does work.

I don’t want to track when they overlap, as the game I am developing moves one step a time. See:

for reference for anyone following here: https://github.com/microsoft/pxt-arcade/issues/2448#issuecomment-703330657 and https://github.com/microsoft/pxt-common-packages/pull/1183

Thank you for your quick reply and succinct explanation; you are very helpful. :+1:

Hi Joey,
I saw that a pull request on this issue was merged (https://github.com/microsoft/pxt-arcade/issues/2448#issuecomment-703330657). It is great that the team responded so quickly. Does that mean the problem is resolved in my game? Do I need to update any files, or does that happen automatically with ‘core’ files in Arcade?

You are going to have to use arcade.makecide.com/beta. They use that site for well, beta. Then they push it to arcade.makecode.com after a couple of months once it’s stable.

1 Like

Of course, no need to push a fix straight into to production, and this is not a drastic issue. I was able to implement a workaround for the time being.

1 Like

Ah, I just merged that a few minutes ago actually. As @UnsignedArduino noted, typically fixes will sit in beta for a bit, and go out to the live site as part of releases after we have time to test / fix bugs. There won’t be any action to take once it’s released – the core dependencies are part of the editor itself and will get updated automatically. (If you find another bug in the future in an extension, you will likely need to update the extension after it is released – currently that’s only possible by going to javascript and clicking the ‘update’ / version button next to the extension in the explorer, unfortunately).

Beta is usually kept up to date with the latest changes across the repos, so there’s often going to be bugs in new features / possibly regressions that we haven’t caught yet, and potentially new features and blocks that will change prior to release.

As a side note, the pr fixing this is pretty tightly scoped / easy to reason about, so it might get tacked onto another patch if we find something we want to patch quickly as a hotfix.

(And thanks for your kind words, we always love feedback, and it’s nice to be able to fix things like that when possible so the bug doesn’t sit around forever!)

2 Likes

I am happy to have helped with this issue. I can imagine it was easy to fix, since the code has already made a relationship between the two sprites and can always check between updates.

Speaking over updates, and I hope that my question is still related to this issue…
I was thinking about implementing my own overlap decisions in game.update(), instead of using the callback feature (on sprite overlap, etc), in order to calculate the precision of where they overlap. Is it wise to do that on every update, or to specify a pause, as I get the impression from other posts that sprites start to slow down if there is no pause?

Pausing in game updates will actually pause the whole game loop / cause the whole game to halt until the pause is up, so you won’t want to pause in there.

If you want to handle collisions in a game update, you’ll want them to be up to date / happen regularly so they don’t feel wrong. The thing that would cause the game to slow down in the first place is the physics, so you can probably add your own logic in without too much issue (assuming it is written fairly efficiently). That said, I don’t think you will be able to get any more info about the collisions in an on game update vs the callbacks; the on overlaps collisions are detected along all points while the movement is happening, whereas the on game update will only happen after all sprites have finished moving for the frame / are settled.

Could you clarify what you mean by the precision of where they overlap? If you mean whether the sprite is hitting colliding with another from above / below / etc, you’re likely better off comparing their centers (x/y positions) && their velocities in an on overlap event.

1 Like

I was thinking about performing this check manually, as I believe ‘on sprite overlap’ occurs in a separate thread (well call back in script) so that if multiple sprites hit the same target, the callback is called multiple times.

Checking manually or on the callback event, I will check the x,y positions to see how far off they differ, and make a decision based on whether the player hit the target. I am right in saying that if the player’s top right position, hits the other sprite’s bottom left, then they overlap?

I my case, Frogger game, I want the x positions of both targets to be within a marginal range; if so, frogger found its nest.

Ah, fair, I suppose in that case it could benefit from running in the on game update.

on overlap events between two sprites are a bit more picky than just checking whether one sprites’ bounding box is within the other – we check whether any colored in pixels overlap – clear portions overlapping do not count. You can get the same behavior in a condition with this block that’s right below the on overlap:

image

1 Like

Thanks Joey for your understanding and clear explanation; you are a great help. :ok_man:

@jwunderl
I just realized that I don’t need to keep checking the position in a game update, since if Frogger is not on target it dies anyway, and would need to start the level again.
Another question, if I may please.
Let’s say I decide to use the ‘on overlap event’, and that type enemy no longer exists in the game, can I remove the on even block? I am assuming that once the event is registers, that internally in the sprites namespace it keeps checking within a loop, but never needs to fire it.

Let me know if I need to start another discussion, or if I am being too pesky.

There’s no way to unregister the event within blocks, but in typescript you can access the scene with game.pushScene and game.popScene; this will change the set of events registered so you can separate things (e.g. making a menu in the game). There currently is no way to remove a specific sprite overlap event in typescript – that could definitely be useful, but requires some work in pxt (we’d need to make sprites.onOverlap return an ID for the event, so we’d need a new block attribute that says to ignore the return value and treat the expression as a statement / convert to gray block if the user uses the return value)

For most situations in block coding it may not be necessary, and a workaround could be to set a boolean variable to ignore code within the event, or even changing the type of the sprite that overlaps. It would be a nice feature to have though. That way you could introduce a sort of ‘invincible’ time period for the player, without having to make it a ghost. That way, the player still behaves within the boundaries of the game, hits walls, etc, and can still overlap other sprites.

It sounds like your mind is already thinking about challenge. The questions may be, is it easy to implement and will people use it?

In blocks, we don’t have a shape for events that return a value – there’d be a significant amount of design and implementation time to support this sort of feature, and so far appears to be something that would be fairly niche. One important thing to note would be that there’d have to be some logic in the users code to reregister the event – so it wouldn’t necessarily be significantly easier.

For what it’s worth, we have a few common workarounds for supporting temporary invincibility / etc:

  • If the event is an on overlap between two sprites, and you want it to be invincible against a specific sprite (e.g. for one second after an overlap, don’t take damage from the same sprite), you can put a pause in the overlap event; only one event between any two sprites will occur at a given time.
  • Another approach is changing the kind of the sprite temporarily, to e.g. InvinciblePlayer; you can switch it back in a variety of ways – a forever loop that you pause in after a flag is set and revert the kind change, setting a lifespan on the sprite and recreating the sprite on an on sprite of kind {kind} destroyed, or using an event from an extension to run a snippet in parallel - e.g. the timers extension or the arcade-story extension:

2 Likes

Thank you again for elaborate explanation; that really helps. I think it is time to put this post to bed. @jwunderl see you on the next discussion. :wink: