How to know when sprite has reached top of wall

The character in this image is able to climb walls. I’m trying to figure out how to detect when he has reached about the height in the image so I can put him in a state that crawls on top of the tile and stands up.

image

I’ve logged the arcade sprite and don’t see anything in there I could use to indicate when this happens.

Here’s player.body.blocked, touching, and checkCollision. None of which have only “left” as true, which could potentially tell me when the sprite has reached the top. Also, he’s very clearly touching the wall, shouldn’t these have left=true?

image

image

image

Any ideas on how I can tell when he’s reached the top?

Hard to tell. We can’t see the hitbox for the wall.
Have a hitbox to the left (in this case) of the character’s head. As soon as it doesn’t collide, you’ve reached the top.

I added a new hitbox (called climb_checker) in the spot you suggested.

climb_checker.body.checkCollisions looks the exact same whether it’s inside the wall or above it. I also added an overlap between the climb_checker and the scene’s layers. That overlap object also looks the exact same when it’s touching and not touching.

What property will I use to determine if it’s colliding with the wall?

I have followed the example as best I can

  this.climb_checker_group = scene.physics.add.group();
  this.climb_checker = this.climb_checker_group.create(x, y, 'heart')
  this.climb_checker.setVisible(false)
  this.climb_checker.body.setAllowGravity(false)
  scene.physics.world.enable(this.climb_checker)
  ...
  scene.physics.add.overlap(this.climb_checker_group, scene.layer)

Yet still, in all circumstances, climb_checker.body.touching.none is true. Regardless of whether it’s overlapping with a tile or not. I know it’s overlapping because I’m able to log something in the overlap while it is.

Are you using tweens to move? You need velocity.

Isn’t this all you need? You know when it’s overlapping (and thus also when it isn’t).

PS. Why use a physics group? Use a zone, it’s meant for stuff like this.

I didn’t know about zones, I’ve switched the climb_checker to a zone and it’s the same result.

About the issue of checking during the overlap, I have another strange issue where I set a variable to true during it, but then log it in update and it seems to have switched it back to false, even though I never did that.

  constructor(){
  ...
  this.climb_checker_colliding = false

  scene.physics.add.overlap(this.climb_checker, scene.layers[0],
  function(checker, layer){
    console.log('colliding now')
    this.climb_checker_colliding = true
    console.log('climb_checker IN OVERLAP is ', this.climb_checker_colliding)

  },
  function(checker, layer){
    return (layer.collides)
  }, this.scene)

  ...      
  }

  update(){
  ...
    console.log('climb_checker IN UPDATE is ', this.climb_checker_colliding)
    console.log('')
  }

image

It’s a different ‘this’. Put your code online or send me a PM, I’ll have a look. I’m curious to know why touching isn’t set.

Is scene.layers[0] the player? :confused:

Generally you need

function create() {
  this.colliding = false;
  // …
  this.add.overlap(
    this.player,
    this.zone,
    function (player, zone) {
      this.colliding = true;
    },
    null,
    this
  );
}

function update() {
  console.log('colliding', this.colliding);

  this.colliding = false;
}

It’s a map layer. The overlap is between the zone in front of the character’s face, and the map tiles.

OK, so the zone is moving and is a proxy for the player.

function create() {
  this.climb_checker_colliding = false;
  // …
  this.add.overlap(
    this.climb_checker,
    scene.layers[0],
    function () {
      this.colliding = true;
    },
    function (climb_checker, tile) {
      return tile.collides;
    },
    this
  );
}

function update() {
  console.log('colliding', this.colliding);

  this.colliding = false;
}

Using the collides variable seems to be working, but do you have any idea why climb_checker.body.touching.none is always true?

Even after I set the overlap and the overlap works

If there’s no movement there’s no touching; embedded is set instead. But the callback is still run.