Phaser中,组与瓦片层之间的碰撞检测
在Phaser中,如何检测一个group与一个瓦片层之间的碰撞?一个可能的原因是例如要删除击中墙面的子弹。理论上很简单,只要使用collider就可以,但似乎没有任何方法奏效。我已经尝试使用overlap代替collide,把子弹设为物理组,使用world.addCollider等等。
有些瓦片通过以下这一行设置了碰撞:
this.groundLayer.setCollisionByProperty({ collides: true });
这是通过从Tiled生成的JSON文件中获取collide属性实现的。因此,玩家与瓦片之间的碰撞工作正常。
有些瓦片被设置为与以下这一行发生碰撞:
this.groundLayer.setCollisionByProperty({ collides: true });
by getting the collide property from a JSON file produced by Tiled. So collision works fine between the player and the tiles.
有问题的代码如下:
this.physics.add.collider(
this.bullets,
this.groundLayer,
(bullet, tile) =>
{
console.log("hit");
bullet.setActive(false);
bullet.setVisible(false);
});
解决方案
问题很可能出在你在 collider 函数中使用了 "wrong" 参数。在这个phaser版本中,似乎总是物理组的第一个参数作为第一个参数(见下面的示例)。你可以把这行 this.physics.add.collider(layer, this.bullets,...) 仅在 layer 和 this.bullets 中互换,代码仍然能工作。
看起来像是一个框架Bug (对我而言,但我还没有读文档)。
Apart from that it seems to work, or am I missing something?
btw.: 我刚刚重新读了你的问题,groundLayer 听起来像地板而不是墙,并且如果都设定为碰撞,由于会立即发生碰撞,屏幕上不会显示任何内容。
document.body.style = 'margin:0;';
var config = {
width: 536 /8,
height: 42,
zoom: 4.5,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 0 },
}
},
scene: { create },
};
function create () {
// HELPER CODE FOR DEMO -- START
let graphics = this.make.graphics();
graphics.fillStyle(0x00ff00);
graphics.fillRect(8, 0, 8, 8);
graphics.fillStyle(0xff0000);
graphics.fillRect(16, 0, 8, 8);
graphics.fillStyle(0xff0000);
graphics.fillRect(24, 0, 8, 8);
graphics.generateTexture('tiles', 8*4, 8);
graphics.fillStyle( 0xff0000 );
graphics.fillRect(0, 0, 2, 2);
graphics.generateTexture(`bullet`, 2, 2);
// HELPER CODE FOR DEMO -- END
var data = [
[1,1,1,1,1], [1,0,0,0,1], [1,0,0,0,1], [1,0,0,0,1], [1,1,1,1,1], ]
var map = this.make.tilemap({ data, tileWidth: 8, tileHeight: 8 });
var tiles = map.addTilesetImage('tiles');
var layer = map.createLayer(0, tiles, 0, 0);
layer.setCollision(1);
this.bullets = this.physics.add.group({
key: 'bullet',
repeat: 0,
setXY: { x: 20, y: 20, stepX: 0}
});
this.bullets.setVelocityX(-10);
// seems like first to parameters can be swapped
this.physics.add.collider(layer, this.bullets, (bullet, tile) =>
{
console.info(bullet, tile);
// destroy bullet
bullet.setActive(false).setVisible(false).stop();
bullet.body.enabled = false;
// respawn bullet for DEMO
let newBullet = this.bullets.getFirstDead(false);
newBullet.setActive(true).setVisible(true).setPosition(20, 20).setVelocityX(-10);
newBullet.body.enable = true;
});
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。