deedeekaka Posted August 22, 2016 Share Posted August 22, 2016 (edited) Hello! I am making a waste sorting game and when the player loses all their lives, I wish to restart the game. I click the 'RETRY' text and the state reloads, but it seems that my life and garbage sprites never reload. I am wondering if it is because they are in an array (see this.garbage = []; and this.lifeSprites = [];). I have never used game.state.start to reload a state multiple times, I have only ever used it to call a state once. If I cannot get game.state.start to reload my game, I will create a restart() method with some re-positioning code and whatnot. BUT it would be way awesome if I could figure out why this doesn't work!! Below is my code and here is a link to my game so far (my code is still mucho messy). Arrow keys to rotate on desktop. BasicGame.Game = function (game) { this.firstDrop = true; this.garbage = []; this.MAX_TRASH = 5; this.lowestTrash = null; this.lastLowestTrash = null; this.lowestTrashType = null; this.lives = 3; this.lifeSprites = []; this.gap = 500; this.MIN_GAP = 250; this.fallSpeed = 3; this.MAX_FALL_SPEED = 5.5; this.sorter = null; this.rotationSpeed = 10; this.targetRotation = null; this.isRotating = false; this.clockwise = true; this.orientation = null; this.Orientation = { NORTH: 0, EAST: -90, SOUTH: -180, WEST: 90 }; this.TrashType = { BLUE: 0, COMPOST: 1, GREY: 2, YELLOW: 3 }; this.leftKey = null; this.rightKey = null; this.gameover = false; this.score = 0; this.scoreText = null; this.highScoreText = null; this.msgText = null; this.continuePrompt = null; }; BasicGame.Game.prototype = { create: function () { this.lowestTrash = 0; this.lastLowestTrash = this.MAX_TRASH - 1; var trash; for (i = 0; i < this.MAX_TRASH; i++) { trash = this.game.add.sprite(this.game.world.centerX, -this.gap * (i + 1), 'trash'); trash.loadTexture('trash', this.rnd.integerInRange(0, this.MAX_TRASH)); trash.anchor.setTo(0.5); this.garbage.push(trash); if (i == 0) { this.lowestTrashType = trash.frame; } } var life; for (i = 0; i < this.lives; i++) { life = this.game.add.sprite(0, 0, 'life'); life.anchor.setTo(0.5); life.x = (this.game.width - (life.width / 2 + 10)) - (i * life.width); life.y = life.height - 10; this.lifeSprites.push(life); } this.sorter = this.game.add.sprite(this.game.world.centerX, this.game.height, 'sorter'); this.sorter.anchor.setTo(0.5); this.orientation = this.Orientation.NORTH; this.targetRotation = this.orientation; this.scoreText = this.add.bitmapText(25, 25, 'arialPixelated', '0', 16); this.scoreText.align = 'left'; this.highScoreText = this.add.bitmapText(25, 50, 'arialPixelated', 'BEST: ' + BasicGame.highScore, 16); this.highScoreText.align = 'left'; this.continuePrompt = new SuperBitmapText(this.game, this.game.world.centerX, this.game.world.centerY + 100, 'arialPixelated', 'RETRY', 16, 25); this.continuePrompt.anchor.setTo(0.5); this.continuePrompt.align = 'left'; this.continuePrompt.alpha = 0; this.continuePrompt.inputEnabled = false; this.msgText = this.add.bitmapText(this.game.world.centerX, this.game.world.centerY, 'arialPixelated', '', 16); this.msgText.anchor.setTo(0.5); this.msgText.align = 'center'; this.game.input.onDown.add(this.rotateSorter, this); this.game.input.onDown.add(function() {if (this.continuePrompt.isDown){this.game.state.start('Game', true, false);}}, this); this.leftKey = this.game.input.keyboard.addKey(Phaser.Keyboard.LEFT); this.rightKey = this.game.input.keyboard.addKey(Phaser.Keyboard.RIGHT); this.game.input.keyboard.addCallbacks(this, this.rotateSorter); //For mobile. Phaser.Canvas.setTouchAction(this.game.canvas, 'auto'); this.game.input.touch.preventDefault = true; }, update : function () { if (!this.gameover) { this.garbage.forEach(function(trash) { trash.y += this.fallSpeed; trash.angle += 0.25; }, this); if (this.garbage[this.lowestTrash].y > this.game.height - (this.sorter.height / 2.5)) { this.checkIfScored(); } } this.sorter.angle = Phaser.Math.snapTo(this.sorter.angle, this.rotationSpeed); if (this.sorter.angle != this.targetRotation) { this.isRotating = true; } else { this.isRotating = false; } if (this.isRotating) { if (this.clockwise) { this.sorter.angle += this.rotationSpeed; } else { this.sorter.angle -= this.rotationSpeed; } } }, resetTrash : function () { this.garbage[this.lowestTrash].y += -this.gap * (this.MAX_TRASH); this.garbage[this.lowestTrash].loadTexture('trash', this.rnd.integerInRange(0, this.MAX_TRASH)); this.lowestTrash++; if (this.lowestTrash > this.garbage.length - 1) { this.lowestTrash = 0; } this.lowestTrashType = this.garbage[this.lowestTrash].frame; }, checkIfScored : function () { if (this.lowestTrashType == this.TrashType.BLUE && this.orientation == this.Orientation.NORTH) { this.score++; if (this.gap > this.MIN_GAP) { this.gap -= 5; } else { this.gap = this.MIN_GAP; } if (this.fallSpeed < this.MAX_FALL_SPEED) { this.fallSpeed += 0.05; } else { this.fallSpeed = this.MAX_FALL_SPEED; } } else if (this.lowestTrashType == this.TrashType.COMPOST && this.orientation == this.Orientation.EAST) { this.score++; if (this.gap > this.MIN_GAP) { this.gap -= 5; } else { this.gap = this.MIN_GAP; } if (this.fallSpeed < this.MAX_FALL_SPEED) { this.fallSpeed += 0.05; } else { this.fallSpeed = this.MAX_FALL_SPEED; } } else if (this.lowestTrashType == this.TrashType.GREY && this.orientation == this.Orientation.SOUTH) { this.score++; if (this.gap > this.MIN_GAP) { this.gap -= 5; } else { this.gap = this.MIN_GAP; } if (this.fallSpeed < this.MAX_FALL_SPEED) { this.fallSpeed += 0.05; } else { this.fallSpeed = this.MAX_FALL_SPEED; } } else if (this.lowestTrashType == this.TrashType.YELLOW && this.orientation == this.Orientation.WEST) { this.score++; if (this.gap > this.MIN_GAP) { this.gap -= 5; } else { this.gap = this.MIN_GAP; } if (this.fallSpeed < this.MAX_FALL_SPEED) { this.fallSpeed += 0.05; } else { this.fallSpeed = this.MAX_FALL_SPEED; } } else { this.fallSpeed = 3; this.updateLives(); } this.resetTrash(); this.scoreText.setText(this.score); }, updateLives : function () { this.lifeSprites[this.lives - 1].loadTexture('lifeFull'); this.lives--; if (this.lives == 0) { this.gameover = true; this.msgText.setText('GAME OVER!\n' + this.score + ' responsibly disposed trashes!'); this.continuePrompt.alpha = 1; this.continuePrompt.inputEnabled = true; this.continuePrompt.input.useHandCursor = true; if (this.score > BasicGame.highScore) { BasicGame.highScore = this.score; this.highScoreText.setText('BEST: ' + BasicGame.highScore); } this.garbage.forEach(function(trash) { trash.kill(); }, this); this.game.input.onDown.remove(this.rotateSorter, this); } }, rotateSorter : function () { if (this.game.device.desktop && !this.gameover) { if (this.leftKey.isDown) { this.rotateLeft(); } else if (this.rightKey.isDown) { this.rotateRight(); } } else { if (this.input.y >= this.sorter.y - this.sorter.height) { if (this.input.x >= this.game.world.centerX) { this.rotateRight(); } else if (this.input.x < this.game.world.centerX) { this.rotateLeft(); } } } }, rotateLeft : function () { this.clockwise = true; switch (this.orientation) { case this.Orientation.NORTH: this.orientation = this.Orientation.WEST; break; case this.Orientation.EAST: this.orientation = this.Orientation.NORTH; break; case this.Orientation.SOUTH: this.orientation = this.Orientation.EAST; break; case this.Orientation.WEST: this.orientation = this.Orientation.SOUTH; break; } this.targetRotation = this.orientation; }, rotateRight : function () { this.clockwise = false; switch (this.orientation) { case this.Orientation.NORTH: this.orientation = this.Orientation.EAST; break; case this.Orientation.EAST: this.orientation = this.Orientation.SOUTH; break; case this.Orientation.SOUTH: this.orientation = this.Orientation.WEST; break; case this.Orientation.WEST: this.orientation = this.Orientation.NORTH; break; } this.targetRotation = this.orientation; } }; EDIT: My input listeners also get jacked up. I separate mobile and desktop but when the state restarts, my mobile listeners are firing when they shouldn't be because I am using desktop, not mobile. Edited August 22, 2016 by deedeekaka Extra Information Link to comment Share on other sites More sharing options...
Yora Posted August 22, 2016 Share Posted August 22, 2016 Before calling state.start you may need to do a little manual cleanup first, like removing your event listeners, setting your array lengths to 0 (ex. this.garbage.length = 0, assures the array is cleared out and any objects referenced by it can be cleaned up by the javascript GC (Garbage Collector)), and calling destroy on sprites. Link to comment Share on other sites More sharing options...
deedeekaka Posted August 22, 2016 Author Share Posted August 22, 2016 Thanks for the reply! I've tried to implement something like you said, but unfortunately no luck.. the lives and garbage don't ever appear on the screen once the game is restarted and my event listeners still do wacky things. reset : function () { this.garbage.forEach(function(trash) { trash.destroy(); }, this); this.garbage.length = 0; this.lifeSprites.forEach(function(life) { life.destroy(); }, this); this.lifeSprites.length = 0; this.game.input.onDown.removeAll(); this.game.input.keyboard.reset(true); this.game.state.start('Game', true, false); } I am going to try a restart without using this.game.state.start() or this.game.state.restart() by just re-initializing my sprites and variables positions and values. Hopefully I can get something working! Link to comment Share on other sites More sharing options...
samme Posted August 22, 2016 Share Posted August 22, 2016 Hi deedee, If you want to use game.state.restart(), move this.garbage = []; this.lifeSprites = []; into your BasicGame.Game.prototype.create() function. In fact you probably want to move all the State properties that might change during the game session (and should be reset when restarting) there too. game.state.restart() runs the state's create() method again. It doesn't reinitialize the state, so the constructor BasicGame.Game() is never run again. deedeekaka 1 Link to comment Share on other sites More sharing options...
deedeekaka Posted August 23, 2016 Author Share Posted August 23, 2016 16 hours ago, samme said: Hi deedee, If you want to use game.state.restart(), move this.garbage = []; this.lifeSprites = []; into your BasicGame.Game.prototype.create() function. In fact you probably want to move all the State properties that might change during the game session (and should be reset when restarting) there too. game.state.restart() runs the state's create() method again. It doesn't reinitialize the state, so the constructor BasicGame.Game() is never run again. Hey! I didn't even think of this! That makes total sense. I will surely give this a shot! Link to comment Share on other sites More sharing options...
deedeekaka Posted August 23, 2016 Author Share Posted August 23, 2016 16 hours ago, samme said: Hi deedee, If you want to use game.state.restart(), move this.garbage = []; this.lifeSprites = []; into your BasicGame.Game.prototype.create() function. In fact you probably want to move all the State properties that might change during the game session (and should be reset when restarting) there too. game.state.restart() runs the state's create() method again. It doesn't reinitialize the state, so the constructor BasicGame.Game() is never run again. It works PERFECTLY and as expected now. I left all my constants outside of the create function since they will never change, and with all my variables in create(), they get reset properly everytime. Thank you for teaching me something about Phaser! You rock samme 1 Link to comment Share on other sites More sharing options...
Recommended Posts