Microsoft MakeCode

Spites collision

Hi all,

Just starting to play around with MakeCode, and I was wondering what was the best approach to handle collisions between two sprites if that means that it will prevent both of them from moving forward. Similarly to a wall I suppose, except that other types of sprites could overlap.

Thanks in advance for your help

Welcome, @bastien!

Once you detect the collision, you can take any action that you want, including changing the velocities of the sprites involved (or any other sprites, for that matter):

If I misinterpreted what you asked, just let us know.

Thanks Alex, that makes sense.
But I was thinking in the case where at least one of the sprites is controlled by the player and could be coming from any direction. That sprite, the player, should be stopped as well and prevented from moving further in that direction.

My initial thought, again, new here, was to use the overlaps function as you suggested and then setPosition to return the sprite to the previous position it was at, except I’m not sure of a simple way of determining that previous position. I hadn’t thought of using velocity, maybe that can be used to determine the previous position.

Here’s my first attempt:

sprites.onOverlap(SpriteKind.Player, SpriteKind.BrickWall, function (player, wall) {
  if (player.vx != 0) {
    player.x = wall.x - (16 * Math.abs(player.vx) / player.vx)
  } if (player.vy != 0) {
    player.y = wall.y - (16 * Math.abs(player.vy) / player.vy)
  }
})

That mostly works, however, they still sometimes overlap, I think it has something to do with the velocity already be 0 by the time this calculation happens.

And here is a working solution, although not very elegant since I had to keep a reference to the last time the sprite was overlapping. I’m not sure why, but despite setting the player x and y to correct values, it is in fact usually off by a couple of pixels. Say the code would move it to x = 16, but it would still overlap and log the player at x = 20. I initially assumed that this might have to do with the velocity, which is why I set it to 0, but that didn’t really helped. Eventually adding the xStoppedAt and yStoppedAt and reusing those in case the sprites are still overlapping did the trick.

let xStoppedAt: number
let yStoppedAt: number
sprites.onOverlap(SpriteKind.Player, SpriteKind.BrickWall, function (player, wall) {
  if (player.vx != 0) {
    xStoppedAt = wall.x - (16 * Math.abs(player.vx) / player.vx)
    yStoppedAt = null
    player.vx = 0
    player.x = xStoppedAt
} if (player.vy != 0) {
    yStoppedAt = wall.y - (16 * Math.abs(player.vy) / player.vy)
    player.vy = 0
    player.y = yStoppedAt
    xStoppedAt = null
} if (player.x + 16 > wall.x && player.x < wall.x + 16 ||
    player.y + 16 > wall.y && player.y < wall.y + 16) {
    if (xStoppedAt !== null) {
        player.x = xStoppedAt
    } else if (yStoppedAt !== null) {
        player.y = yStoppedAt
    }
  }
})

I would like a simpler solution though.

Overlaps are detected as quickly as possible, but they might not trigger the event as soon as sprites touch. It depends on the sprites’ velocities and how frequently the game is able to test for collisions. If you need to simulate a wall, you’ll need to manipulate the moving sprite as you’ve done.