我需要实现的是对玩家(主角)内部较小的撞击框与墙壁的碰撞检测,以便给出玩家能够在墙壁旁边行走的图像。这应该非常简单,但碰撞检测确实有效。相关部分是墙壁层和碰撞盒sprote。这是我的代码:
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);
...
}
只要阅读代码,就有一个问题是,您自己正在移动碰撞箱。
街机 (可能很重要) 当您移动/设置游戏对象的位置时,物理不起作用,因为您正在覆盖该位置。
如何解决您的问题并不是那么简单,就想到的解决方案而言,就是简单地使用玩家的碰撞箱,并使用
processCallback
函数的 collide
参数来确定玩家是否应该碰撞或不是(链接到文档)。
根据您的用例以及您需要的精确程度,简单检查两个碰撞对象的相对位置和距中心的距离就可以解决问题。