Microsoft MakeCode

New Sprite Physics in beta!

We recently made some changes to the sprite physics to allow for better collision detection and higher speeds for sprites, and they have made their way into the current beta release!

Previously, sprites were limited to velocities of about 153 - this limitation was in place to make sure the sprites couldn’t go through walls by accident, and also because it helped minimize the number of situations where two sprites would move past each other without triggering an on overlap event.

With the changes in beta, that speed cap has been raised to about 500 by default. This is done by interpolating the changes in position for each sprite - within a single frame, sprites that are moving at high speeds will now have their motion split into separate steps of between ~1-4 pixels (by default), with collisions checked between relevant sprites within those steps. If you’re interested in the specifics of this, you can see all of the changes in the pull request here - though beware that much of the math uses the fixed point library for faster calculations, which can be a bit hard to follow.

If you notice any of your games no longer work properly in the beta site, I’d love to hear about it - it was a pretty decent sized change, with a bunch of small bug fixes along the way, but it’s definitely possible I made a few new ones by accident :beetle:.

One thing to be careful of is the velocities of your sprites - for example, if you had set a sprite to have a velocity of 1000 or something else that was very large, it will now be moving significantly faster than before - this can be fixed by setting the velocity down to something smaller (the easiest first step would be about 150 or -150, to get back to a similar point to the current live site).

If you want to change the values mentioned above, they are configurable in JavaScript only at this time - you can set the max speed (by default, 500), minimum step when interpolating (defaults to 2), and maximum step when interpolating (defaults to 4) by creating a new physics engine on the scene (this link will not work on the live site, as the parameters on the physics engine are new to beta):

game.currentScene().physicsEngine = new ArcadePhysicsEngine(1000, 4, 8);
const mySprite = sprites.create(img`
    . . . . c c c b b b b b . . . .
    . . c c b 4 4 4 4 4 4 b b b . .
    . c c 4 4 4 4 4 5 4 4 4 4 b c .
    . e 4 4 4 4 4 4 4 4 4 5 4 4 e .
    e b 4 5 4 4 5 4 4 4 4 4 4 4 b c
    e b 4 4 4 4 4 4 4 4 4 4 5 4 4 e
    e b b 4 4 4 4 4 4 4 4 4 4 4 b e
    . e b 4 4 4 4 4 5 4 4 4 4 b e .
    8 7 e e b 4 4 4 4 4 4 b e e 6 8
    8 7 2 e e e e e e e e e e 2 7 8
    e 6 6 2 2 2 2 2 2 2 2 2 2 6 c e
    e c 6 7 6 6 7 7 7 6 6 7 6 c c e
    e b e 8 8 c c 8 8 c c c 8 e b e
    e e b e c c e e e e e c e b e e
    . e e b b 4 4 4 4 4 4 4 4 e e .
    . . . c c c c c e e e e e . . .
`, SpriteKind.Player);
mySprite.setFlag(SpriteFlag.BounceOnWall, true);
mySprite.setVelocity(1000, 1000);
scene.setTileMap(img`
    3 3 3 3 3 3 3 3 3 3
    3 . . . . . 3 . . 3
    3 . . . . . 3 . . 3
    3 . . . . . . . . 3
    3 3 3 . . . . . . 3
    3 . . . . . 3 . . 3
    3 . . . . . 3 . . 3
    3 3 3 3 3 3 3 3 3 3
`);
scene.setTile(3, img`
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
    3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
`, true);

(tagging a few posts where I remember this being mentioned: Raptor Run - Microsoft MakeCode, Why is the speed up to 153 floating point numbers?)

2 Likes

I extended Joey’s demo slightly in the “cartridge” below. Use B to slow the burger’s velocity; use A to speed it up. Feel free to un-comment the game.splashes to see the sprite’s current velocities.

Love it, Joey! Nice work! Working late on a Saturday, I see. Hope you’re getting some vacation time in this coming week. :slight_smile:

Again, be sure to load the demos in beta: https://arcade.makecode.com/beta

arcade-Bouncing-Burger

1 Like

Hi!

With this latest change I noticed that wall collision works a little bit funky. When there is a tilemap now the sprites aren’t kept in the screen by default and, while top and bottom collision work fine, sprites go right through on lateral collision.

Thanks!

1 Like

Ahh, hm. Looks like the issue in both of these is that the movement is being handled explicitly by changing the x position instead of through setting velocity, good catch. I’ll have to think for a minute on what the right approach to fixing this one is (wrote up a fix here for all the issues I saw that affected mateo’s platformer, will try to get it merged monday or tuesday ), as we definitely don’t want to count collisions for all sprite position changes (e.g. if you move them from one side of the screen to the other you don’t want a collision in the middle of the screen as you just made it ‘teleport’), but small changes definitely should respect the tile map (maybe just as simple as counting the sprite position change as a sort of temporary velocity if it would overlap with itself in it’s previous position?)

For now, the move sprite block should fix those problems - if you place it in the sprite initialization section, expand the block, and change the vx parameter to 50 and the vy to 0, it should behave like the current movement behavior (allow you to move left and right at a rate of about 50), but will be done using velocity instead (so it will respect the tile map). Sorry about that!

1 Like