Phaser.js两个图层之间的坐标碰撞

huangapple go评论75阅读模式
英文:

Phaser.js coordinate collisions between two layers

问题

我有两个图层,objLayerBGLayer

所以,这座木桥是非碰撞的,允许玩家通过,但是桥下的水是碰撞的,不允许玩家通过。

假设我不能只是替换水砖块,因为我需要桥可以被移除,而水仍然显示在下面,那么我如何让玩家穿过桥和水,但不只是水?

编辑:
我正在使用一个用于碰撞的 tiled 瓦片集属性,因为我不仅需要与水瓦片碰撞。

this.BGLayer.setCollisionByProperty({ collides: true });
this.objLayer.setCollisionByProperty({ collides: true });
const debugGraphics = this.add.graphics().setAlpha(0.75);
this.worldLayer.renderDebug(debugGraphics, {
  tileColor: null, // 不碰撞的瓦片颜色
  collidingTileColor: new Phaser.Display.Color(243, 134, 48, 255), // 碰撞瓦片的颜色
  faceColor: new Phaser.Display.Color(40, 39, 37, 255), // 碰撞边缘的颜色
});

所以我在碰撞回调中添加了这个函数,

this.physics.add.collider(this.player, this.BGLayer);
this.physics.add.collider(this.player, this.objLayer, function () {
  let tile = this.objLayer.getTileAtWorldXY(this.player.x, this.player.y);
  if (tile != null && tile.index == 16) {
    console.log("bridge");
    return false;
  }
  return true;
});

但是,如果放在 BGLayer 中,它会出现错误,放在 obj 层中也没有任何作用?

英文:

So, I have two layers, objLayer, and BGLayer

Phaser.js两个图层之间的坐标碰撞

So, the wooden bridge, is non colliding, allowing the player to pass through, however, the water underneath it is colliding, and will not let the player pass through.

Assuming I cant just replace the water tile, because I need the bridge to be removable with the water still showing below, how can I Make the player cross the bridge, and the water, but not just water?

EDIT:
I'm using a tiled tileset property for collisions, as I have more than just water tiles to collide with

this.BGLayer.setCollisionByProperty({ collides: true });
this.objLayer.setCollisionByProperty({ collides: true });
const debugGraphics = this.add.graphics().setAlpha(0.75);
       this.worldLayer.renderDebug(debugGraphics, {
        tileColor: null, // Color of non-colliding tiles
        collidingTileColor: new Phaser.Display.Color(243, 134, 48, 255), // Color of colliding tiles
        faceColor: new Phaser.Display.Color(40, 39, 37, 255), // Color of colliding face edges
      });

So I added the function in collide callback,

this.physics.add.collider(this.player, this.BGLayer);
    this.physics.add.collider(this.player, this.objLayer, function () {
      let tile = this.objLayer.getTileAtWorldXY(this.player.x, this.player.y);
      if (tile != null && tile.index == 16) {
        console.log("bridge")
        return false;
      }
      return true;
    });

However it gives a bug if put in BGLayer, and putting it in obj layer also does nothing?

答案1

得分: 1

可以使用collider函数的processCallback(详细信息请参考Phaser文档)。

在该函数中,您可以检查玩家是否位于桥瓷砖上。如果是,则processCallback函数应该返回false,否则返回true

...
this.physics.add.collider(player, water, collideCallback, processCallback, this);
...

processCallback可以看起来像这样:

function processCallback(){
    let tile = objLayer.getTileAtWorldXY(player.x, player.y);
    if (tile && tile.index == BRIDGE_TILE_INDEX){
        return false;
    }
    return true;
}

更新:

根据您的代码进行了适应:

this.physics.add.collider(this.player, this.objLayer, function (){
        // ... 您可以放置一些代码
    }, 
    function () {
        let tile = this.objLayer.getTileAtWorldXY(this.player.x, this.player.y);
        if (tile != null && tile.index == 16) {
            console.log("bridge");
            return false;
         }
         return true;
 });
英文:

Well you can use the processCallback of the collider function (details phaser docs).

In that function you can check, if the player is on a bridge-tile. if so the processCallback function should return false in all other cases return true.

<!-- langauge: lang-js -->

...
this.physics.add.collider( player, water, collideCallback, processCallback, this);
...

The processCallback could look something like this:

<!-- langauge: lang-js -->

function processCallback(){
    let tile = objLayer.getTileAtWorldXY(player.x, player.y);
    if ( tile &amp;&amp; tile.index == BRIDGE_TILE_INDEX ){
        return false;
    }
    return true;
}

Update:

Example adapted to your code:

this.physics.add.collider(this.player, this.objLayer, function (){
        // ... you could put some code
    }, 
    function () {
        let tile = this.objLayer.getTileAtWorldXY(this.player.x, this.player.y);
        if (tile != null &amp;&amp; tile.index == 16) {
            console.log(&quot;bridge&quot;)
            return false;
         }
         return true;
 });

huangapple
  • 本文由 发表于 2023年6月22日 13:48:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76528901.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定