Phaser: remove a circle previously drawn with drawCircle - phaser-framework

In Phaser (2.4.x), I'm drawing a circle around a sprite when it is dragged:
function dragStart(sprite, pointer, dragX, dragY) {
var graphics = game.add.graphics(0, 0);
graphics.lineStyle(6, 0x909090, 0.3);
graphics.drawCircle(dragX, dragY, 200);
}
That works fine, but now I need to remove the circle when the drag ends, and I can't figure that part out:
function dragStop() {
// ?
}
Is it possible to remove graphics? Is there a better or simpler option to draw a circle and remove it later?

You could kill() the object
But be carefull with the scope of the var you want kill (you are defining it inside the function).
Or you could just create the graphic and then show or hide depending of your event (drag)
I leave you a very simple example with both solutions:
var game = new Phaser.Game(500, 500, Phaser.AUTO, 'game');
var mainState = {
create:function(){
var graphics = game.add.graphics(0, 0);
graphics.lineStyle(6, 0x909090, 0.3);
graphics.drawCircle(game.world.centerX+100,game.world.centerY+100, 200);
console.log(graphics);
setTimeout(function(){
graphics.kill();
},2000);
this.graphics2 = game.add.graphics(0, 0);
this.graphics2.lineStyle(6, 0xff0000, 1);
this.graphics2.drawCircle(game.world.centerX-100,game.world.centerY-100, 200);
this.graphics2.visible = false;
this.show_later = game.time.now + 2000;
this.hide_again = game.time.now + 4000;
},
update:function(){
if(this.show_later < game.time.now){
this.graphics2.visible = false;
}
if(this.hide_again < game.time.now){
this.graphics2.visible = true;
}
},
};
game.state.add('main', mainState);
game.state.start('main');
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.4.4/phaser.min.js"></script>
<div id="game"></div>

Related

Three.js shooting bullet

I'm a beginner in three.js. My task is to build a simple FPS game. I'm having many troubles with the gun and the bullets. When I press "spacebar" my weapon shoots but the problem is that the bullets go in the right direction only for a small part of the screen then they start to go in direction that are not the ones I want.
This is an example :
image1
image2
Here is the code I wrote for the bullet :
// SHOOT BULLET
for(var index=0; index<bullets.length; index+=1){
if( bullets[index] === undefined ) continue;
if( bullets[index].alive == false ){
bullets.splice(index,1);
continue;
}
bullets[index].position.add(bullets[index].velocity);
}
if(keyboard[32] && canShoot <= 0){ // spacebar key
// creates a bullet as a Mesh object
var bullet = new THREE.Mesh(
new THREE.SphereGeometry(0.2,8,8),
new THREE.MeshBasicMaterial({color:0x42FFFF})
);
// position the bullet to come from the player's weapon
bullet.position.set(
camera.position.x - 0.7*parseInt(-Math.cos(camera.rotation.z)),
camera.position.y - 0.3,
camera.position.z +1*parseInt(-Math.cos(camera.rotation.z))
);
// set the velocity of the bullet
bullet.velocity = new THREE.Vector3( (-mouse.x - Math.sin(camera.rotation.y + Math.PI/6) * 7),//*parseInt(-Math.cos(camera.rotation.z)) ,
mouse.y,
Math.cos(camera.rotation.y)*parseInt(-Math.cos(camera.rotation.z))
).normalize();
console.info(bullet.velocity);
// after 1000ms, set alive to false and remove from scene
// setting alive to false flags our update code to remove
// the bullet from the bullets array
bullet.alive = true;
setTimeout(function(){
bullet.alive = false;
scene.remove(bullet);
}, 1000);
// add to scene, array, and set the delay to 10 frames
bullets.push(bullet);
scene.add(bullet);
canShoot = 10;
}
if(canShoot > 0) canShoot -= 1;
A rough concept of how you can set direction and movement of bullets:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 10000);
camera.position.set(0, 0, 1);
scene.add(camera);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var background = new THREE.Mesh(new THREE.SphereGeometry(1000, 90, 45), new THREE.MeshBasicMaterial({
color: "gray",
wireframe: true
}));
scene.add(background);
var weapon = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 5), new THREE.MeshBasicMaterial({
color: 0x5555ff
}));
weapon.position.set(2, -1, -2.5);
camera.add(weapon);
var emitter = new THREE.Object3D();
emitter.position.set(2, -1, -5);
camera.add(emitter);
var plasmaBalls = [];
window.addEventListener("mousedown", onMouseDown);
function onMouseDown() {
let plasmaBall = new THREE.Mesh(new THREE.SphereGeometry(0.5, 8, 4), new THREE.MeshBasicMaterial({
color: "aqua"
}));
plasmaBall.position.copy(emitter.getWorldPosition()); // start position - the tip of the weapon
plasmaBall.quaternion.copy(camera.quaternion); // apply camera's quaternion
scene.add(plasmaBall);
plasmaBalls.push(plasmaBall);
}
var speed = 50;
var clock = new THREE.Clock();
var delta = 0;
(function render() {
requestAnimationFrame(render);
delta = clock.getDelta();
plasmaBalls.forEach(b => {
b.translateZ(-speed * delta); // move along the local z-axis
});
renderer.render(scene, camera);
})()
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.115.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.115.0/examples/js/controls/OrbitControls.js"></script>

