我正在制作一款涉及俄罗斯方 block 的游戏,但我在让方 block 落地方面遇到了困难。由于某种原因,这些 block 停在我用作地面的长而清晰的 Sprite 附近。
我使用的代码如下:
在创建方法中:
this.active = false;
this.activeBlock = null;
在更新方法中:
if (this.active == false){
this.cube = Math.floor((Math.random()* 7));
this.testblock = this.physics.add.sprite(608, 32, this.blocks[this.cube]);
this.testblock.body.immovable = true;
this.testblock.body.allowGravity = false;
this.physics.add.collider(this.testblock, this.walls);
this.physics.add.collider(this.p1, this.testblock);
this.activeBlock = this.testblock;
this.active = true;
}
this.activeBlock.y = this.testblock.y + 0.1;
if(Phaser.Input.Keyboard.JustDown(this.keyA) && this.activeBlock.x != 352) {
this.activeBlock.x = this.activeBlock.x - 64;
}
if(Phaser.Input.Keyboard.JustDown(this.keyD) && this.activeBlock.x != 928) {
this.activeBlock.x = this.activeBlock.x + 64;
}
if (this.checkCollision(this.activeBlock, this.ground)){
this.activeBlock = null;
this.active = false;
}
这是我经常使用的 checkCollision 方法:
checkCollision(a, b) {
// simple AABB checking
if ((a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.height + a.y > b.y) ) {
return true;
}
else {
return false;
}
}
我不知道我做错了什么。谁能告诉一下吗?
如果有帮助的话,我正在使用街机物理原理在 VSCode 中使用 Phaser 3。
更新:
if (this.active == false){
this.cube = Math.floor((Math.random()* 7));
this.testblock = this.physics.add.sprite(608, 32, this.blocks[this.cube]);
this.testblock.body.immovable = true;
//this.testblock.body.allowGravity = false;
this.testblock.body.setGravity(0.1);
this.physics.add.collider(this.walls, this.testblock, this.callbackOnCollision, null, this);
this.physics.add.collider(this.p1, this.testblock);
this.activeBlock = this.testblock;
this.active = true;
}
//this.activeBlock.y = this.activeBlock.y + 0.1;
callbackOnCollision(floor, block){
this.physics.world.disable( block)
this.activeBlock = null;
this.active = false;
}
这是我在阅读建议后添加的代码。
它确实使方 block 更接近地面,但仍然没有到达底部。此外,控制方 block 重力的新线不起作用,因为方 block 现在只受到正常重力的影响。
我添加代码时是否搞砸了?
最佳答案
问题在于 checkCollision
函数,因为它仅通过考虑以下因素来检查命中:x
,y
,width
和 height
,它不采用其他属性,例如 origin
。 (参见下面的示例,右侧)
我建议仅使用物理引擎的内置collider
功能,也可以在以下示例中看到
btw.: moving the objects yourself, by setting
x
ory
, like thisthis.activeBlock.y = this.testblock.y + 0.1;
, will cause the collision system of the physics engine not to function correctly, if the gravity is to slow/fast just set a different value globaly in the config, or if you only need different gravity for some objects, set it directly, withsetGravityY
(link to documenation).
简短演示:
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 100 },
debug: true
}
},
scene: {
create,
update
},
banner: false
};
let blockCustomCollision;
let floor;
let label;
let blockCollision2;
function create () {
label = this.add.text(10,10, 'Left physics collision /"
+ " Right custom collision (+ slow gravity)')
.setScale(1)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.make.graphics();
graphics.fillStyle(0xffffff);
graphics.fillRect(0, 0, 10, 10);
graphics.generateTexture('img', 10, 10);
let blockCollision = this.physics.add.image(50, 10, 'img');
blockCustomCollision = this.physics.add.image(200, 10, 'img')
.setOrigin(1)
.setGravityY(-50);
this.add.text(90, 95, '<- Stop mid Air ')
.setScale(1)
.setOrigin(0, .5)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
blockCollision2 = this.physics.add.image(80, 10, 'img')
.setGravityY(100);
floor = this.add.rectangle(0, config.height-10, config.width, 20, 0xcdcdcd)
.setOrigin(0, 0);
this.physics.add.existing(floor, true);
this.physics.add.collider(floor, blockCollision, onCollision, null, this);
this.physics.add.collider(floor, blockCollision2, onCollision, null, this);
}
function onCollision(floor, block){
label.setText(' Executes on Collision');
this.physics.world.disable( block)
}
function update(){
if (checkCollision(blockCustomCollision, floor)){
this.physics.world.disable( blockCustomCollision)
}
if(blockCollision2.body.velocity.y > 1 && blockCollision2.body.y >= 90){
blockCollision2.body.setAllowGravity(false);
blockCollision2.body.setVelocity(0);
}
}
function checkCollision(a, b) {
// simple AABB checking
if ((a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.height + a.y > b.y) ) {
return true;
}
else {
return false;
}
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f2829a93819780b2c1dcc7c7dcc0" rel="noreferrer noopener nofollow">[email protected]</a>/dist/phaser.js"></script>
更新:
如果你想在碰撞时触发函数,你可以使用collider
函数的回调函数(参数3)。上面的示例也已更新
this.physics.add.collider(floor, blockCollision, callbackOnCollision);
Update 2:
Demo Code was update to show stopping in midair, with a defined
y
height in theupdate
function.
关于javascript - Phaser 3 俄罗斯方 block 克隆,但方 block 不会落地,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74415251/