我正在尝试用phaser.js制作一个迷你游戏。在我的想法中。如果它们粘在一起, Sprite 对象可以与静态 Sprite 碰撞并持续执行所需的效果。但是,当我使用 this.physicals.add.collider 处理它们时,回调函数只运行一次。
搜索API文档。我发现触摸事件可以通过object.body.touching
来判断。但看到了也只能返回面子。所以我想知道如何获取接触 Sprite 特定方向的对象?或者该功能需要方便处理?
感谢您的帮助。
最佳答案
如果您在移相器中需要更多“详细”/“更好”的物理函数,您可以使用 matterjs
物理引擎。
(它与arcade
引擎一样简单,至少设置起来)
使用matterjs
有更多选项,例如“碰撞事件”,使用matter
你可以使用事件collisionactive
。
( link to the documentation )
collisionactive
只要两个碰撞对象接触就会执行。
这样您就可以知道接触的确切物体。 (如果您需要方向,您可以通过物体的 x
和 y
位置,或者物体的 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/