.svg asset in three.js 3d space

I'm trying to load a .svg asset into my three.js scene, as a flat vector layer; I found this example with SVGLoader and SVGRenderer from another post, but I can't make it work.
The svg loaded is stuck in 2d space and not responding to camera movement, I can't access its position.
I tried to switch to WebGLRenderer, but the svg doesn’t get loaded.
The option of loading it as sprite would be good, but I would want the sprite to not face the camera and stay still in 3d space.
var svgManager = new THREE.SVGLoader();
var url = 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Europe_laea_location_map.svg';
function svg_loading_done_callback(doc) {
init();
svg(new THREE.SVGObject(doc));
ico();
animate();
};
svgManager.load(url,
svg_loading_done_callback,
function() {
console.log("Loading SVG...");
},
function() {
console.log("Error loading SVG!");
});
var AMOUNT = 100;
var container, camera, scene, renderer;
function init() {
scene = new THREE.Scene();
renderer = new THREE.SVGRenderer();
renderer.setClearColor(0x00ff00);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
var container = document.getElementById('container');
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1100;
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableZoom = true;
window.addEventListener('resize', onWindowResize, false);
}
function svg(svgObject) {
svgObject.position.x = 510;
svgObject.position.y = -110;
svgObject.position.z = 0;
scene.add(svgObject);
}
function ico() {
geometry = new THREE.IcosahedronGeometry(100, 1)
material = new THREE.MeshNormalMaterial({});
ico = new THREE.Mesh(geometry, material);
ico.position.y = -300;
scene.add(ico);
ico2 = new THREE.Mesh(geometry, material);
ico2.position.y = 500;
ico2.position.x = -500;
ico2.position.z = -50;
scene.add(ico2);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update;
render();
}
function render() {
renderer.render(scene, camera);
}
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%
}
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<div id="container"></div>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/renderers/SVGRenderer.js"></script>
<script src="https://threejs.org/examples/js/renderers/Projector.js"></script>
<script src="https://threejs.org/examples/js/loaders/SVGLoader.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
The SVGLoader and SVGRenderer are two different things. The first loads an SVG file and converts it to three.js shapes (albeit with some limitations, i.e. can read very simple SVGs, does not render strokes but only filled objects, etc), while the latter renders three.js primitives using SVG elements instead of WebGL. In a sense, they are opposites of each other.
So, first of all, you'd need to use the WebGLRenderer for your case.
Then, you need to change the SVG loading callback. It receives an array of paths with which you can render the SVG.
See the changes in functions svg_loading_done_callback, init and svg, and run it in JSFiddle:
var svgManager = new THREE.SVGLoader();
var url = 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Europe_laea_location_map.svg';
function svg_loading_done_callback(paths) {
init();
svg(paths);
ico();
animate();
};
svgManager.load(url,
svg_loading_done_callback,
function() {
console.log("Loading SVG...");
},
function() {
console.log("Error loading SVG!");
});
var AMOUNT = 100;
var container, camera, scene, renderer;
function init() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x00ff00);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
var container = document.getElementById('container');
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1100;
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableZoom = true;
window.addEventListener('resize', onWindowResize, false);
}
function svg(paths) {
var group = new THREE.Group();
group.position.x = 510;
group.position.y = -110;
group.position.z = 0;
for ( var i = 0; i < paths.length; i ++ ) {
var path = paths[ i ];
var material = new THREE.MeshBasicMaterial( {
color: path.color,
side: THREE.DoubleSide,
depthWrite: false
} );
var shapes = path.toShapes( true );
for ( var j = 0; j < shapes.length; j ++ ) {
var shape = shapes[ j ];
var geometry = new THREE.ShapeBufferGeometry( shape );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
}
}
scene.add( group );
}
function ico() {
geometry = new THREE.IcosahedronGeometry(100, 1)
material = new THREE.MeshNormalMaterial({});
ico = new THREE.Mesh(geometry, material);
ico.position.y = -300;
scene.add(ico);
ico2 = new THREE.Mesh(geometry, material);
ico2.position.y = 500;
ico2.position.x = -500;
ico2.position.z = -50;
scene.add(ico2);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update;
render();
}
function render() {
renderer.render(scene, camera);
}
PS: Check the SVG Loader to see what it's able to parse

