在 Phaser 中的玩家精灵位置创建子弹精灵,但精灵不会被创建/添加到游戏中
Creating A Bullet Sprite At Players Sprite Location In Phaser But The Sprite Wont Be Created / Added To The Game
这是一款猴子在平台上移动收集硬币的游戏。我想让猴子在按下向下箭头和向左箭头时射出香蕉。
我将如何创建子弹?
我有射击按键,它会根据按下的箭头调用 shootR 或 shootL。我需要的是创建射弹并让它向右或向左移动(不受重力影响)。我能得到一些帮助来创建这个射弹吗 var proj = projs.create(x, y, 'proj');不管用。我擅长用 js 编码,phaser 对我来说是新手,所以非常感谢帮助。
var config = {
type: Phaser.AUTO,
width: 1900,
height: 1000,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var main = document.getElementById("startBtn")
var heading = document.getElementById("header")
var gameOver
var platforms;
var score = 0;
var scoreText;
var leafAm = 0
var leafText
var gunAm = 0
var ammoAm = 0
var ammoText
var monkeyType = "monkey"
var delay = 0
function start() {
game = new Phaser.Game(config);
main.innerHTML = ''
heading.innerHTML += '<h1 class="header2" onclick="shop()"><u>Click To Access Shop</u></h1>'
}
function preload() {
this.load.image('Background', 'assets/Background.jpg');
this.load.image('ground', 'assets/platform.png');
this.load.image('coin', 'assets/coin.png');
this.load.image('redCoin', 'assets/redCoin.png');
this.load.spritesheet('monkey', 'assets/monkey.png', { frameWidth: 600, frameHeight: 720 });
this.load.spritesheet('proj', 'assets/bullet.png', { frameWidth: 200, frameHeight: 200 });
}
function create() {
this.add.image(500, 275, 'Background').setScale(3);
platforms = this.physics.add.staticGroup();
platforms.create(200, 650, 'ground').setScale(0.15).refreshBody();
platforms.create(600, 400, 'ground').setScale(0.15).refreshBody();
platforms.create(1600, 650, 'ground').setScale(0.15).refreshBody();
platforms.create(750, 100, 'ground').setScale(0.15).refreshBody();
platforms.create(850, 750, 'ground').setScale(0.15).refreshBody();
platforms.create(100, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(400, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(700, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1000, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1300, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1600, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1900, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1800, 800, 'ground').setScale(0.15).refreshBody();
platforms.create(250, 250, 'ground').setScale(0.15).refreshBody();
platforms.create(1000, 500, 'ground').setScale(0.15).refreshBody();
platforms.create(1150, 220, 'ground').setScale(0.15).refreshBody();
player = this.physics.add.sprite(100, 450, 'monkey').setScale(0.075);
this.physics.add.collider(player, platforms);
player.setBounce(0.2);
player.setCollideWorldBounds(true);
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('monkey', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [{ key: 'monkey', frame: 4 }],
frameRate: 20
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('monkey', { start: 5, end: 8 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'shoot',
frames: this.anims.generateFrameNumbers('proj', { start: 0, end: 3 }),
framerate: 15,
repeat: -1
})
coins = this.physics.add.group({
key: 'coin',
repeat: 10,
setXY: { x: 12, y: 0, stepX: 150 }
});
coins.children.iterate(function (child) {
child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));
child.setScale(0.05)
});
this.physics.add.collider(coins, platforms);
this.physics.add.overlap(player, coins, collectCoin, null, this);
redCoins = this.physics.add.group();
this.physics.add.collider(redCoins, platforms);
this.physics.add.collider(player, redCoins, hitredCoin, null, this);
projs = this.physics.add.group()
this.physics.add.collider(projs, platforms)
this.physics.add.collider(projs, redCoins, shootredCoin, null, this)
scoreText = this.add.text(16, 16, 'Score: 0₴', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
ammoText = this.add.text(16, 66, 'Ammo: 0', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
leafText = this.add.text(16, 116, 'Shields: 0', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
}
function update() {
cursors = this.input.keyboard.createCursorKeys();
if (cursors.down.isDown && cursors.left.isDown && delay == 0) {
shootL()
} else if (cursors.down.isDown && cursors.right.isDown && delay == 0) {
shootR()
}
if (cursors.left.isDown) {
player.setVelocityX(-240);
player.anims.play('left', true);
}
else if (cursors.right.isDown) {
player.setVelocityX(240);
player.anims.play('right', true);
}
else {
player.setVelocityX(0);
player.anims.play('turn');
}
if (cursors.up.isDown && player.body.touching.down) {
player.setVelocityY(-330);
}
}
function collectCoin(player, coin) {
coin.disableBody(true, true);
score += 1;
scoreText.setText('Score: ' + score + '₴');
if (coins.countActive(true) === 0) {
coins.children.iterate(function (child) {
child.enableBody(true, child.x, 0, true, true);
});
var x = Phaser.Math.Between(0, 800);
var redCoin = redCoins.create(x, 16, 'redCoin').setScale(0.05);
redCoin.setBounce(1);
redCoin.setCollideWorldBounds(true);
redCoin.setVelocity(Phaser.Math.Between(-300, 300), 20);
}
}
function shootR(player, redCoin, proj) {
var x = player.x
var y = player.y
var proj = projs.create(x, y, 'proj');
// proj.setVelocityX(-240);
// player.anims.play('shoot', true);
ammoAm -= 1
ammoText.setText('Ammo: ' + ammoAm + '');
delay = 1
this.time.delayedCall(3000, delayer, null, this);
}
function shootL(player, redCoin, proj) {
var x = player.x
var y = player.y
var proj = projs.create(x, y, 'proj');
ammoAm -= 1
ammoText.setText('Ammo: ' + ammoAm + '');
delay = 1
this.time.delayedCall(3000, delayer, null, this);
}
function hitredCoin(player, redCoin) {
if (leafAm > 0) {
leafAm -= 1
leafText.setText('Shields: ' + leafAm + '');
redCoin.disableBody(true, true);
var x = Phaser.Math.Between(0, 800);
var redCoin = redCoins.create(x, 16, 'redCoin').setScale(0.05);
redCoin.setBounce(1);
redCoin.setCollideWorldBounds(true);
redCoin.setVelocity(Phaser.Math.Between(-300, 300), 20);
} else {
this.physics.pause();
player.setTint(0xff0000);
player.anims.play('turn');
gameOver = true;
this.time.delayedCall(3000, restart, null, this);
}
}
function shootredCoin(projs, redCoin) {
redCoin.disableBody(true, true);
projs.disableBody(true, true);
}
function restart() {
score = 0
var leafAm = 0
var gunAm = 0
var ammoAm = 0
this.scene.stop();
this.scene.start();
}
function shop() {
main.innerHTML = `<button class="shopBackground"></button>`
main.innerHTML += `<button class="shop1">Shop</button>`
main.innerHTML += `<button class="shop2">Warning: Shop Fast, you can still die</button>`
main.innerHTML += `<button class="shop3" onclick = "buy1()">Banana Gun...₴100.00<br>(Ability to shoot bananas)<br>click here to buy</button>`
main.innerHTML += `<button class="shop4" onclick = "buy2()">Leaf Shield...₴30.00<br>(Protection from 1 hit)<br>click here to buy</button>`
main.innerHTML += `<button class="shop5" onclick = "buy3()">Bananas...₴10.00<br>(Extra ammo, gun comes with 1)<br>click here to buy</button>`
main.innerHTML += `<button class="shop6">₴ is score</button>`
main.innerHTML += `<button class="shop7" onclick="main.innerHTML = ''">Back To Game</button>`
main.innerHTML += `<img src="/assets/banana1.png" class="banana1">`
main.innerHTML += `<img src="/assets/banana2.png" class="banana2">`
main.innerHTML += `<img src="/assets/leaf.png" class="leaf">`
}
function buy1() {
if (score > 99 && gunAm < 1) {
gunAm += 1
ammoAm += 1
score -= 100
scoreText.setText('Score: ' + score + '₴');
alert("You have bought a gun \nClick the down arrow and either left or right to shoot\nShooting costs ammo but bullets detroy the red orbs\nEnjoy and good luck")
} else if (gunAm > 0) {
alert("You already have one")
} else {
alert("Not enough score")
}
}
function buy2() {
if (score > 29) {
leafAm += 1
score -= 30
scoreText.setText('Score: ' + score + '₴');
leafText.setText('Shields: ' + leafAm + '');
} else {
alert("Not enough score")
}
}
function buy3() {
if (score > 9) {
ammoAm += 1
score -= 10
scoreText.setText('Score: ' + score + '₴');
ammoText.setText('Ammo: ' + ammoAm + '');
;
} else {
alert("Not enough score")
}
}
function delayer() {
delay = 0
}
如有任何帮助或想法,我们将不胜感激。
还有一些 HTML 和 CSS 但这些部分不会影响它,或者至少它们不应该
这里有些东西要打开,
Btw.: usually on Whosebug you should only post the essential code: https://whosebug.com/help/minimal-reproducible-example this makes helping easy
但是回到你的问题:
- 首先,函数
shootR
和shootL
不起作用,因为它们是用参数定义的,但没有传递。 所以 player
参数重载了全局 player
变量(顺便说一句,全局播放器变量永远不会用 var
、let
或 const
)
函数定义:
function shootR(player, redCoin, proj)
...
正在调用的函数:
...
if (cursors.down.isDown && cursors.left.isDown && delay == 0) {
shootL()
} else if (cursors.down.isDown && cursors.right.isDown && delay == 0) {
shootR()
}
...
快速修复: 传递播放器参数,示例:shootR(player)
- 其次
shootR
和 shootL
函数中的 this
没有指向正确的对象。
快速修复: 将场景传递给函数,示例:shootR(this, player)
并将函数更改为:
function shootL(scene, player, redCoin, proj) {
var x = player.x
var y = player.y
var proj = projs.create(x, y, 'proj');
ammoAm -= 1
ammoText.setText('Ammo: ' + ammoAm + '');
delay = 1
scene.time.delayedCall(3000, delayer, null, scene);
}
第三个“去除重力”,只需使用
快速修复: proj.body.setAllowGravity(false);
在 shootR
和 shootL
(这里是 link to the documentation )函数中,
最后只需添加子弹的速度proj.setVelocityX()
btw.: 可以使用 类 及其属性改进代码,我建议查看移相器示例
https://phaser.io/examples/v3/view/scenes/scene-from-class and/or https://phaser.io/examples/v3/view/scenes/scene-from-es6-class 关于如何使用 类 场景,这可以解决很多问题。而且您不需要使用全局变量或传递那么多参数。
这是一款猴子在平台上移动收集硬币的游戏。我想让猴子在按下向下箭头和向左箭头时射出香蕉。
我将如何创建子弹?
我有射击按键,它会根据按下的箭头调用 shootR 或 shootL。我需要的是创建射弹并让它向右或向左移动(不受重力影响)。我能得到一些帮助来创建这个射弹吗 var proj = projs.create(x, y, 'proj');不管用。我擅长用 js 编码,phaser 对我来说是新手,所以非常感谢帮助。
var config = {
type: Phaser.AUTO,
width: 1900,
height: 1000,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var main = document.getElementById("startBtn")
var heading = document.getElementById("header")
var gameOver
var platforms;
var score = 0;
var scoreText;
var leafAm = 0
var leafText
var gunAm = 0
var ammoAm = 0
var ammoText
var monkeyType = "monkey"
var delay = 0
function start() {
game = new Phaser.Game(config);
main.innerHTML = ''
heading.innerHTML += '<h1 class="header2" onclick="shop()"><u>Click To Access Shop</u></h1>'
}
function preload() {
this.load.image('Background', 'assets/Background.jpg');
this.load.image('ground', 'assets/platform.png');
this.load.image('coin', 'assets/coin.png');
this.load.image('redCoin', 'assets/redCoin.png');
this.load.spritesheet('monkey', 'assets/monkey.png', { frameWidth: 600, frameHeight: 720 });
this.load.spritesheet('proj', 'assets/bullet.png', { frameWidth: 200, frameHeight: 200 });
}
function create() {
this.add.image(500, 275, 'Background').setScale(3);
platforms = this.physics.add.staticGroup();
platforms.create(200, 650, 'ground').setScale(0.15).refreshBody();
platforms.create(600, 400, 'ground').setScale(0.15).refreshBody();
platforms.create(1600, 650, 'ground').setScale(0.15).refreshBody();
platforms.create(750, 100, 'ground').setScale(0.15).refreshBody();
platforms.create(850, 750, 'ground').setScale(0.15).refreshBody();
platforms.create(100, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(400, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(700, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1000, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1300, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1600, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1900, 950, 'ground').setScale(0.15).refreshBody();
platforms.create(1800, 800, 'ground').setScale(0.15).refreshBody();
platforms.create(250, 250, 'ground').setScale(0.15).refreshBody();
platforms.create(1000, 500, 'ground').setScale(0.15).refreshBody();
platforms.create(1150, 220, 'ground').setScale(0.15).refreshBody();
player = this.physics.add.sprite(100, 450, 'monkey').setScale(0.075);
this.physics.add.collider(player, platforms);
player.setBounce(0.2);
player.setCollideWorldBounds(true);
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('monkey', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [{ key: 'monkey', frame: 4 }],
frameRate: 20
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('monkey', { start: 5, end: 8 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'shoot',
frames: this.anims.generateFrameNumbers('proj', { start: 0, end: 3 }),
framerate: 15,
repeat: -1
})
coins = this.physics.add.group({
key: 'coin',
repeat: 10,
setXY: { x: 12, y: 0, stepX: 150 }
});
coins.children.iterate(function (child) {
child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));
child.setScale(0.05)
});
this.physics.add.collider(coins, platforms);
this.physics.add.overlap(player, coins, collectCoin, null, this);
redCoins = this.physics.add.group();
this.physics.add.collider(redCoins, platforms);
this.physics.add.collider(player, redCoins, hitredCoin, null, this);
projs = this.physics.add.group()
this.physics.add.collider(projs, platforms)
this.physics.add.collider(projs, redCoins, shootredCoin, null, this)
scoreText = this.add.text(16, 16, 'Score: 0₴', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
ammoText = this.add.text(16, 66, 'Ammo: 0', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
leafText = this.add.text(16, 116, 'Shields: 0', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
}
function update() {
cursors = this.input.keyboard.createCursorKeys();
if (cursors.down.isDown && cursors.left.isDown && delay == 0) {
shootL()
} else if (cursors.down.isDown && cursors.right.isDown && delay == 0) {
shootR()
}
if (cursors.left.isDown) {
player.setVelocityX(-240);
player.anims.play('left', true);
}
else if (cursors.right.isDown) {
player.setVelocityX(240);
player.anims.play('right', true);
}
else {
player.setVelocityX(0);
player.anims.play('turn');
}
if (cursors.up.isDown && player.body.touching.down) {
player.setVelocityY(-330);
}
}
function collectCoin(player, coin) {
coin.disableBody(true, true);
score += 1;
scoreText.setText('Score: ' + score + '₴');
if (coins.countActive(true) === 0) {
coins.children.iterate(function (child) {
child.enableBody(true, child.x, 0, true, true);
});
var x = Phaser.Math.Between(0, 800);
var redCoin = redCoins.create(x, 16, 'redCoin').setScale(0.05);
redCoin.setBounce(1);
redCoin.setCollideWorldBounds(true);
redCoin.setVelocity(Phaser.Math.Between(-300, 300), 20);
}
}
function shootR(player, redCoin, proj) {
var x = player.x
var y = player.y
var proj = projs.create(x, y, 'proj');
// proj.setVelocityX(-240);
// player.anims.play('shoot', true);
ammoAm -= 1
ammoText.setText('Ammo: ' + ammoAm + '');
delay = 1
this.time.delayedCall(3000, delayer, null, this);
}
function shootL(player, redCoin, proj) {
var x = player.x
var y = player.y
var proj = projs.create(x, y, 'proj');
ammoAm -= 1
ammoText.setText('Ammo: ' + ammoAm + '');
delay = 1
this.time.delayedCall(3000, delayer, null, this);
}
function hitredCoin(player, redCoin) {
if (leafAm > 0) {
leafAm -= 1
leafText.setText('Shields: ' + leafAm + '');
redCoin.disableBody(true, true);
var x = Phaser.Math.Between(0, 800);
var redCoin = redCoins.create(x, 16, 'redCoin').setScale(0.05);
redCoin.setBounce(1);
redCoin.setCollideWorldBounds(true);
redCoin.setVelocity(Phaser.Math.Between(-300, 300), 20);
} else {
this.physics.pause();
player.setTint(0xff0000);
player.anims.play('turn');
gameOver = true;
this.time.delayedCall(3000, restart, null, this);
}
}
function shootredCoin(projs, redCoin) {
redCoin.disableBody(true, true);
projs.disableBody(true, true);
}
function restart() {
score = 0
var leafAm = 0
var gunAm = 0
var ammoAm = 0
this.scene.stop();
this.scene.start();
}
function shop() {
main.innerHTML = `<button class="shopBackground"></button>`
main.innerHTML += `<button class="shop1">Shop</button>`
main.innerHTML += `<button class="shop2">Warning: Shop Fast, you can still die</button>`
main.innerHTML += `<button class="shop3" onclick = "buy1()">Banana Gun...₴100.00<br>(Ability to shoot bananas)<br>click here to buy</button>`
main.innerHTML += `<button class="shop4" onclick = "buy2()">Leaf Shield...₴30.00<br>(Protection from 1 hit)<br>click here to buy</button>`
main.innerHTML += `<button class="shop5" onclick = "buy3()">Bananas...₴10.00<br>(Extra ammo, gun comes with 1)<br>click here to buy</button>`
main.innerHTML += `<button class="shop6">₴ is score</button>`
main.innerHTML += `<button class="shop7" onclick="main.innerHTML = ''">Back To Game</button>`
main.innerHTML += `<img src="/assets/banana1.png" class="banana1">`
main.innerHTML += `<img src="/assets/banana2.png" class="banana2">`
main.innerHTML += `<img src="/assets/leaf.png" class="leaf">`
}
function buy1() {
if (score > 99 && gunAm < 1) {
gunAm += 1
ammoAm += 1
score -= 100
scoreText.setText('Score: ' + score + '₴');
alert("You have bought a gun \nClick the down arrow and either left or right to shoot\nShooting costs ammo but bullets detroy the red orbs\nEnjoy and good luck")
} else if (gunAm > 0) {
alert("You already have one")
} else {
alert("Not enough score")
}
}
function buy2() {
if (score > 29) {
leafAm += 1
score -= 30
scoreText.setText('Score: ' + score + '₴');
leafText.setText('Shields: ' + leafAm + '');
} else {
alert("Not enough score")
}
}
function buy3() {
if (score > 9) {
ammoAm += 1
score -= 10
scoreText.setText('Score: ' + score + '₴');
ammoText.setText('Ammo: ' + ammoAm + '');
;
} else {
alert("Not enough score")
}
}
function delayer() {
delay = 0
}
如有任何帮助或想法,我们将不胜感激。
还有一些 HTML 和 CSS 但这些部分不会影响它,或者至少它们不应该
这里有些东西要打开,
Btw.: usually on Whosebug you should only post the essential code: https://whosebug.com/help/minimal-reproducible-example this makes helping easy
但是回到你的问题:
- 首先,函数
shootR
和shootL
不起作用,因为它们是用参数定义的,但没有传递。 所以player
参数重载了全局player
变量(顺便说一句,全局播放器变量永远不会用var
、let
或const
)
函数定义:
function shootR(player, redCoin, proj)
...
正在调用的函数:
...
if (cursors.down.isDown && cursors.left.isDown && delay == 0) {
shootL()
} else if (cursors.down.isDown && cursors.right.isDown && delay == 0) {
shootR()
}
...
快速修复: 传递播放器参数,示例:shootR(player)
- 其次
shootR
和shootL
函数中的this
没有指向正确的对象。
快速修复: 将场景传递给函数,示例:shootR(this, player)
并将函数更改为:
function shootL(scene, player, redCoin, proj) {
var x = player.x
var y = player.y
var proj = projs.create(x, y, 'proj');
ammoAm -= 1
ammoText.setText('Ammo: ' + ammoAm + '');
delay = 1
scene.time.delayedCall(3000, delayer, null, scene);
}
第三个“去除重力”,只需使用
快速修复:proj.body.setAllowGravity(false);
在shootR
和shootL
(这里是 link to the documentation )函数中,最后只需添加子弹的速度
proj.setVelocityX()
btw.: 可以使用 类 及其属性改进代码,我建议查看移相器示例 https://phaser.io/examples/v3/view/scenes/scene-from-class and/or https://phaser.io/examples/v3/view/scenes/scene-from-es6-class 关于如何使用 类 场景,这可以解决很多问题。而且您不需要使用全局变量或传递那么多参数。