[SOLVED] Overlap between 2 sprites not detecting

I’m making the part of a level where a player sprite overlaps a telescope sprite, which should make the telescope ‘light up’ (just changes the frame from the spritesheet) and turn to normal when the player is no longer overlapping. This is what it looks like on screen:

There seems to be an issue, as the telescope sprite does not have any hitbox.

Here is some of my code:

  class Level2 extends Phaser.Scene {
constructor() {
	super("level2");
}
create() {
	endgame = false;
	this.score = 0;
	this.lives = 3;
	this.queue = [];
	this.runSpeed = 0.5;
	//telescope
	this.telescope = new Telescope(this, 1500, 520, 'telescope',this.choose([0,4,8])).setOrigin(0.5,1).setScale(1.7);
	this.physics.add.existing(this.telescope, true);
	this.physics.world.enable(this.telescope);
	this.telescope.enableBody = true;
	this.telescope.on("overlapstart", function() {
		if (this.telescope.frame == 0){
			this.telescope.frame = 2;
		}
		if (this.telescope.frame == 4){
			this.telescope.frame = 6;
		}
		if (this.telescope.frame == 8){
			this.telescope.frame = 10;
		}
		console.log("overlapstart");
	});
	this.telescope.on("overlapend", function() {
		if (this.telescope.frame == 0){
			this.telescope.frame = 0;
		}
		if (this.telescope.frame == 4){
			this.telescope.frame = 4;
		}
		if (this.telescope.frame == 8){
			this.telescope.frame = 8;
		}
		console.log("overlapend");
	});
	//spawn Serol
	this.serol = new Serol(this, 100, 350);
	this.physics.add.existing(this.serol);
	this.serol.body.setGravityY(3000);
	this.serol.anims.play('walkRight',true);
	this.serol.setCollideWorldBounds(true);
	//Serol controls
	this.cursorKeys = this.input.keyboard.createCursorKeys();
	this.wasdKeys = this.input.keyboard.addKeys('W,S,A,D');
	//colliding with floor platform
	this.physics.add.collider(this.stagePlatform, this.serol);
	//increasing runspeed
	this.runspeedIncrease = this.time.addEvent({
		delay: 5000,
		callback: ()=>{
		  this.runSpeed = this.runSpeed * 1.2;
		},
		loop: true
	})
	this.physics.add.overlap(this.serol, this.telescope);
}

update() {
	this.telescope.x -= this.runSpeed;
	// Treat 'embedded' as 'touching' also
	if (this.telescope.body.embedded) {
		this.telescope.body.touching.none = false
	};

	var touching = !this.telescope.body.touching.none;
	var wasTouching = !this.telescope.body.wasTouching.none;
  
	if (touching && !wasTouching) this.telescope.emit("overlapstart");
	else if (!touching && wasTouching) this.telescope.emit("overlapend");
}
lvlTwoComplete(){
	this.scene.start('level2Complete');
}

}

//Telescope object
class Telescope extends Phaser.Physics.Arcade.Sprite{
	constructor(scene, x=0, y=0, texture = "telescope", frame = 0) {
		super(scene,x,y,texture,frame)
		scene.add.existing(this)
		scene.events.on('update', this.update, this)
	}
}

I used an example from this thread to make the overlap possible:

Any help will be appreciated :slight_smile:

@samme please save me from the nothing I’ve become

Is the dark blue horizontal line at the bottom of your screenshot the physics body?

1 Like

Nah, that’s an invisible floor panel I’m using as an alternative to changing world boundaries. The telescope doesn’t seem to have a physics body despite me assigning it. It should just be a rectangle around it, right?

A couple things to help you on your way.

Firstly, You are adding the telescope as a static physics object, as you are passing true in, this.physics.add.existing(this.telescope, true);. This generally means that your telescope should not move. Since you are using overlap, you don’t really need it to be static anyway.

Secondly, you are setting the scale of the telescope, but you are not adjusting the size of the body. Unfortunately when you change the size of an image, the body does not adjust accordingly. Try using telescope.body.setSize(width, height) and telescope.body.setOffset(offsetX, offsetY) to match the sizes up. (You should probably set the telescope to start in the middle of the screen, so you can accurately position the body.)

Overall, you are not seeing the body because you are starting the telescope off the screen and as it moves in, only the image moves in because the body is static and staying put.

1 Like

Thank you!
I removed this line from my code: this.physics.add.existing(this.telescope, true); and that has helped make the hitbox appear onscreen, I’ll just fix the offset, since it doesn’t appear around the sprite, but a bit higher and to the left of the desired location.

The one thing I’m struggling to access now is the frame of the telescope. this.telescope.frame isn’t right, so I’ve been looking for alternatives. The object is always using the same spritesheet, so this.texture.key doesn’t quite give me the desired output. Any idea how to access which frame is being used specifically? I realised I should use .setFrame() later on, but I can’t trigger it, as I can’t get the current frame.

You’re close. To get the frame name, you’ll want to use: this.telescope.frame.name

1 Like

Awesome! now it works fully!
This is in the create function:

	//telescopes
	this.telescope = new Telescope(this, 1500, 520, 'telescope',this.choose([0,4,8])).setOrigin(0.5,1).setScale(1.7);
	this.physics.world.enable(this.telescope);
	this.telescope.body.setSize(250, 250);
	this.telescope.on("overlapstart", function() {
		overlapping = true;
		if (this.frame.name == 0){
			this.setFrame(2);
		}
		if (this.frame.name == 4){
			this.setFrame(6);
		}
		if (this.frame.name == 8){
			this.setFrame(10);
		}
	});
	this.telescope.on("overlapend", function() {
		overlapping = false;
		if (this.frame.name == 2){
			this.setFrame(0);
		}
		if (this.frame.name == 6){
			this.setFrame(4);
		}
		if (this.frame.name == 10){
			this.setFrame(8);
		}
	});

This is in the update function:

// Treat 'embedded' as 'touching' also
	if (this.telescope.body.embedded) {
		this.telescope.body.touching.none = false
	};

	var touching = !this.telescope.body.touching.none;
	var wasTouching = !this.telescope.body.wasTouching.none;
  
	if (touching && !wasTouching) this.telescope.emit("overlapstart");
	else if (!touching && wasTouching) this.telescope.emit("overlapend");

Thank you very much for your help