Phaser scaling is changing my game bounds

I'm building a platformer game in Phaser. I have a player which can move left or right & since the game bound is set it stops when hits the left & right portion of the screen.
Main game settings:
var game = new Phaser.Game(360, 592, Phaser.AUTO);
this.game.world.setBounds(0, 0, 360, 700);
A camera is following the player:
this.camera.follow(this.player);
I have a spritesheet of the player that contains the animation of it moving but it has only left moving animations & i'm using
this.player.scale.setTo(-1, 1);
to play the reverse animation in the right moving case which is working fine & but due to which the right bound has been decreased somehow i.e the player is hitting everything 15px before the actualy position where it should stop.
Here's the screenshots:
^ When the right collision is perfect i.e before adding scale on right key animation
^ When the scale is set to -1
Note:
Event the collision with fire when moving right is before the same distance off as with the wall.
Update:
Result after debugging the body of the player & when moving right:
The green box (i.e body)is actually on the right of the player when moving right & on moving left it's exactly on the player.(game.debug.body(this.player);)
The pink border is of the sprite (game.debug.spriteBounds(this.player, 'pink', false);)
Observation:
I think the sprite is flipping around it's center since the anchor of it is set to 0.5 but the debugger box is flipping around the right side of the sprite.. Weird 😕
Here is the complete code of the game:
var GameState = {
init: function() {
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
this.game.physics.startSystem(Phaser.Physics.ARCADE);
this.game.physics.arcade.gravity.y = 1500;
this.cursors = this.game.input.keyboard.createCursorKeys();
this.PLAYER_SPEED = 200;
this.JUMP_SPEED = 670;
this.game.world.setBounds(0, 0, 360, 700);
},
preload: function() {
this.load.image('ground', 'assets/monster-kong/ground.png');
this.load.image('actionButton', 'assets/monster-kong/actionButton.png');
this.load.image('arrowButton', 'assets/monster-kong/arrowButton.png');
this.load.image('barrel', 'assets/monster-kong/barrel.png');
this.load.image('gorilla', 'assets/monster-kong/gorilla3.png');
this.load.image('platform', 'assets/monster-kong/platform.png');
this.load.spritesheet('player', 'assets/monster-kong/player_spritesheet.png', 28, 30, 5, 1, 1);
this.load.spritesheet('fire', 'assets/monster-kong/fire_spritesheet.png', 20, 21, 2, 1, 1);
this.load.text('level', 'assets/monster-kong/level.json');
},
create: function() {
var levelData = JSON.parse(this.game.cache.getText('level'));
this.ground = this.add.sprite(0, 638, 'ground');
this.game.physics.arcade.enable(this.ground);
this.ground.body.allowGravity = false;
this.ground.body.immovable = true;
console.log(levelData);
this.platforms = this.add.group();
this.platforms.enableBody = true;
levelData.platformPositions.forEach(function(platform) {
this.platforms.create(platform.x, platform.y, 'platform');
}, this);
this.platforms.setAll('body.immovable', true);
this.platforms.setAll('body.allowGravity', false);
//fire
this.fires = this.add.group();
this.fires.enableBody = true;
this.fires.setAll('body.allowGravity', false);
console.log(levelData.firePositions);
levelData.firePositions.forEach(function(fire) {
var currentFire = this.fires.create(fire.x, fire.y, 'fire');
currentFire.animations.add('firedance', [0,1], 4, true);
currentFire.play('firedance');
}, this);
this.fires.setAll('body.allowGravity', false);
this.player = this.add.sprite(levelData.playerPosition.x, levelData.playerPosition.y, 'player', 3);
this.player.anchor.setTo(0.5,0.5);
this.player.animations.add('walking', [0, 1, 2, 1], 6, true);
this.player.properties = {};
this.game.physics.arcade.enable(this.player);
this.player.body.collideWorldBounds = true;
this.camera.follow(this.player);
this.createOnScreenControls();
},
update: function() {
this.game.physics.arcade.collide(this.player, this.ground);
this.game.physics.arcade.collide(this.player, this.platforms);
this.game.physics.arcade.overlap(this.player, this.fires, this.killPlayer);
this.player.body.velocity.x = 0;
if(this.cursors.left.isDown || this.player.properties.isMovingLeft) {
this.player.body.velocity.x = -this.PLAYER_SPEED;
this.player.scale.setTo(1,1);
this.player.play('walking');
}else if(this.cursors.right.isDown || this.player.properties.isMovingRight) {
this.player.body.velocity.x = this.PLAYER_SPEED;
this.player.scale.setTo(-1,1);
this.player.play('walking');
}else {
this.player.animations.stop();
this.player.frame = 4;
}
if((this.cursors.up.isDown || this.player.properties.isJumping )&& this.player.body.touching.down) {
this.player.body.velocity.y = -this.JUMP_SPEED;
}
},
createOnScreenControls: function() {
this.leftArrow = this.add.button(20, 535, 'arrowButton');
this.rightArrow = this.add.button(110, 535, 'arrowButton');
this.actionButton = this.add.button(280, 535, 'actionButton');
this.leftArrow.alpha = 0.5;
this.rightArrow.alpha = 0.5;
this.actionButton.alpha = 0.5;
this.leftArrow.fixedToCamera = true;
this.rightArrow.fixedToCamera = true;
this.actionButton.fixedToCamera = true;
this.leftArrow.events.onInputDown.add(function() {
this.player.properties.isMovingLeft = true;
}, this);
this.leftArrow.events.onInputUp.add(function() {
this.player.properties.isMovingLeft = false;
}, this);
this.rightArrow.events.onInputDown.add(function() {
this.player.properties.isMovingRight = true;
}, this);
this.rightArrow.events.onInputUp.add(function() {
this.player.properties.isMovingRight = false;
}, this);
this.actionButton.events.onInputDown.add(function() {
this.player.properties.isJumping = true;
}, this);
this.actionButton.events.onInputUp.add(function() {
this.player.properties.isJumping = false;
}, this);
},
killPlayer: function(player, fire) {
game.state.start('GameState');
},
render: function() {
game.debug.spriteInfo(this.player, 32, 32);
game.debug.body(this.player);
game.debug.spriteBounds(this.player, 'pink', false);
}
};
var game = new Phaser.Game(360, 592, Phaser.AUTO);
game.state.add('GameState',GameState);
game.state.start('GameState');
Anyone can help me with this issue ?
I understand your problem, your player physics body some how moved to right its not is center position. I can't give you solution without viewing proper code. I assumed that there is a line like this body.setSize(width, height, offsetX, offsetY); if there then comment out the line and see if its fix the issue. another solution set the anchor of the player - this.player.scale.setTo(-0.5, 0.5); if that solve your problem. In nutshell your player physics body moved to right of the player so that its occurring this wired problem.
SOLUTION (kind of) So I went ahead with editing the sprite & made a reflection & appended it on the right.. so now I have diff frames for right & diff for left but I still wasn't able to determine the reason of why that scale hack wasn't working.
Here's the new sprite:
Thank you everyone for your help.

