javascript - 如何获取正在触摸特定 Sprite 的目标

标签 javascript game-engine phaser-framework

我正在尝试用phaser.js制作一个迷你游戏。在我的想法中。如果它们粘在一起, Sprite 对象可以与静态 Sprite 碰撞并持续执行所需的效果。但是,当我使用 this.physicals.add.collider 处理它们时,回调函数只运行一次。

搜索API文档。我发现触摸事件可以通过object.body.touching来判断。但看到了也只能返回面子。所以我想知道如何获取接触 Sprite 特定方向的对象?或者该功能需要方便处理?

感谢您的帮助。

最佳答案

如果您在移相器中需要更多“详细”/“更好”的物理函数,您可以使用 matterjs 物理引擎。
(它与arcade引擎一样简单,至少设置起来)

使用matterjs有更多选项,例如“碰撞事件”,使用matter你可以使用事件collisionactive( link to the documentation )

collisionactive 只要两个碰撞对象接触就会执行。

这样您就可以知道接触的确切物体。 (如果您需要方向,您可以通过物体的 xy 位置,或者物体的 velocity 来找到它。影响)

这里是来自官方网站的演示,显示 collisionstart 事件 https://phaser.io/examples/v3/view/physics/matterjs/collision-event

这是一个带有 matter 的小演示:

// Minor formating for stackoverflow
document.body.style = "display: flex;flex-direction: column;";  

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 153,
    backgroundColor: '#1b1464',
    physics: {
        default: 'matter',
        matter: {
          debug:true,
          gravity:{y:0, x:0}
        }
    },
    scene: {
        create: create
    }
};

var game = new Phaser.Game(config);

var counter = 0;
var gOverlay;
function create ()
{
    var blockA = this.matter.add.image(50, 80, 'block1');

    var blockB = this.matter.add.image(300, 80, 'block1').setStatic(true);
    var text = this.add.text(10,10, 'Not touching')
    blockA.setVelocityX(3);
    
    
    gOverlay = this.add.graphics();

    this.matter.world.on('collisionstart', function (event, bodyA, bodyB) {
        text.setText(text.text + '\nHIT')
        drawDirectionArrow(bodyA, bodyB)
    });

    this.matter.world.on('collisionactive', function (event, bodyA, bodyB) {
        text.setText(`Touching: ${counter++}`)
        if(counter > 60 ) {
            counter = 0;
            blockA.setVelocityX(-2);
        }
    });

    this.matter.world.on('collisionend', (function (event, bodyA, bodyB) {
        text.setText(text.text + '\nNot touching');
        gOverlay.clear();
        this.time.delayedCall(2000, _ => blockA.setVelocityX(5)); 
    }).bind(this));
}

function drawDirectionArrow(a, b){
  gOverlay.clear();
  
  gOverlay.fillStyle( 0xFF00FF);
  gOverlay.fillTriangle(a.position.x, a.position.y, b.position.x, b.position.y - 10, b.position.x, b.position.y + 10);
  
}
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0c0d8d1c3d5c2f0839e85859e82" rel="noreferrer noopener nofollow">[email protected]</a>/dist/phaser.js">
</script>

更新:
如果您需要/想要使用arcade物理功能,这里有一个类似的演示,其中有一个小解决方法,使用第二个物理对象来检查重叠。

街机 - 物理解决方法 - 演示:

// Minor formating for stackoverflow
document.body.style = "display: flex;flex-direction: column;";  

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 153,
    backgroundColor: '#1b1464',
    physics: {
        default: 'arcade',
        arcade: {
          debug:true,
        }
    },
    scene: {
        create: create
    }
};

var game = new Phaser.Game(config);

var counter = 0;
var gOverlay;

function create () {
    var blockA = this.physics.add.image(50, 80, 'block1').setOrigin(.5);
    var blockB = this.physics.add.image(300, 80, 'block1').setOrigin(.5);
    
    // Helper
    var blockBx = this.add.rectangle(300, 80, 34, 34);
    
    this.physics.add.existing(blockBx);
    
    blockB.setImmovable();
    
    var text = this.add.text(10,10, 'Not touching')
    blockA.setVelocityX(50);
    
    gOverlay = this.add.graphics();
    
    this.physics.add.collider(blockA, blockB,  function ( bodyA, bodyB) {
        drawDirectionArrow(bodyA, bodyB);
    })
    
    this.physics.add.overlap(blockA, blockBx, function ( bodyA, bodyB) {
        text.setText(`Touching: ${counter++}`);
        if(counter > 60 ) {
            counter = 0;
            gOverlay.clear();
            blockA.setVelocityX(-50);
            text.setText('Not touching');
            this.time.delayedCall(2000, _ => blockA.setVelocityX(50)); 
        }
    }, null, this);
}

function drawDirectionArrow(a, b){
  gOverlay.clear();
  
  gOverlay.fillStyle( 0xFF00FF);
  gOverlay.fillTriangle(a.x, a.y, b.x, b.y - 10, b.x, b.y + 10);
  
}
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bdcdd5dcced8cffd8e938888938f" rel="noreferrer noopener nofollow">[email protected]</a>/dist/phaser.js">
</script>

关于javascript - 如何获取正在触摸特定 Sprite 的目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72009547/

相关文章:

javascript - 与 Phaser Arcade 物理引擎的碰撞

phaser-framework - 如何正确更改 sprite 上的 z-index?

javascript - 分块算法帮助 JS

javascript - Hello Analytics 示例生成 403 错误

javascript - 如何从后面的代码传递 JavaScript 函数中的逗号分隔字符串?

artificial-intelligence - 多个 AI 引擎之间的进程间通信

android - AndEngine是游戏引擎吗?

c++ - C 语言还在游戏引擎中被广泛使用吗?

javascript - Phaser JS 走上瓷砖楼梯

javascript - Uncaught Error : define cannot be used indirect