Javascript : Phaser 在另一个方法中调用一个方法 class
Javascript : Phaser call a method inside another method class
我在 javascript 使用 Phaser 进行开发时遇到了问题。我尝试在 class 的方法中调用方法,但出现错误。
这是我的 class :
import Enemy from '../classes/Enemy';
import Turret from '../classes/Turret';
import Bullet from '../classes/Bullet';
class GameScene extends Phaser.Scene {
constructor() {
super({
key: 'GameScene'
});
}
preload()
{
this.load.image('turret', './www/assets/tour_simple.png');
}
drawGrid(graphics)
{
graphics.lineStyle(1, 0x0000ff, 0.8);
for(var i = 0; i < 8; i++)
{
graphics.moveTo(0, i * 64);
graphics.lineTo(640, i * 64);
}
for(var j = 0; j < 10; j++)
{
graphics.moveTo(j * 64, 0);
graphics.lineTo(j * 64, 512);
}
graphics.strokePath();
}
canPlaceTurret(i, j)
{
return this.map[i][j] === 0;
}
placeTurret(pointer)
{
var i = Math.floor(pointer.y/64);
var j = Math.floor(pointer.x/64);
if(this.canPlaceTurret(i, j)) {
var turret = this.turrets.get();
if (turret)
{
turret.setActive(true);
turret.setVisible(true);
turret.place(i, j);
}
}
}
damageEnemy(enemy, bullet)
{
// only if both enemy and bullet are alive
if (enemy.active === true && bullet.active === true) {
// we remove the bullet right away
bullet.setActive(false);
bullet.setVisible(false);
//todo mettre dans une classe constante
var BULLET_DAMAGE = 25;
// decrease the enemy hp with BULLET_DAMAGE
enemy.receiveDamage(BULLET_DAMAGE);
}
}
create() {
this.add.text(200, 230, 'good!', { fill: '#0f0' });
var graphics = this.add.graphics();
this.map = [[ 0,-1, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0,-1, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0,-1,-1,-1,-1,-1,-1,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0]];
//TODO creer une classe qui dessine le path
// the path for our enemies
// parameters are the start x and y of our path
this.path = this.add.path(96, -32);
this.path.lineTo(96, 164);
this.path.lineTo(480, 164);
this.path.lineTo(480, 544);
graphics.lineStyle(3, 0xffffff, 1);
// visualize the path
this.path.draw(graphics);
this.enemies = this.physics.add.group({ classType: Enemy, runChildUpdate: true });
this.nextEnemy = 0;
var graphics = this.add.graphics();
this.drawGrid(graphics);
this.turrets = this.add.group({ classType: Turret, runChildUpdate: true });
this.input.on('pointerdown', this.placeTurret);
this.bullets = this.physics.add.group({ classType: Bullet, runChildUpdate: true });
this.physics.add.overlap(this.enemies, this.bullets, this.damageEnemy);
}
update(time, delta) {
if (time > this.nextEnemy)
{
var enemy = this.enemies.get();
console.log(enemy);
if (enemy)
{
enemy.setActive(true);
enemy.setVisible(true);
// place the enemy at the start of the path
enemy.startOnPath();
this.nextEnemy = time + 2000;
}
}
}
}
export default GameScene;
我的游戏出现错误:
TypeError: this.canPlaceTurret is not a function
错误来自我调用 canPlaceTurret
方法的 placeTurret
方法。
我尝试了一些方法,比如向我的 class 添加属性:self = this;
并使用 self.canPlaceTurret
调用我的函数,但问题始终存在。我认为这是一个范围问题,但我不知道如何解决。
另一个重要信息:我们正在使用 Webpack
感谢阅读:)。
尝试替换:
this.input.on('pointerdown', this.placeTurret);
与:
this.input.on('pointerdown', pointer => this.placeTurret(pointer));
(根据您在下方的评论略作编辑)
基本上,当您将方法作为回调传递时,它就变成了一个简单的函数引用。当稍后调用该函数时,this
将不会引用您期望的 class 实例,因为它不再在您的 class.
的上下文中调用
通过使用粗箭头语法,您创建了一个特定的回调,并明确告诉它在当前的上下文中调用该方法(如在定义回调时)this
.
或者,您也可以这样做:
this.input.on('pointerdown', this.placeTurret.bind(this));
这不是创建一个新的匿名函数,而是将您的方法作为参考(就像它开始时所做的那样),但手动将当前 this
绑定到它。
更详细的解释请参考this post
调用 canPlaceTurret() 时,如果不在 placeTurret() 方法中使用 this 关键字,它会不会工作?
placeTurret(pointer)
{
var i = Math.floor(pointer.y/64);
var j = Math.floor(pointer.x/64);
if(canPlaceTurret(i, j)) {
var turret = this.turrets.get();
if (turret)
{
turret.setActive(true);
turret.setVisible(true);
turret.place(i, j);
}
}
}
我在 javascript 使用 Phaser 进行开发时遇到了问题。我尝试在 class 的方法中调用方法,但出现错误。
这是我的 class :
import Enemy from '../classes/Enemy';
import Turret from '../classes/Turret';
import Bullet from '../classes/Bullet';
class GameScene extends Phaser.Scene {
constructor() {
super({
key: 'GameScene'
});
}
preload()
{
this.load.image('turret', './www/assets/tour_simple.png');
}
drawGrid(graphics)
{
graphics.lineStyle(1, 0x0000ff, 0.8);
for(var i = 0; i < 8; i++)
{
graphics.moveTo(0, i * 64);
graphics.lineTo(640, i * 64);
}
for(var j = 0; j < 10; j++)
{
graphics.moveTo(j * 64, 0);
graphics.lineTo(j * 64, 512);
}
graphics.strokePath();
}
canPlaceTurret(i, j)
{
return this.map[i][j] === 0;
}
placeTurret(pointer)
{
var i = Math.floor(pointer.y/64);
var j = Math.floor(pointer.x/64);
if(this.canPlaceTurret(i, j)) {
var turret = this.turrets.get();
if (turret)
{
turret.setActive(true);
turret.setVisible(true);
turret.place(i, j);
}
}
}
damageEnemy(enemy, bullet)
{
// only if both enemy and bullet are alive
if (enemy.active === true && bullet.active === true) {
// we remove the bullet right away
bullet.setActive(false);
bullet.setVisible(false);
//todo mettre dans une classe constante
var BULLET_DAMAGE = 25;
// decrease the enemy hp with BULLET_DAMAGE
enemy.receiveDamage(BULLET_DAMAGE);
}
}
create() {
this.add.text(200, 230, 'good!', { fill: '#0f0' });
var graphics = this.add.graphics();
this.map = [[ 0,-1, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0,-1, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0,-1,-1,-1,-1,-1,-1,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0,-1, 0, 0]];
//TODO creer une classe qui dessine le path
// the path for our enemies
// parameters are the start x and y of our path
this.path = this.add.path(96, -32);
this.path.lineTo(96, 164);
this.path.lineTo(480, 164);
this.path.lineTo(480, 544);
graphics.lineStyle(3, 0xffffff, 1);
// visualize the path
this.path.draw(graphics);
this.enemies = this.physics.add.group({ classType: Enemy, runChildUpdate: true });
this.nextEnemy = 0;
var graphics = this.add.graphics();
this.drawGrid(graphics);
this.turrets = this.add.group({ classType: Turret, runChildUpdate: true });
this.input.on('pointerdown', this.placeTurret);
this.bullets = this.physics.add.group({ classType: Bullet, runChildUpdate: true });
this.physics.add.overlap(this.enemies, this.bullets, this.damageEnemy);
}
update(time, delta) {
if (time > this.nextEnemy)
{
var enemy = this.enemies.get();
console.log(enemy);
if (enemy)
{
enemy.setActive(true);
enemy.setVisible(true);
// place the enemy at the start of the path
enemy.startOnPath();
this.nextEnemy = time + 2000;
}
}
}
}
export default GameScene;
我的游戏出现错误:
TypeError: this.canPlaceTurret is not a function
错误来自我调用 canPlaceTurret
方法的 placeTurret
方法。
我尝试了一些方法,比如向我的 class 添加属性:self = this;
并使用 self.canPlaceTurret
调用我的函数,但问题始终存在。我认为这是一个范围问题,但我不知道如何解决。
另一个重要信息:我们正在使用 Webpack
感谢阅读:)。
尝试替换:
this.input.on('pointerdown', this.placeTurret);
与:
this.input.on('pointerdown', pointer => this.placeTurret(pointer));
(根据您在下方的评论略作编辑)
基本上,当您将方法作为回调传递时,它就变成了一个简单的函数引用。当稍后调用该函数时,this
将不会引用您期望的 class 实例,因为它不再在您的 class.
通过使用粗箭头语法,您创建了一个特定的回调,并明确告诉它在当前的上下文中调用该方法(如在定义回调时)this
.
或者,您也可以这样做:
this.input.on('pointerdown', this.placeTurret.bind(this));
这不是创建一个新的匿名函数,而是将您的方法作为参考(就像它开始时所做的那样),但手动将当前 this
绑定到它。
更详细的解释请参考this post
调用 canPlaceTurret() 时,如果不在 placeTurret() 方法中使用 this 关键字,它会不会工作?
placeTurret(pointer)
{
var i = Math.floor(pointer.y/64);
var j = Math.floor(pointer.x/64);
if(canPlaceTurret(i, j)) {
var turret = this.turrets.get();
if (turret)
{
turret.setActive(true);
turret.setVisible(true);
turret.place(i, j);
}
}
}