Phaser: background image issue

So, i have this problem, i'm doing that "flapy bird" game with Phaser, but when i put a background image moving, the other images (like the bird, pipes, and everything) won't display, and i don't know why, any ideas?, here's my code:
// Initialize Phaser, and creates a 400x490px game
var game = new Phaser.Game(400, 490, Phaser.AUTO, 'game_div');
// Creates a new 'main' state that wil contain the game
var main_state = {
preload: function() {
// Change the background color of the game
// this.game.stage.backgroundColor = '#71c5cf';
// Load the bird sprite
this.game.load.image('bird', 'assets/bird2.png');
this.game.load.image('pipe', 'assets/pipe.png');
this.game.load.audio('jump', 'assets/jump.wav');
this.game.load.image("background", "assets/background.png");
},
create: function() {
// Display the bird on the screen
this.bird = this.game.add.sprite(100, 245, 'bird');
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe');
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);
this.score = 0;
var style = { font: "30px Arial", fill: "#ffffff" };
this.label_score = this.game.add.text(20, 20, "0", style);
this.jump_sound = this.game.add.audio('jump');
this.bg= game.add.tileSprite(0, 0, game.stage.bounds.width, game.cache.getImage('background').height, 'background');
// Add gravity to the bird to make it fall
this.bird.body.gravity.y = 1000;
// Call the 'jump' function when the spacekey is hit
var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this);
this.bird.anchor.setTo(-0.2, 0.5);
},
update: function() {
// If the bird is out of the world (too high or too low), call the 'restart_game' function
if (this.bird.inWorld == false)
this.restart_game();
this.game.physics.overlap(this.bird, this.pipes, this.restart_game, null, this);
if (this.bird.angle < 20)
this.bird.angle += 1;
this.game.physics.overlap(this.bird, this.pipes, this.hit_pipe, null, this);
this.bg.tilePosition.x -= 1;
},
// Make the bird jump
jump: function() {
this.jump_sound.play();
if (this.bird.alive == false)
return;
// Add a vertical velocity to the bird
this.bird.body.velocity.y = -350;
// create an animation on the bird
var animation = this.game.add.tween(this.bird);
// Set the animation to change the angle of the sprite to -20° in 100 milliseconds
animation.to({angle: -20}, 100);
// And start the animation
animation.start();
},
// Restart the game
restart_game: function() {
// Start the 'main' state, which restarts the game
this.game.state.start('main');
this.game.time.events.remove(this.timer);
},
add_one_pipe: function(x, y) {
// Get the first dead pipe of our group
var pipe = this.pipes.getFirstDead();
// Set the new position of the pipe
pipe.reset(x, y);
// Add velocity to the pipe to make it move left
pipe.body.velocity.x = -200;
// Kill the pipe when it's no longer visible
pipe.outOfBoundsKill = true;
},
add_row_of_pipes: function() {
var hole = Math.floor(Math.random()*5)+1;
for (var i = 0; i < 8; i++)
if (i != hole && i != hole +1)
this.add_one_pipe(400, i*60+10);
this.score += 1;
this.label_score.content = this.score;
},
hit_pipe: function() {
// Set the alive property of the bird to false
this.bird.alive = false;
// Prevent new pipes from appearing
this.game.time.events.remove(this.timer);
// Go through all the pipes, and stop their movement
this.pipes.forEachAlive(function(p){
p.body.velocity.x = 0;
}, this);
},
};
// Add and start the 'main' state to start the game
game.state.add('main', main_state);
game.state.start('main');
maybe try to add the background first in your create function.
create: function() {
// Display background
this.bg= this.game.add.tileSprite(0, 0, game.stage.bounds.width, game.cache.getImage('background').height, 'background');
// Display the bird on the screen
this.bird = this.game.add.sprite(100, 245, 'bird');
...
},
sometimes you use this.game and sometimes just game.

