Thank you! Unfortunately, nothing helps!
Wherever I place this.lives and no matter how I define them I get undefined, and it keeps saying this.endgame is not a function.
I made my code by taking examples from the labs.phaser.io and adapting them for my purpose.
So it must be quite a mess lol.
I’m also having a problem with creating an object pool and spawning game objects.
Some parts of the code work, others don’t. Basically most of it works, except for the object pooling and game over stuff, somehow functions addveggie and endgame bring up undefined variables, even though these variables are set to global. When I change them to this, the screen goes black altogether, I’m unable to define this on veggies and lives.
I’m trying a hands on approach to learning all this stuff but now I’m completely and utterly stuck!
I’m pulling my hair out, I just can’t understand Javascript I guess.
Here is the complete code:
let config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 100 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
let info;
let score = 0;
let lives = 1;
let zone;
let veggie;
let veggies;
let scorelabel;
let scoretween;
//target for movetoObject on the character's basket to make veggies fall there after the player clicks on them
let target = new Phaser.Math.Vector2();
// random veggie type
let veggieType = Math.floor(Math.random() * 8);
let highScore;
// this is an object catching game, help a cute character catch falling veggies. when a player clicks on a falling veggie it falls into the character's basket and the score adds up, if you miss a veggie and it falls to the ground you lose a life.
let game = new Phaser.Game(config);
function preload() {
// loading assets
this.load.image('background', 'assets/BG.png');
this.load.image('plusone', 'assets/plus-one.png')
this.load.spritesheet('char-idle',
'assets/IdleSprite.png',
{ frameWidth: 1080, frameHeight: 1080, endFrame: 3 }
);
this.load.spritesheet('char-catch',
'assets/CatchSprite.png',
{ frameWidth: 1080, frameHeight: 1080, endFrame: 3 }
);
this.load.spritesheet('veg',
'assets/veggies.png',
{ frameWidth: 512, frameHeight: 512, endFrame: 8 }
);
}
function create() {
// adding the overlap zone on the basket
zone = this.add.zone(150, 459).setSize(20, 20);
this.physics.world.enable(zone);
zone.body.setAllowGravity(false);
zone.body.moves = false;
// adding background
let bg = this.add.sprite(400, 300, 'background');
//adding the idle character animation
let animIdle = {
key: 'idle',
frames: this.anims.generateFrameNumbers('char-idle', { frames: [ 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0 ] }),
frameRate: 4,
repeat: -1
};
this.anims.create(animIdle);
// adding the catch character animation
let animCatch = {
key: 'catch',
frames: this.anims.generateFrameNumbers('char-catch', { frames: [ 0, 0, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 1, 1, 0, 0 ] }),
frameRate: 16,
repeat: 0
};
this.anims.create(animCatch);
// adding the idle sprite
this.player = this.add.sprite(100, 500, 'char-idle').play('idle');
this.player.setScale(.25);
// adding the catch sprite
this.catchPlayer = this.add.sprite(100, 500, 'char-catch').play('catch');
this.catchPlayer.setScale(.25);
this.catchPlayer.setVisible(false);
// area of the "ceiling" where the veggies will fall from
let x = Phaser.Math.Between(250, 800);
let y = 0;
// veggies group
veggies = this.physics.add.group({
key: 'veg',
frame: [veggieType],
setXY: { x: x, y: y },
maxSize: 32,
createCallback: function (veggie) {
veggie.setName('veggie' + this.getLength());
console.log('Created', veggie.name);
},
removeCallback: function (veggie) {
console.log('Removed', veggie.name);
}
});
// random veggie is created, this is supposed to go into the addveggie function, but doing so breaks my game
veggie = Phaser.Utils.Array.GetRandom(veggies.getChildren());
//input enabled, scaled and rotating while in air
veggie.setInteractive();
veggie.setScale(0.25);
veggie.setAngularAcceleration(60);
// overlap zone on the basket
this.physics.add.overlap(zone, veggie);
// taken from the phaser example on interactive object listener events:
// The images will dispatch a 'clicked' event when they are clicked on
veggie.on('clicked', clickHandler, this);
// If a Game Object is clicked on, this event is fired.
// We can use it to emit the 'clicked' event on the game object itself.
this.input.on('gameobjectup', function (pointer, gameObject)
{
gameObject.emit('clicked', gameObject);
}, this);
// Display the game stats
info = this.add.text(10, 10, '', { font: '48px Helsinki', fill: '#000000' });
//this is the problem with object pooling in my code, i commented it out for this example
/*this.time.addEvent({
delay: 300,
loop: true,
callback: addveggie
});
*/
}
function update ()
{
veggies.children.iterate(function (veggie) {
if (veggie.y > 605) {
veggies.killAndHide(veggie);
}
});
// score
info.setText('Score: ' + score + '\nLives: ' + lives);
// overlap zone on the basket, the overlap means the veggie is caught by the character in the basket, so the overlap changes the animation back to idle
let touching = zone.body.touching;
if (!touching.none) {
this.catchPlayer.setVisible(false);
this.player.setVisible(true);
veggie.setVisible(false);
}
// if the object falls to the floor, to the right of the character's position the player loses a life, I made only one life to test it
if (veggie.y > 550 && veggie.x > 150 && veggie.visible === true ) {
//score = 0;
veggie.setVisible(false);
lives --;
}
if (lives <= 0) {
this.endgame();
}
}
//this is what happens after the player clicks on the fallen veggie, "helping" the character to catch the veggie.
function clickHandler (veggie)
{
//the score grows by one point
score++;
//floating score
scorelabel = this.add.image(veggie.x, veggie.y-30, 'plusone').setScale(0.1);
// text can be used instead of an image
/*scorelabel = this.add.text(veggie.x, veggie.y-20, '+1', { fontFamily: 'Arial', fontSize: 30, color: '#ff0000'}); */
scoretween = this.tweens.add({
targets: scorelabel,
alpha: 0,
y: -30,
delay: 300,
duration: 600
});
veggie.off('clicked', clickHandler);
//the target is placed on the character's basket, where the veggie must fly to after being clicked by the player
target.x = 150;
target.y = 450;
//the veggie falls into the basket
// Moves at 1000 px/s:
this.physics.moveToObject(veggie, target, 1000);
// the idle animation is set to invisible
this.player.setVisible(false);
//the catch animation plays
this.catchPlayer.setVisible(true);
this.catchPlayer.play('catch');
veggie.input.enabled = false;
}
//this stuff is from the object pooling example
function activateveggie (veggie) {
veggie
.setActive(true)
.setVisible(true)
}
//game over stuff
function endgame() {
//this.input.off('gameobjectup');
this.add.text(400, 300, "Game Over\n\nYour score: " + score + "\nBest score: " + localStorage.score + "\n\nTap to restart", { fontFamily: 'Helsinki', fontSize: 30, color: '#ff0000'});
// restart game
this.time.delayedCall(500, function() {
this.scene.restart();
}, [], this);
};
//this is another problem area, everything is undefined when I use this function
/*
function addveggie () {
//veggie = Phaser.Utils.Array.GetRandom(veggies.getChildren());
if (!veggie) return; // None free
activateveggie(veggie);
}
*/