Aftersun Lotion
Aftersun Lotion

Reputation: 55

Make inward collision detection with phaser

enter image description here

What I need to achieve is the collision detection for the smaller hitbox inside player (protagonist) against the wall so that it gives a image of player being able to walk next to the wall. This should be pretty straightforward but the collision detection doenst work. Relevant parts are walls layer and hitbox sprote. Here is my code:

preload(){
  //all the assets here
}
create() {
  console.log('create method executed');


  const characterPositionInWorldMap = 3700;
  this.hitbox = this.physics.add.sprite(characterPositionInWorldMap, 250, null); // we need collision for this
  this.protagonist = this.physics.add.sprite(characterPositionInWorldMap, 250, 'protagonist');
  
   // Initialize the hitbox sprite for collision detection
  
  this.hitbox.setSize(10, 10); // Set hitbox size (adjust as needed)

  
  this.protagonist.setDepth(3);
  this.hitbox.setDepth(3);
  const map = this.make.tilemap({ key: 'map' });
  this.animatedTiles.init(map);
  this.physics.world.createDebugGraphic();

// Add the tilesets...



// Create layers from tilemap data using different tilesets
const groundLayer = map.createLayer('Groundlayer', darkTileset, 0, 0);
const waterLayer = map.createLayer('waterlayer', darkTileset, 0, 0);
const grassLayer = map.createLayer('grass_and_tree_layer', darkTileset, 0, 0);
const stoneLayer = map.createLayer('stones_n_stuff', darkTileset, 0, 0);

// Create hut layer using the hut tileset
const hutLayer = map.createLayer('hutLayer', hutTileset, 0, 0);
const transportlayer = map.createLayer('transportlayer', hutTileset, 0, 0);
const walls = map.createLayer('walls', hutTileset, 0, 0);


  // Adjust the depth of layers as needed
  groundLayer.setDepth(1);
  waterLayer.setDepth(0);
  grassLayer.setDepth(1);
  stoneLayer.setDepth(2);
  hutLayer.setDepth(3);
  walls.setDepth(4);
  transportlayer.setDepth(10);

  // Enable collision detection between player and walls layer
  const collidableTileIndexes = [
    1279,1278,1244,1225,1257,1267,1302,1302,1320,1305,1277,1298,1307,1288,1319,1320,1321,1225,1223,1244
];

  collidableTileIndexes.forEach(index => {
    map.setCollision(index, true, walls);
});


  //animations....
 
  // Enable physics for the protagonist
  this.physics.world.setBounds(0, 0, map.widthInPixels, map.heightInPixels);

  // Listen for collision between hitbox and walls
this.physics.add.collider(this.hitbox, walls, () => {
// Disable movement controls for the protagonist
//this.protagonist.setVelocity(0); // Stop the protagonist's movement
console.log("hitbox hit")
});

// Listen for when hitbox stops colliding with walls
this.physics.add.collider(this.hitbox, walls, () => {
// Re-enable movement controls for the protagonist
// You may need to adjust this depending on how your movement controls are implemented
// For example, if you're using velocity-based movement, reset the velocity to allow movement
this.protagonist.setVelocity(0); // Reset velocity
});

this.groundLayer = groundLayer;
this.waterLayer = waterLayer;
this.grassLayer = grassLayer;
this.stoneLayer = stoneLayer;
this.hutLayer = hutLayer;
this.walls = walls;
this.transportlayer = transportlayer;


 // Set up camera to follow the player
 this.cameras.main.startFollow(this.protagonist);

}

update() {
  // Reset velocity
  this.protagonist.setVelocity(0);
  
  this.physics.collide(this.hitbox, this.walls, this.handleWallCollision, null, this);
    // Update the hitbox sprite position to match the player sprite
    this.hitbox.setPosition(this.protagonist.x, this.protagonist.y);
    ...
}

Upvotes: 1

Views: 45

Answers (1)

winner_joiner
winner_joiner

Reputation: 14785

One issue I see, just reading the code is, that you are moving the hitbox yourself.
Arcade (and probably matter) Physics don't work when you move / set the position of the game object, since you are overriding the position calculation of the engine (and also the object can be set inside the other object).

How to solve your issue is not that straight forward, one solution that comes to mind, would be to simply use the hitbox/body of the player, and use the processCallback parameter (the 4th one) of the collide function to determine, if the player should collide or not (link to the documentation).

Depending on your usecase and how exact you need it, a simple check of relative position (ontop, below, left or right) and distance from the center of the two colliding objects could do the trick.

Upvotes: 0

Related Questions