Wait for click before starting the game in phaser

The JSFiddle demo is here, but am pasting the code below also. My question is simple (though I can't seem to find any example in how to realize this): right now if you start the game in JSFiddle you will see that the rectangle immediately "falls" down. I would somehow like the game to start when I click with the mouse (basically that nothing happens before the first click of a mouse) - any points on how to accomplish this?
JS:
// Initialize Phaser, and creates a 400x490px game
var game = new Phaser.Game(400, 490, Phaser.AUTO, 'game_div');
var game_state = {};
// Creates a new 'main' state that wil contain the game
game_state.main = function () {};
game_state.main.prototype = {
preload: function () {
// Change the background color of the game
this.game.stage.backgroundColor = '#71c5cf';
// Load the bird sprite
this.game.load.image('bird', 'https://lh6.googleusercontent.com/Xrz0PnR6Ezg5_k5zyFKxGv0LzehAP9SMj_ga3qQzIF4JAfv8xHm7TxfliwtBD8ihfw=s190');
this.game.load.image('pipe', 'https://lh4.googleusercontent.com/RSMNhJ3KY4Xl0PQpUf6I9EayOdLhvOKKV9QV7_BXXYVedPy0oMNRFKANW14xV76NDA=s190');
},
create: function () {
// Display the bird on the screen
this.bird = this.game.add.sprite(100, 245, 'bird');
// Add gravity to the bird to make it fall
this.bird.body.gravity.y = 1000;
// Call the 'jump' function when the spacekey is hit
var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this);
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe');
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);
this.score = 0;
var style = {
font: "30px Arial",
fill: "#ffffff"
};
this.label_score = this.game.add.text(20, 20, "0", style);
},
update: function () {
// If the bird is out of the world (too high or too low), call the 'restart_game' function
this.game.physics.overlap(this.bird, this.pipes, this.restart_game, null, this);
if (this.bird.inWorld == false) this.restart_game();
},
// Make the bird jump
jump: function () {
// Add a vertical velocity to the bird
this.bird.body.velocity.y = -350;
},
// Restart the game
restart_game: function () {
// Start the 'main' state, which restarts the game
this.game.time.events.remove(this.timer);
this.game.state.start('main');
},
add_one_pipe: function (x, y) {
// Get the first dead pipe of our group
var pipe = this.pipes.getFirstDead();
// Set the new position of the pipe
pipe.reset(x, y);
// Add velocity to the pipe to make it move left
pipe.body.velocity.x = -200;
// Kill the pipe when it's no longer visible
pipe.outOfBoundsKill = true;
},
add_row_of_pipes: function () {
this.score += 1;
this.label_score.content = this.score;
var hole = Math.floor(Math.random() * 5) + 1;
for (var i = 0; i < 8; i++)
if (i != hole && i != hole + 1) this.add_one_pipe(400, i * 60 + 10);
},
};
// Add and start the 'main' state to start the game
game.state.add('main', game_state.main);
game.state.start('main');
CSS:
#game_div {
width: 400px;
margin: auto;
margin-top: 50px;
}
HTML:
<div id="game_div"></div>
So, to not leave this question unanswered and to help further readers, here is the link to the updated jsFiddle where I solved my initial problem, and below is the code from jsFiddle.
However, if one will be interested I suggest taking a look at the freely available code on GitHub which uses game states and has a better structured code.
jsFiddle
CSS:
#game_div {
width: 400px;
margin: auto;
margin-top: 50px;
}
HTML:
<div id="game_div"></div>
JS:
// Initialize Phaser, and creates a 400x490px game
var game = new Phaser.Game(400, 490, Phaser.AUTO, 'game_div');
var game_state = {};
var gameStarted = false;
// Creates a new 'main' state that wil contain the game
game_state.main = function () {};
game_state.main.prototype = {
game_start: function(){
if (!gameStarted){
this.bird.body.gravity.y = 1000;
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);
this.label_start.content = "";
}
gameStarted = true;
},
preload: function () {
// Change the background color of the game
this.game.stage.backgroundColor = '#71c5cf';
// Load the bird sprite
this.game.load.image('bird', 'https://lh6.googleusercontent.com/Xrz0PnR6Ezg5_k5zyFKxGv0LzehAP9SMj_ga3qQzIF4JAfv8xHm7TxfliwtBD8ihfw=s190');
this.game.load.image('pipe', 'https://lh4.googleusercontent.com/RSMNhJ3KY4Xl0PQpUf6I9EayOdLhvOKKV9QV7_BXXYVedPy0oMNRFKANW14xV76NDA=s190');
},
create: function () {
// Display the bird on the screen
this.bird = this.game.add.sprite(100, 245, 'bird');
// Add gravity to the bird to make it fall
// Call the 'jump' function when the spacekey is hit
this.game.input.onDown.add(this.game_start, this);
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe');
this.score = 0;
var style = {
font: "30px Arial",
fill: "#ffffff"
};
this.label_score = this.game.add.text(20, 20, "0", style);
this.label_start = this.game.add.text(35, 180, "Click to start the show", style);
game.input.onDown.add(this.jump, this);
},
update: function () {
// If the bird is out of the world (too high or too low), call the 'restart_game' function
this.game.physics.overlap(this.bird, this.pipes, this.restart_game, null, this);
if (this.bird.inWorld == false) this.restart_game();
},
// Make the bird jump
jump: function () {
// Add a vertical velocity to the bird
this.bird.body.velocity.y = -350;
},
// Restart the game
restart_game: function () {
// Start the 'main' state, which restarts the game
this.game.time.events.remove(this.timer);
this.game.state.start('main');
gameStarted=false;
},
add_one_pipe: function (x, y) {
// Get the first dead pipe of our group
var pipe = this.pipes.getFirstDead();
// Set the new position of the pipe
pipe.reset(x, y);
// Add velocity to the pipe to make it move left
pipe.body.velocity.x = -200;
// Kill the pipe when it's no longer visible
pipe.outOfBoundsKill = true;
},
add_row_of_pipes: function () {
this.score += 1;
this.label_score.content = this.score;
var hole = Math.floor(Math.random() * 5) + 1;
for (var i = 0; i < 8; i++)
if (i != hole && i != hole + 1) this.add_one_pipe(400, i * 60 + 10);
},
};
// Add and start the 'main' state to start the game
game.state.add('main', game_state.main);
game.state.start('main');

Resources