重新启动状态后为空引用

时间:2015-04-22 04:35:42

标签: javascript phaser-framework

我为Phaser创建了一个小游戏用于演示目的。在您赢了或输了之后,您可以重新开始游戏。这是由各州完成的。当我在重新启动游戏后尝试发射子弹时,会发生空引用错误并且游戏冻结。似乎发生了空引用,因为在重新启动状态后,在Weapon类中未正确设置this.game属性。

var PhaserGame = function () {

    this.background = null;
    this.stars = null;

    this.player = null;
    this.enemies = null;
    this.cursors = null;
    this.speed = 300;

    this.weapons = [];
    this.currentWeapon = 0;
    this.weaponName = null;

    this.score = 0;

};

PhaserGame.prototype = {

    init: function () {

        this.game.renderer.renderSession.roundPixels = true;

        this.physics.startSystem(Phaser.Physics.ARCADE);

    },


    preload: function () {

        this.game.time.advancedTiming = true;

    },

    create: function () {

        this.background = this.add.tileSprite(0, 0, this.game.width, this.game.height, 'background');
        this.background.autoScroll(-40, 0);

        this.stars = this.add.tileSprite(0, 0, this.game.width, this.game.height, 'stars');
        this.stars.autoScroll(-60, 0);

        this.weapons.push(new Weapon.SingleBullet(this.game));
        //this.weapons.push(new Weapon.FrontAndBack(this.game));
        this.weapons.push(new Weapon.ThreeWay(this.game));
        //this.weapons.push(new Weapon.EightWay(this.game));
        this.weapons.push(new Weapon.ScatterShot(this.game));
        this.weapons.push(new Weapon.Beam(this.game));
        this.weapons.push(new Weapon.SplitShot(this.game));
        //this.weapons.push(new Weapon.Pattern(this.game));
        this.weapons.push(new Weapon.Rockets(this.game));
        this.weapons.push(new Weapon.ScaleBullet(this.game));
        //this.weapons.push(new Weapon.Combo1(this.game));
        //this.weapons.push(new Weapon.Combo2(this.game));

        this.currentWeapon = 0;

        for (var i = 1; i < this.weapons.length; i++)
        {
            this.weapons[i].visible = false;
        }

        this.player = this.add.existing(new Spaceship(this.game, 100, 200, 'player'));

        this.player.events.onKilled.add(this.toGameOver, this);

        this.physics.arcade.enable(this.player);

        this.player.body.collideWorldBounds = true;

        this.player.animations.add('flame', [0, 1, 2, 3], 10, true);
        this.player.animations.play('flame');

        //Enemies
        this.enemies = this.add.group();

        //Enable Physics for Enemies
        //this.physics.arcade.enable(this.enemies);
        this.enemies.enableBody = true;

        for (var i = 0; i < 24; i++) {
            //create a star inside the group
            var enemy = this.enemies.add(new Enemy(this.game, 1000 + (i * 50), 10 + Math.random() * 300, 'enemy'));
            enemy.events.onKilled.add(this.raiseCounter, this);
        }

        //this.weaponName = this.add.bitmapText(8, 364, 'shmupfont', "ENTER = Next Weapon", 24);

        //  Cursor keys to fly + space to fire
        this.cursors = this.input.keyboard.createCursorKeys();

        this.input.keyboard.addKeyCapture([ Phaser.Keyboard.SPACEBAR ]);

        var changeKey = this.input.keyboard.addKey(Phaser.Keyboard.ENTER);
        changeKey.onDown.add(this.nextWeapon, this);
    },

    nextWeapon: function () {

        //  Tidy-up the current weapon
        this.weapons[this.currentWeapon].visible = false;
        this.weapons[this.currentWeapon].callAll('reset', null, 0, 0);
        this.weapons[this.currentWeapon].setAll('exists', false);

        //  Activate the new one
        this.currentWeapon++;

        if (this.currentWeapon === this.weapons.length)
        {
            this.currentWeapon = 0;
        }

        this.weapons[this.currentWeapon].visible = true;

        //this.weaponName.text = this.weapons[this.currentWeapon].name;

    },

    enemyHit: function (bullet, enemy) {
        bullet.kill();
        enemy.dealDamage(2);
    },

    playerHit: function (player, enemy) {
        player.dealDamage(10);
        enemy.dealDamage(1);
    },

    raiseCounter: function () {
        this.score++;
    },

    toGameOver: function () {
        this.game.state.start('GameOver', true, false, this.score);
    },

    update: function () {

        //Framerate
        this.game.debug.text(this.time.fps || '--', 2, 14, "#00ff00");
        this.game.debug.text('Health: ' + this.player.health || 'Health: ---', 2, 30, "#00ff00");
        this.game.debug.text('Counter: ' + this.score || 'Counter: ---', 2, 44, "#00ff00");

        this.game.physics.arcade.overlap(this.weapons[this.currentWeapon], this.enemies, this.enemyHit, null, this);
        this.game.physics.arcade.overlap(this.player, this.enemies, this.playerHit, null, this);


        this.player.body.velocity.set(0);
        this.enemies.setAll('body.velocity.x', -50);

        if (this.cursors.left.isDown)
        {
            this.player.body.velocity.x = -this.speed;
        }
        else if (this.cursors.right.isDown)
        {
            this.player.body.velocity.x = this.speed;
        }

        if (this.cursors.up.isDown)
        {
            this.player.body.velocity.y = -this.speed;
        }
        else if (this.cursors.down.isDown)
        {
            this.player.body.velocity.y = this.speed;
        }

        if (this.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR))
        {
            this.weapons[this.currentWeapon].fire(this.player);
        }

    }

};

武器级别来自Phaser-Coding-Tips 7:

Weapon.SingleBullet = function (game) {

    console.log(game);

    Phaser.Group.call(this, game, game.world, 'Single Bullet', false, true, Phaser.Physics.ARCADE);

    this.nextFire = 0;
    this.bulletSpeed = 600;
    this.fireRate = 200;

    for (var i = 0; i < 64; i++)
    {
        this.add(new Bullet(game, 'bullet5'), true);
    }

    return this;

};

Weapon.SingleBullet.prototype = Object.create(Phaser.Group.prototype);
Weapon.SingleBullet.prototype.constructor = Weapon.SingleBullet;

Weapon.SingleBullet.prototype.fire = function (source) {
    //Here occurs the problem, because this.game is null after restarting the state
    if (this.game.time.time < this.nextFire) { return; }

    var x = source.x + 50;
    var y = source.y + 15;

    this.getFirstExists(false).fire(x, y, 0, this.bulletSpeed, 0, 0);

    this.nextFire = this.game.time.time + this.fireRate;

};

重新启动状态后,所有Weapon类中的问题都会一致。

1 个答案:

答案 0 :(得分:0)

在填充create之前weapons - 方法的开头,我忘了清空数组。有趣的是:我之前尝试清空数组,但它没有用。当我记录weapons的长度时,它突然开始按预期工作。也许原因是由javascript引擎做出的奇怪优化。