(Phaser 3 Arcade)2 个圆形物体之间的碰撞问题
(Phaser 3 Arcade) Issue with collisions between 2 circular bodies
我实例化了一堆在屏幕上移动的扩展 Phaser.Physics.Arcade.Sprite。当他们互相攻击时,一切正常,基本街机 body。
虽然,如果我添加“this.body.setCircle(200);” (或“this.setCircle(200);”顺便说一句,我不确定它们的构造函数中的区别)。
他们没有像我希望的那样平稳地偏转撞击,而是立即停止。
这是我的 class 的代码:
import Phaser from "phaser";
export default class Sheep extends Phaser.Physics.Arcade.Sprite {
target: Phaser.Math.Vector2 = new Phaser.Math.Vector2();
speed: number = 50;
reach: boolean = true;
constructor(scene: Phaser.Scene, x: number, y: number, spriteKey: string) {
super(scene, x, y, spriteKey);
this.setOrigin(0, 0);
scene.physics.add.existing(this);
scene.add.existing(this);
this.setCircle(5);
this.visible = false;
//this.scale = 0.05;
//this.setBounce(1);
}
setRandomTarget() {
this.target = new Phaser.Math.Vector2(
Math.random() * this.scene.scale.width,
Math.random() * this.scene.scale.height
);
}
preUpdate(time: number, delta: number) {
super.preUpdate(delta, time);
if (
this.reach ||
this.target.distance(new Phaser.Math.Vector2(this.x, this.y)) <=
this.speed
) {
this.setRandomTarget();
this.reach = false;
this.setHeading();
}
}
setHeading() {
let vPos = new Phaser.Math.Vector2(this.x, this.y);
let vTarget = this.target.clone();
let velocity = vTarget.subtract(vPos).normalize().scale(this.speed);
this.setVelocity(velocity.x, velocity.y);
}
}
下面是创建它们并将它们添加到场景的代码:
for (let i = 0; i < 10; i++) {
this.sheeps.push(
new Sheep(
this,
Math.round(Math.random() * width),
Math.round(Math.random() * height),
"sheep2"
)
);
}
let sheepGroup = this.physics.add.group(this.sheeps);
this.physics.add.collider(sheepGroup, sheepGroup);
结果如下:
Circular collision
Rectangular collision
你的问题的第一部分
如果您在构造函数中从 Phaser.Physics.Arcade.Sprite
扩展,您可以同时执行这两项操作,this.setCircle
(link documentation) or this.body.setCircle
(link documentation) 应该做同样的事情。
你的问题的第二部分 (查看下面的更新,解决方案)
为什么它不起作用,很难说,没有看到你的代码,但这是我诊断问题的方法:
打开物理调试设置(我假设碰撞盒有某种偏移)
var config = {
...
physics: {
default: 'arcade',
arcade: {
...
debug: true
}
},
};
检查浏览器控制台是否有错误(立即停止,表示可能有错误)
Update/Solution:
看完你的代码后,我不得不说问题出在行
let sheepGroup = this.physics.add.group(this.sheeps);
改成
let sheepGroup = this.add.group(this.sheeps);
它应该可以工作。移相器 group
的物理特性正在干扰 绵羊 .
的物理特性
这里是我用来测试的demo:
class Sheep extends Phaser.Physics.Arcade.Sprite {
constructor(scene, x, y, spriteKey) {
super(scene, x, y, spriteKey);
this.target = new Phaser.Math.Vector2();
this.speed = 50;
this.reach = true;
this.setOrigin(0, 0);
scene.add.existing(this);
scene.physics.add.existing(this);
this.setCircle(5);
this.visible = false;
//this.scale = 0.05;
this.setBounce(1);
}
setRandomTarget() {
this.target = new Phaser.Math.Vector2(
Math.random() * this.scene.scale.width,
Math.random() * this.scene.scale.height
);
}
preUpdate(time, delta) {
super.preUpdate(delta, time);
if (
this.reach ||
this.target.distance(new Phaser.Math.Vector2(this.x, this.y)) <=
this.speed
) {
this.setRandomTarget();
this.reach = false;
this.setHeading();
}
}
setHeading() {
let vPos = new Phaser.Math.Vector2(this.x, this.y);
let vTarget = this.target.clone();
let velocity = vTarget
.subtract(vPos)
.normalize()
.scale(this.speed);
this.setVelocity(velocity.x, velocity.y);
}
}
var config = {
type: Phaser.AUTO,
width: 400,
height: 200,
physics: {
default: 'arcade',
arcade: {
debug: true
}
},
scene: { create }
};
var controls;
var game = new Phaser.Game(config);
function create ()
{
this.sheeps = [];
for (let i = 0; i < 20
; i++) {
this.sheeps.push(
new Sheep(
this,
Math.round(Math.random() * 400),
Math.round(Math.random() * 200),
"sheep2"
)
);
}
let sheepGroup = this.add.group(this.sheeps);
this.physics.add.collider(sheepGroup, sheepGroup);
}
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
我实例化了一堆在屏幕上移动的扩展 Phaser.Physics.Arcade.Sprite。当他们互相攻击时,一切正常,基本街机 body。
虽然,如果我添加“this.body.setCircle(200);” (或“this.setCircle(200);”顺便说一句,我不确定它们的构造函数中的区别)。 他们没有像我希望的那样平稳地偏转撞击,而是立即停止。
这是我的 class 的代码:
import Phaser from "phaser";
export default class Sheep extends Phaser.Physics.Arcade.Sprite {
target: Phaser.Math.Vector2 = new Phaser.Math.Vector2();
speed: number = 50;
reach: boolean = true;
constructor(scene: Phaser.Scene, x: number, y: number, spriteKey: string) {
super(scene, x, y, spriteKey);
this.setOrigin(0, 0);
scene.physics.add.existing(this);
scene.add.existing(this);
this.setCircle(5);
this.visible = false;
//this.scale = 0.05;
//this.setBounce(1);
}
setRandomTarget() {
this.target = new Phaser.Math.Vector2(
Math.random() * this.scene.scale.width,
Math.random() * this.scene.scale.height
);
}
preUpdate(time: number, delta: number) {
super.preUpdate(delta, time);
if (
this.reach ||
this.target.distance(new Phaser.Math.Vector2(this.x, this.y)) <=
this.speed
) {
this.setRandomTarget();
this.reach = false;
this.setHeading();
}
}
setHeading() {
let vPos = new Phaser.Math.Vector2(this.x, this.y);
let vTarget = this.target.clone();
let velocity = vTarget.subtract(vPos).normalize().scale(this.speed);
this.setVelocity(velocity.x, velocity.y);
}
}
下面是创建它们并将它们添加到场景的代码:
for (let i = 0; i < 10; i++) {
this.sheeps.push(
new Sheep(
this,
Math.round(Math.random() * width),
Math.round(Math.random() * height),
"sheep2"
)
);
}
let sheepGroup = this.physics.add.group(this.sheeps);
this.physics.add.collider(sheepGroup, sheepGroup);
结果如下: Circular collision Rectangular collision
你的问题的第一部分
如果您在构造函数中从 Phaser.Physics.Arcade.Sprite
扩展,您可以同时执行这两项操作,this.setCircle
(link documentation) or this.body.setCircle
(link documentation) 应该做同样的事情。
你的问题的第二部分 (查看下面的更新,解决方案)
为什么它不起作用,很难说,没有看到你的代码,但这是我诊断问题的方法:
打开物理调试设置(我假设碰撞盒有某种偏移)
var config = { ... physics: { default: 'arcade', arcade: { ... debug: true } }, };
检查浏览器控制台是否有错误(立即停止,表示可能有错误)
Update/Solution:
看完你的代码后,我不得不说问题出在行
let sheepGroup = this.physics.add.group(this.sheeps);
改成
let sheepGroup = this.add.group(this.sheeps);
它应该可以工作。移相器 group
的物理特性正在干扰 绵羊 .
这里是我用来测试的demo:
class Sheep extends Phaser.Physics.Arcade.Sprite {
constructor(scene, x, y, spriteKey) {
super(scene, x, y, spriteKey);
this.target = new Phaser.Math.Vector2();
this.speed = 50;
this.reach = true;
this.setOrigin(0, 0);
scene.add.existing(this);
scene.physics.add.existing(this);
this.setCircle(5);
this.visible = false;
//this.scale = 0.05;
this.setBounce(1);
}
setRandomTarget() {
this.target = new Phaser.Math.Vector2(
Math.random() * this.scene.scale.width,
Math.random() * this.scene.scale.height
);
}
preUpdate(time, delta) {
super.preUpdate(delta, time);
if (
this.reach ||
this.target.distance(new Phaser.Math.Vector2(this.x, this.y)) <=
this.speed
) {
this.setRandomTarget();
this.reach = false;
this.setHeading();
}
}
setHeading() {
let vPos = new Phaser.Math.Vector2(this.x, this.y);
let vTarget = this.target.clone();
let velocity = vTarget
.subtract(vPos)
.normalize()
.scale(this.speed);
this.setVelocity(velocity.x, velocity.y);
}
}
var config = {
type: Phaser.AUTO,
width: 400,
height: 200,
physics: {
default: 'arcade',
arcade: {
debug: true
}
},
scene: { create }
};
var controls;
var game = new Phaser.Game(config);
function create ()
{
this.sheeps = [];
for (let i = 0; i < 20
; i++) {
this.sheeps.push(
new Sheep(
this,
Math.round(Math.random() * 400),
Math.round(Math.random() * 200),
"sheep2"
)
);
}
let sheepGroup = this.add.group(this.sheeps);
this.physics.add.collider(sheepGroup, sheepGroup);
}
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>