Phaser 3 对撞机发射无穷无尽
Phaser 3 collider fires endless
我尝试为一款弹跳 3 次后应该消失的游戏制作弹跳子弹。
我认为这很简单,我给了我的子弹一个值为 3 的变量,并在我的子弹平台对撞机中将它减少了一个。
不行后用console.log()检查变量,发现变量在不断减小。
我测试了我的其他对撞机,发现只有子弹平台对撞机可以做到这一点,
而玩家平台、敌人平台、子弹玩家和子弹敌人对撞机则没有。
此外,当子弹击中平台时,我的销毁子弹的功能奇怪地工作正常。
我的子弹只有在击中平台时才会被摧毁。
有没有人知道如何解决这个问题?
编辑:
我为我的游戏创建了一个 Github 存储库,以便更好地了解。
(至少我希望我做到了,我以前没有用过 Github。)
https://github.com/Kiroho/Game
编辑2:
经过测试,我发现这一定与我使用 ammoGroup class.
的方式有关
我发现,如果我通过 ammoGroup(通过 createMultiple)创建子弹,对撞机开始为每颗子弹发射,直到我至少射击一次。
所有现有子弹发射一次后,一切正常,碰撞器按预期发射 -> 仅在碰撞时发射。
我的子弹平台对撞机
this.scene.physics.add.collider(this.scene.platforms, this.scene.playerProjectiles_Bounce, function (platform, projectile) {
//destoryProjectile(projectile);
console.log("hit");
});
弹药小组。我用它们作为每件武器的“杂志”
class AmmoGroup extends Phaser.Physics.Arcade.Group {
constructor(scene) {
super(scene.physics.world, scene);
}
fire(x, y, direction) {
const projectile = this.getFirstDead(false);
if (projectile) {
projectile.fire(x, y, direction);
}
}
loadAmmo(ammoIndex) {
this.clear();
if (ammoIndex == 1) {
this.classtype = Blaster;
}
else if (ammoIndex == 2) {
this.classtype = BlasterBig;
}
else if (ammoIndex == 3) {
this.classtype = Granade;
}
else if (ammoIndex == 4) {
this.classtype = Granade;
}
else if (ammoIndex == 0) {
this.classtype = Laser;
}
this.createMultiple({
classType: this.classtype,
frameQuantity: 20,
active: false,
visible: false,
key: ['ballAnim', 'kugel']
})
}
}
子弹class
class Granade extends Phaser.Physics.Arcade.Sprite {
constructor(scene, x, y) {
super(scene, x, y, 'kugel');
this.dmg = 20;
this.enemyHit = [];
this.bounceCounter = 3;
}
fire(x, y, direction) {
this.body.reset(x, y);
this.body.setGravityY(-1000);
this.setBounce(1);
this.setActive(true);
this.setVisible(true);
this.setVelocityY(WeaponConst.VELOCITY_Y_GRENADE);
if (direction == "left") {
this.setVelocityX(WeaponConst.VELOCITY_X_GRENADE * -1);
}
else if (direction == "up") {
this.setVelocityY(WeaponConst.VELOCITY_Y_GRENADE * 2);
this.setVelocityX(0);
}
else {
this.setVelocityX(WeaponConst.VELOCITY_X_GRENADE);
}
}
preUpdate(time, delta) {
super.preUpdate(time, delta);
if (!this.scene.cameras.main.worldView.contains(this.x, this.y)) {
this.enemyHit = [];
this.setActive(false);
this.setVisible(false);
}
}
}
补充:
玩家(和敌人)有一个武器对象。
这个武器对象有一个 ammoGroup 对象并设置它的射弹,射击时的速度,将它分配给组等等。
class Weapon {
constructor(scene) {
this.scene = scene;
this.type = null;
this.attackRate = null;
this.attackRange = null;
this.ammoGroup = new AmmoGroup(this.scene.scene, 1)
this.direction = null;
}
chooseWeapon(type) {
if (type == 'Blaster') {
this.setUpWeapon(
WeaponConst.TYPE_BLASTER,
WeaponConst.ATK_RATE_BLASTER,
WeaponConst.VELOCITY_X_BLASTER,
WeaponConst.VELOCITY_Y_BLASTER,
WeaponConst.AMMO_GROUP_BLASTER
);
console.log("Blaster choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_Normal);
}
else if (type == 'BlasterBig') {
this.setUpWeapon(
WeaponConst.TYPE_BLASTER_BIG,
WeaponConst.ATK_RATE_BLASTER_BIG,
WeaponConst.VELOCITY_X_BLASTER_BIG,
WeaponConst.VELOCITY_Y_BLASTER_BIG,
WeaponConst.AMMO_GROUP_BLASTER_BIG
);
console.log("BlasterBig choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_PierceEnemies);
}
else if (type == 'Grenade') {
this.setUpWeapon(
WeaponConst.TYPE_GRENADE,
WeaponConst.ATK_RATE_GRENADE,
WeaponConst.VELOCITY_X_GRENADE,
WeaponConst.VELOCITY_Y_GRENADE,
WeaponConst.AMMO_GROUP_GRENADE
);
console.log("Grenade choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_Bounce);
}
else if (type == 'GrenadeBig') {
this.setUpWeapon(
WeaponConst.TYPE_GRENADE_BIG,
WeaponConst.ATK_RATE_GRENADE_BIG,
WeaponConst.VELOCITY_X_GRENADE_BIG,
WeaponConst.VELOCITY_Y_GRENADE_BIG,
WeaponConst.AMMO_GROUP_GRENADE_BIG
);
console.log("GrenadeBig choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_PierceEnemies);
}
else if (type == 'Laser') {
this.setUpWeapon(
WeaponConst.TYPE_LASER,
WeaponConst.ATK_RATE_LASER,
WeaponConst.VELOCITY_X_LASER,
WeaponConst.VELOCITY_Y_LASER,
WeaponConst.AMMO_GROUP_LASER
);
console.log("Laser choosen");
this.scene.scene.enemyProjectiles_Normal.add(this.ammoGroup);
this.scene.scene.enemyProjectiles_PiercePlayer.remove(this.ammoGroup);
this.scene.scene.enemyProjectiles_PierceAll.remove(this.ammoGroup);
}
}
setUpWeapon(type, attackRate, velocityX, velocityY, ammoGroup ) {
this.type = type;
this.attackRate = attackRate;
this.velocityX = velocityX;
this.velocityY = velocityY;
this.ammoGroup.loadAmmo(ammoGroup);
//this.scene.scene.enemyProjectiles_Normal.add(this.ammoGroup);
}
fire(x, y, direction) {
this.ammoGroup.fire(x, y, direction);
}
assignToGroup(group) {
this.scene.scene.playerProjectiles_Normal.remove(this.ammoGroup);
this.scene.scene.playerProjectiles_PierceEnemies.remove(this.ammoGroup);
this.scene.scene.playerProjectiles_PierceAll.remove(this.ammoGroup);
this.scene.scene.playerProjectiles_Bounce.remove(this.ammoGroup);
group.add(this.ammoGroup)
}
}
我发现我必须在创建时禁用子弹 objects 的 body,否则碰撞器会触发。我不知道为什么,但这似乎是(或多或少)众所周知的事情。虽然 body.checkCollision.none=true 有效,但使用 body.enable = false 禁用 body 的物理可能是更好的解决方案,因为它禁用所有物理而不仅仅是碰撞。
我尝试为一款弹跳 3 次后应该消失的游戏制作弹跳子弹。 我认为这很简单,我给了我的子弹一个值为 3 的变量,并在我的子弹平台对撞机中将它减少了一个。
不行后用console.log()检查变量,发现变量在不断减小。 我测试了我的其他对撞机,发现只有子弹平台对撞机可以做到这一点, 而玩家平台、敌人平台、子弹玩家和子弹敌人对撞机则没有。 此外,当子弹击中平台时,我的销毁子弹的功能奇怪地工作正常。 我的子弹只有在击中平台时才会被摧毁。
有没有人知道如何解决这个问题?
编辑: 我为我的游戏创建了一个 Github 存储库,以便更好地了解。 (至少我希望我做到了,我以前没有用过 Github。) https://github.com/Kiroho/Game
编辑2: 经过测试,我发现这一定与我使用 ammoGroup class.
的方式有关我发现,如果我通过 ammoGroup(通过 createMultiple)创建子弹,对撞机开始为每颗子弹发射,直到我至少射击一次。 所有现有子弹发射一次后,一切正常,碰撞器按预期发射 -> 仅在碰撞时发射。
我的子弹平台对撞机
this.scene.physics.add.collider(this.scene.platforms, this.scene.playerProjectiles_Bounce, function (platform, projectile) {
//destoryProjectile(projectile);
console.log("hit");
});
弹药小组。我用它们作为每件武器的“杂志”
class AmmoGroup extends Phaser.Physics.Arcade.Group {
constructor(scene) {
super(scene.physics.world, scene);
}
fire(x, y, direction) {
const projectile = this.getFirstDead(false);
if (projectile) {
projectile.fire(x, y, direction);
}
}
loadAmmo(ammoIndex) {
this.clear();
if (ammoIndex == 1) {
this.classtype = Blaster;
}
else if (ammoIndex == 2) {
this.classtype = BlasterBig;
}
else if (ammoIndex == 3) {
this.classtype = Granade;
}
else if (ammoIndex == 4) {
this.classtype = Granade;
}
else if (ammoIndex == 0) {
this.classtype = Laser;
}
this.createMultiple({
classType: this.classtype,
frameQuantity: 20,
active: false,
visible: false,
key: ['ballAnim', 'kugel']
})
}
}
子弹class
class Granade extends Phaser.Physics.Arcade.Sprite {
constructor(scene, x, y) {
super(scene, x, y, 'kugel');
this.dmg = 20;
this.enemyHit = [];
this.bounceCounter = 3;
}
fire(x, y, direction) {
this.body.reset(x, y);
this.body.setGravityY(-1000);
this.setBounce(1);
this.setActive(true);
this.setVisible(true);
this.setVelocityY(WeaponConst.VELOCITY_Y_GRENADE);
if (direction == "left") {
this.setVelocityX(WeaponConst.VELOCITY_X_GRENADE * -1);
}
else if (direction == "up") {
this.setVelocityY(WeaponConst.VELOCITY_Y_GRENADE * 2);
this.setVelocityX(0);
}
else {
this.setVelocityX(WeaponConst.VELOCITY_X_GRENADE);
}
}
preUpdate(time, delta) {
super.preUpdate(time, delta);
if (!this.scene.cameras.main.worldView.contains(this.x, this.y)) {
this.enemyHit = [];
this.setActive(false);
this.setVisible(false);
}
}
}
补充: 玩家(和敌人)有一个武器对象。 这个武器对象有一个 ammoGroup 对象并设置它的射弹,射击时的速度,将它分配给组等等。
class Weapon {
constructor(scene) {
this.scene = scene;
this.type = null;
this.attackRate = null;
this.attackRange = null;
this.ammoGroup = new AmmoGroup(this.scene.scene, 1)
this.direction = null;
}
chooseWeapon(type) {
if (type == 'Blaster') {
this.setUpWeapon(
WeaponConst.TYPE_BLASTER,
WeaponConst.ATK_RATE_BLASTER,
WeaponConst.VELOCITY_X_BLASTER,
WeaponConst.VELOCITY_Y_BLASTER,
WeaponConst.AMMO_GROUP_BLASTER
);
console.log("Blaster choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_Normal);
}
else if (type == 'BlasterBig') {
this.setUpWeapon(
WeaponConst.TYPE_BLASTER_BIG,
WeaponConst.ATK_RATE_BLASTER_BIG,
WeaponConst.VELOCITY_X_BLASTER_BIG,
WeaponConst.VELOCITY_Y_BLASTER_BIG,
WeaponConst.AMMO_GROUP_BLASTER_BIG
);
console.log("BlasterBig choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_PierceEnemies);
}
else if (type == 'Grenade') {
this.setUpWeapon(
WeaponConst.TYPE_GRENADE,
WeaponConst.ATK_RATE_GRENADE,
WeaponConst.VELOCITY_X_GRENADE,
WeaponConst.VELOCITY_Y_GRENADE,
WeaponConst.AMMO_GROUP_GRENADE
);
console.log("Grenade choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_Bounce);
}
else if (type == 'GrenadeBig') {
this.setUpWeapon(
WeaponConst.TYPE_GRENADE_BIG,
WeaponConst.ATK_RATE_GRENADE_BIG,
WeaponConst.VELOCITY_X_GRENADE_BIG,
WeaponConst.VELOCITY_Y_GRENADE_BIG,
WeaponConst.AMMO_GROUP_GRENADE_BIG
);
console.log("GrenadeBig choosen");
this.assignToGroup(this.scene.scene.playerProjectiles_PierceEnemies);
}
else if (type == 'Laser') {
this.setUpWeapon(
WeaponConst.TYPE_LASER,
WeaponConst.ATK_RATE_LASER,
WeaponConst.VELOCITY_X_LASER,
WeaponConst.VELOCITY_Y_LASER,
WeaponConst.AMMO_GROUP_LASER
);
console.log("Laser choosen");
this.scene.scene.enemyProjectiles_Normal.add(this.ammoGroup);
this.scene.scene.enemyProjectiles_PiercePlayer.remove(this.ammoGroup);
this.scene.scene.enemyProjectiles_PierceAll.remove(this.ammoGroup);
}
}
setUpWeapon(type, attackRate, velocityX, velocityY, ammoGroup ) {
this.type = type;
this.attackRate = attackRate;
this.velocityX = velocityX;
this.velocityY = velocityY;
this.ammoGroup.loadAmmo(ammoGroup);
//this.scene.scene.enemyProjectiles_Normal.add(this.ammoGroup);
}
fire(x, y, direction) {
this.ammoGroup.fire(x, y, direction);
}
assignToGroup(group) {
this.scene.scene.playerProjectiles_Normal.remove(this.ammoGroup);
this.scene.scene.playerProjectiles_PierceEnemies.remove(this.ammoGroup);
this.scene.scene.playerProjectiles_PierceAll.remove(this.ammoGroup);
this.scene.scene.playerProjectiles_Bounce.remove(this.ammoGroup);
group.add(this.ammoGroup)
}
}
我发现我必须在创建时禁用子弹 objects 的 body,否则碰撞器会触发。我不知道为什么,但这似乎是(或多或少)众所周知的事情。虽然 body.checkCollision.none=true 有效,但使用 body.enable = false 禁用 body 的物理可能是更好的解决方案,因为它禁用所有物理而不仅仅是碰撞。