英文:
how can I set up a T-shaped hitbox for an umbrella?
问题
我已经开始学习Phaser 3.60,不幸的是,我陷入了困境。我找不到设置碰撞框的方法。我想要的是让雨滴从顶部落下,有一个伞,当雨滴落在伞上时,它会取消雨滴并生成一个新的雨滴。这些机制已经写好,但我无法重新编写碰撞框。我希望你能帮助我。我将发送给你一些我的代码。
伞:
export class Umbrella extends Phaser.Physics.Arcade.Sprite {
private raindrops: Phaser.Physics.Arcade.Group;
private debugGraphic: Phaser.GameObjects.Graphics;
constructor(
scene: Phaser.Scene,
x: number,
y: number,
raindrops: Phaser.Physics.Arcade.Group
) {
super(scene, x, y, "umbrella");
scene.add.existing(this);
this.scene.physics.world.enable(this);
this.debugGraphic = scene.add.graphics();
(this.body as Phaser.Physics.Arcade.Body).allowGravity = false;
const hitboxWidth = 100;
const hitboxHeight = 100;
const topHeight = hitboxHeight * 0.25;
const bottomHeight = hitboxHeight - topHeight;
this.raindrops = raindrops;
}
public mouseMove(input: Phaser.Input.InputPlugin): void {
var pointer = input.activePointer;
if (pointer.isDown) {
this.x = pointer.x;
this.y = pointer.y;
}
input.on("pointermove", (pointer) => {
this.x = pointer.x;
this.y = pointer.y;
this.drawHitbox(this.x, this.y);
});
}
private drawHitbox(x: number, y: number): void {
const hitbox = this.body as Phaser.Physics.Arcade.Body;
this.debugGraphic.clear();
this.debugGraphic.lineStyle(2, 0xff0000);
this.debugGraphic.strokeRect(
x - hitbox.width / 2,
y - hitbox.height / 2,
hitbox.width,
hitbox.height
);
}
}
MainGame Scene:
碰撞事件:
// 检测雨滴和伞的碰撞
this.physics.add.overlap(
this.umbrella,
this.raindrops,
this.collectDrop,
null,
this
);
碰撞检测:
private collectDrop(
umbrella: Phaser.Physics.Arcade.Sprite,
drop: Phaser.Physics.Arcade.Sprite
): void {
// 从组中移除雨滴
this.raindrops.remove(drop, true, true);
// 生成一个新的雨滴
const newDrop = new Raindrop(
this,
Math.floor(Math.random() * Number(this.game.config.width)),
-100
);
this.raindrops.add(newDrop);
}
希望这对你有所帮助。
英文:
I have started learning Phaser 3.60 and unfortunately I am stuck. I can't find a way to set up the hitbox. Exactly what I would like is to have the raindrop falling from the top down and have an umbrella that when the raindrop falls on it, it cancels the raindrop and generates a new one. The mechanics are written but I can't rewrite the hitbox. I would like your help with this. I will send you a few lines of my code.
Umbrella:
export class Umbrella extends Phaser.Physics.Arcade.Sprite {
private raindrops: Phaser.Physics.Arcade.Group;
private debugGraphic: Phaser.GameObjects.Graphics; // debugGraphic tulajdonság hozzáadása
constructor(
scene: Phaser.Scene,
x: number,
y: number,
raindrops: Phaser.Physics.Arcade.Group
) {
super(scene, x, y, "umbrella");
scene.add.existing(this);
this.scene.physics.world.enable(this); // Engedélyezzük a fizikai testet az esernyő Sprite-hoz
// Inicializáljuk a debugGraphic-t
this.debugGraphic = scene.add.graphics();
(this.body as Phaser.Physics.Arcade.Body).allowGravity = false; // Kikapcsoljuk a gravitációt
const hitboxWidth = 100; // A hitbox szélessége
const hitboxHeight = 100; // A hitbox magassága
const topHeight = hitboxHeight * 0.25; // A felső téglalap magassága (25%)
const bottomHeight = hitboxHeight - topHeight; // Az alsó téglalap magassága
this.raindrops = raindrops;
}
public mouseMove(input: Phaser.Input.InputPlugin): void {
// Itt mozgatjuk az egérrel az esernyőt ha kattintunk
var pointer = input.activePointer;
if (pointer.isDown) {
this.x = pointer.x;
this.y = pointer.y;
}
// Itt mozgatjuk az egérrel az esernyőt ha simán mozgatjuk.
input.on("pointermove", (pointer) => {
this.x = pointer.x;
this.y = pointer.y;
this.drawHitbox(this.x, this.y);
});
}
private drawHitbox(x: number, y: number): void {
const hitbox = this.body as Phaser.Physics.Arcade.Body;
// Rajzolás a debugGraphic segítségével
this.debugGraphic.clear();
this.debugGraphic.lineStyle(2, 0xff0000); // Vonalstílus beállítása (2 pixel vastag, piros szín)
this.debugGraphic.strokeRect(
x - hitbox.width / 2,
y - hitbox.height / 2,
hitbox.width,
hitbox.height
);
}
}
MainGame Scene:
collision event:
//Az esőcsepp és az esernyő detektálása.
this.physics.add.overlap(
this.umbrella,
this.raindrops,
this.collectDrop,
null,
this
);
}
Collision detection:
private collectDrop(
umbrella: Phaser.Physics.Arcade.Sprite,
drop: Phaser.Physics.Arcade.Sprite
): void {
// // Eltávolítjuk a cseppet a csoportból
this.raindrops.remove(drop, true, true);
// Generálunk egy új esőcseppet
const newDrop = new Raindrop(
this,
Math.floor(Math.random() * Number(this.game.config.width)),
-100
);
this.raindrops.add(newDrop);
}
答案1
得分: 0
如@zenly提到的,细长条足够了。要创建它,你可以使用物理体的setSize
和setOffset
函数,如下演示所示(文档链接)。
顺便说一下: 你实际上不需要创建一个调试图形对象,因为Phaser提供了一个名为config的属性
debug
,只需将其设置为true
即可。
这里是一个简短的演示:
document.body.style = 'margin:0;';
class Umbrella extends Phaser.Physics.Arcade.Sprite {
constructor( scene, x, y, raindrops ) {
super(scene, x, y, "umbrella");
scene.add.existing(this);
this.scene.physics.world.enable(this);
this.body.allowGravity = false;
// 碰撞箱的大小
this.setSize(80, 5);
// 碰撞箱的偏移
this.setOffset(-25, -20);
const hitboxWidth = 100;
const hitboxHeight = 100;
const topHeight = hitboxHeight * 0.25;
const bottomHeight = hitboxHeight - topHeight;
this.raindrops = raindrops;
}
//...
}
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
// 显示调试碰撞箱
debug: true
}
},
scene: { create }
};
function create () {
let i = new Umbrella(this, 100, 100, []);
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
如果你想创建一个T形碰撞箱。我可以创建一个自定义的Phaser容器,并添加两个物理对象/物体,然后使用上述提到的函数来定位它们。
英文:
As @zenly mentioned thin-bar is enough. To create this you can use the functions setSize
and setOffset
of the physics body, shown in the following demo (link to the documentation).
> btw.: you don't really need, to create a debug graphics object, since phaser offers it out-of-the-box, with the config property debug
, just set it to true
.
Here a short demo:
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
document.body.style = 'margin:0;';
class Umbrella extends Phaser.Physics.Arcade.Sprite {
constructor( scene, x, y, raindrops ) {
super(scene, x, y, "umbrella");
scene.add.existing(this);
this.scene.physics.world.enable(this);
this.body.allowGravity = false;
// size of hitbox
this.setSize(80, 5);
// offset of hitbox
this.setOffset(-25, -20);
const hitboxWidth = 100;
const hitboxHeight = 100;
const topHeight = hitboxHeight * 0.25;
const bottomHeight = hitboxHeight - topHeight;
this.raindrops = raindrops;
}
//...
}
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
// shows debug hitbox
debug: true
}
},
scene: { create }
};
function create () {
let i = new Umbrella(this, 100, 100, []);
}
new Phaser.Game(config);
<!-- language: lang-html -->
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
<!-- end snippet -->
> If you want the create a T-shaped hitbox. I could create a custom Phaser Container and add two physics objects/bodies, and position the with the above mentioned functions.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论