Cancel collision after initial detection, using phaser in js - javascript

When 2 sprites collide I'd like to count that as 1 life lost, and then cancel the collision so the sprites pass over one another. I don't want multiple lives to be lost as the same 2 sprites pass over each other.
Any ideas how I can cancel the contact after I've subsracted 1 life?
http://jsfiddle.net/bobbyrne01/44zmvm8z/
javascript ..
var player,
emitter,
lives = 5;
var game = new Phaser.Game(
800,
600,
Phaser.CANVAS,
'Game', {
preload: preload,
create: create,
update: update,
render: render
});
function preload() {
game.load.image('missile', 'http://images.apple.com/v/iphone-5s/a/images/buystrip_retail_icon.png');
game.load.image('player', 'http://38.media.tumblr.com/avatar_0714f87e9e76_128.png');
}
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.physics.arcade.gravity.y = 300;
game.stage.backgroundColor = '#000';
game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL; // Maintain aspect ratio
player = game.add.sprite(game.world.width / 2, game.world.height / 2, 'player');
player.scale.setTo(0.5, 0.5);
game.physics.arcade.enable(player);
player.body.allowGravity = false;
emitter = game.add.emitter(0, 100, 100);
emitter.makeParticles('missile');
emitter.gravity = 200;
emitter.width = 500;
emitter.x = game.world.width / 2;
emitter.y = -300;
emitter.minRotation = 0;
emitter.maxRotation = 0;
emitter.setScale(0.1, 0.5, 0.1, 0.5, 6000, Phaser.Easing.Quintic.Out);
emitter.start(false, 2000, 500);
}
function update() {
game.physics.arcade.collide(player, emitter, chec, change, this);
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
player.x -= 4;
} else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
player.x += 4;
}
}
function chec() {}
function change() {
lives--;
return false;
}
function render() {
game.debug.text('Lives: ' + lives, 2, 28, "#00ff00");
}

Is it optional to destroy the particle just after the collision? If yes, do it this way, just edit the change() function like this:
function change(a, b) {
b.destroy();
lives--;
return false;
}
The second parameter happens to be the particle itself, the first one is the emitter.

Related

How to prevent objects to jump off platforms?

I have a game set up like this:
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', {preload: preload, create: create, update: update});
var platforms;
var aGroup;
function preload() {
game.load.image('platform', 'img/platform.png');
game.load.image('a', 'img/a.png');
}
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
platforms = game.add.group();
platforms.enableBody = true;
var platform = platforms.create(100, 100, 'platform');
aGroup = game.add.group();
aGroup.enableBody = true;
platforms.forEach(function(item) {
item.body.immovable = true;
aGroup.create(item.x, item.y - 32, 'a');
}, this);
aGroup.forEach(function(a) {
a.body.velocity.x = 100;
}
}
function update() {
game.physics.arcade.collide(aGroup, platforms);
aGroup.forEach(function(a) {
if(a.body.blocked.right) {
a.body.velocity.x = -100;
}
else if(a.body.blocked.left) {
a.body.velocity.x = 100;
}, this);
}
}
Currently I can check if a is colliding with the world boundaries and if it does it changes direction. Right now when a reaches the end of the platform it just falls down. I want a to change direction when it reaches the end of the platform.
How can I do it?

Phaser: Key Down + Collision Kill

Forewarning: semi-newbie
Basically, if the user has the left cursor down and a "token" collides with the lftRect, I want to kill the token. For some reason my kill callback function for the collision is not working (below is relevant code):  
gumballGoGo.Preloader = function(game){
this.player = null;
this.ground = null;
//this.tokens = null;
this.ready = false;
};
var cursors, lftInit, rghtInit, ground, testDrp, sprite, tokens, rect, lftRect, ctrRect, rghtRect, lftToken;
var total = 0;
function lftHit(lftRect, lftToken) {
if ( lftInit == true ){
lftToken.kill()
}
};
gumballGoGo.Preloader.prototype = {
preload: function(){
},
create: function() {
// LFT BOX
lftRect = this.add.sprite(0, this.world.height - 150, null);
this.physics.enable(lftRect, Phaser.Physics.ARCADE);
lftRect.body.setSize(100, 100, 0, 0);
// CNTR BOX
ctrRect = this.add.sprite(100, this.world.height - 150, null);
this.physics.enable(ctrRect, Phaser.Physics.ARCADE);
ctrRect.body.setSize(100, 100, 0, 0);
// RGHT BOX
rghtRect = this.add.sprite(200, this.world.height - 150, null);
this.physics.enable(rghtRect, Phaser.Physics.ARCADE);
rghtRect.body.setSize(100, 100, 0, 0);
// INIT TOKEN GROUP
tokens = this.add.group();
tokens.enableBody = true;
this.physics.arcade.enable(tokens);
testDrp = tokens.create(125, -50, 'token');
testDrp.body.gravity.y = 300;
// CONTROLS
this.cursors = this.input.keyboard.createCursorKeys();
},
update: function() {
this.ready = true;
if (this.cursors.left.isDown)
{
lftInit = true;
}
else if (this.cursors.right.isDown)
{
rghtInit = true;
}
else
{
lftInit, rghtInit = false;
}
if (total < 20)
{
tokenSpawn();
}
this.physics.arcade.collide(lftRect, lftToken, lftHit, null, this);
}
};
function tokenSpawn() {
lftToken = tokens.create(25, -(Math.random() * 800), 'token');
lftToken.body.gravity.y = 300;
total++;
}
The ultimate goal is to recreate this type of gameplay. 
One additional note: as of now I am dropping "tokens" using a random spawn loop. I'd rather use a timed patter for the token drop. If you have any advice on that please share as well. Thanks :]
Not sure, so this is a guess, but you're applying the last parameter of 'this' to the function 'lfthit' that is outside of the gumballGoGo.Preloader.prototype object. What error are you getting in the console?

Sprite vs Group Collider not working in phaser with enableBody set as true

I'm a bit new to JavaScript and have been playing around with Phaser lately. So I'm building an infinite side scroller and everything works fine except that my player won't collide with the walls. Both sprites have physics enabled and I have tried multiple solutions, none of which work. Can you please help me out?
function bloxo()
{
var game = new Phaser.Game(1200, 600, Phaser.CANVAS, 'gameStage', { preload: preload, create: create, update: update });
var prevHole = 3;
function preload() {
game.load.image('bloxoDown','../bloxo/assets/images/bloxoDown.png');
game.load.image('bloxoUp','../bloxo/assets/images/bloxoUp.png');
game.load.image('wall','../bloxo/assets/images/platform.png',400,200);
var space;
var esc;
var player;
var walls;
var score;
}
function create() {
//Canvas With a White Bacground and Physics is Created
game.stage.backgroundColor = "#ffffff";
game.physics.startSystem(Phaser.Physics.ARCADE);
//Sets the initial Score.
score = 0;
//Sets how fast the tiles move
tileSpeed = -300;
tileWidth = game.cache.getImage('wall').width;
tileHeight = game.cache.getImage('wall').height;;
//Keys for User Input are created
space = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
esc = game.input.keyboard.addKey(Phaser.Keyboard.ESC);
//Adds Bloxo to the game as a sprite.
player = game.add.sprite(200,200,'bloxoDown');
player.scale.setTo(0.6, 0.6);
game.physics.enable(player, Phaser.Physics.ARCADE);
player.body.collideWorldBounds = true;
player.body.immovable = true;
//Walls Group is created
walls = game.add.physicsGroup();
walls.createMultiple(50, 'wall');
walls.enableBody = true;
game.physics.arcade.overlap(player, walls,null,this)
game.physics.arcade.collide(player,walls,gameOver);
// Stop the following keys from propagating up to the browser
game.input.keyboard.addKeyCapture([ Phaser.Keyboard.SPACEBAR, Phaser.Keyboard.ESC,]);
//Unpausing Function
window.onkeydown = function(event)
{
if (esc.onDown && (esc.timeDown > 2000))
{
if(game.paused)
{
game.paused = !game.paused;
pauseLbl.destroy();
}
}
}
//Add an initial platform
addWall();
//Add a platform every 3 seconds
var timerWorld = game.time.events.loop(500, addWall);
}
function update() {
if (space.isDown)
{
player.body.y -=5;
bloxoUp();
}
else
{
player.body.y +=5;
bloxoDown();
}
if(esc.isDown)
{
pauseGame();
}
}
function bloxoUp()
{
player.loadTexture('bloxoUp');
}
function bloxoDown()
{
player.loadTexture('bloxoDown');
}
function pauseGame()
{
game.paused = true;
pauseLbl = game.add.text(500, 300, 'Game Paused', { font: '30px Roboto', fill: '#aaaaaa' });
}
function addTile(x,y)
{
//Get a tile that is not currently on screen
var tile = walls.getFirstDead();
//Reset it to the specified coordinates
tile.reset(x,y);
tile.body.velocity.x = tileSpeed;
tile.body.immovable = true;
//When the tile leaves the screen, kill it
tile.checkWorldBounds = true;
tile.outOfBoundsKill = true;
}
function addWall()
{
//Speed up the game to make it harder
tileSpeed -= 1;
score += 1;
//Work out how many tiles we need to fit across the whole screen
var tilesNeeded = Math.ceil(game.world.height / tileHeight);
//Add a hole randomly somewhere
do
{
var hole = Math.floor(Math.random() * (tilesNeeded - 2)) + 1;
}while((hole > (prevHole + 2)) && (hole < (prevHole - 2)) );
prevHole = hole;
//Keep creating tiles next to each other until we have an entire row
//Don't add tiles where the random hole is
for (var i = 0; i < tilesNeeded; i++){
if (i != hole && (i != hole+1 && i != hole-1) && (i != hole+2 && i != hole-2)){
addTile(game.world.width, i * tileHeight);
}
}
}
function gameOver()
{
console.log("player hit");
player.kill();
game.state.start(game.state.current);
}
}
You have just to move collide call into your update method:
game.physics.arcade.collide(player, walls, gameOver);
Take a look to the runnable snippet below(I have resized the canvas for the preview, sorry) or Fiddle:
var game = new Phaser.Game(450, 150, Phaser.CANVAS, 'gameStage', {
preload: preload,
create: create,
update: update
});
var prevHole = 3;
function preload() {
game.load.image('bloxoDown', '../bloxo/assets/images/bloxoDown.png');
game.load.image('bloxoUp', '../bloxo/assets/images/bloxoUp.png');
game.load.image('wall', '../bloxo/assets/images/platform.png', 400, 100);
var space;
var esc;
var player;
var walls;
var score;
}
function create() {
//Canvas With a White Bacground and Physics is Created
game.stage.backgroundColor = "#ffffff";
game.physics.startSystem(Phaser.Physics.ARCADE);
//Sets the initial Score.
score = 0;
//Sets how fast the tiles move
tileSpeed = -300;
tileWidth = game.cache.getImage('wall').width;
tileHeight = game.cache.getImage('wall').height;;
//Keys for User Input are created
space = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
esc = game.input.keyboard.addKey(Phaser.Keyboard.ESC);
//Adds Bloxo to the game as a sprite.
player = game.add.sprite(200, 200, 'bloxoDown');
player.scale.setTo(0.6, 0.6);
game.physics.enable(player, Phaser.Physics.ARCADE);
player.body.collideWorldBounds = true;
player.body.immovable = true;
//Walls Group is created
walls = game.add.physicsGroup();
walls.createMultiple(50, 'wall');
walls.enableBody = true;
game.physics.arcade.overlap(player, walls, null, this)
// remove your call to collide
// Stop the following keys from propagating up to the browser
game.input.keyboard.addKeyCapture([Phaser.Keyboard.SPACEBAR, Phaser.Keyboard.ESC, ]);
//Unpausing Function
window.onkeydown = function(event) {
if (esc.onDown && (esc.timeDown > 2000)) {
if (game.paused) {
game.paused = !game.paused;
pauseLbl.destroy();
}
}
}
//Add an initial platform
addWall();
//Add a platform every 3 seconds
var timerWorld = game.time.events.loop(500, addWall);
}
function update() {
if (space.isDown) {
player.body.y -= 5;
bloxoUp();
} else {
player.body.y += 5;
bloxoDown();
}
// move your collide call here
game.physics.arcade.collide(player, walls, gameOver);
if (esc.isDown) {
pauseGame();
}
}
function bloxoUp() {
player.loadTexture('bloxoUp');
}
function bloxoDown() {
player.loadTexture('bloxoDown');
}
function pauseGame() {
game.paused = true;
pauseLbl = game.add.text(500, 300, 'Game Paused', {
font: '30px Roboto',
fill: '#aaaaaa'
});
}
function addTile(x, y) {
//Get a tile that is not currently on screen
var tile = walls.getFirstDead();
//Reset it to the specified coordinates
if (tile) {
tile.reset(x, y);
tile.body.velocity.x = tileSpeed;
tile.body.immovable = true;
//When the tile leaves the screen, kill it
tile.checkWorldBounds = true;
tile.outOfBoundsKill = true;
}
}
function addWall() {
//Speed up the game to make it harder
tileSpeed -= 1;
score += 1;
//Work out how many tiles we need to fit across the whole screen
var tilesNeeded = Math.ceil(game.world.height / tileHeight);
var prevHole;
//Add a hole randomly somewhere
do {
var hole = Math.floor(Math.random() * (tilesNeeded - 2)) + 1;
} while ((hole > (prevHole + 2)) && (hole < (prevHole - 2)));
prevHole = hole;
//Keep creating tiles next to each other until we have an entire row
//Don't add tiles where the random hole is
for (var i = 0; i < tilesNeeded; i++) {
if (i != hole && (i != hole + 1 && i != hole - 1) && (i != hole + 2 && i != hole - 2)) {
addTile(game.world.width, i * tileHeight);
}
}
}
function gameOver() {
console.log("player hit");
player.kill();
game.state.start(game.state.current);
}
canvas{
border: 5px solid #333;
margin-left:25px;
margin-top:25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.6.2/phaser.min.js"></script>

Phaser - Implementing states / changing active script

Sorry if this is the wrong place to put this, I haven't had much luck anywhere else unfortunately.
In Phaser I have made a tilemap and a player sprite, this all works perfectly using P2 physics. I have a door way in my tilemap which when I enter I want a different script to run, changing the current tilemap to a different one and moving the player's position accordingly.
I already have a basic if statement that checks if the player's position is within the range of the door and console logs, that works fine.
Code:
var game = new Phaser.Game(560, 560, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.tilemap('tilemap', 'assets/tilemaps/test.json', null, Phaser.Tilemap.TILED_JSON);
game.load.image('tiles', 'assets/tilemaps/tileset.png');
game.load.image('player', 'assets/images/player.png');
}
var player;
var cursors;
var map;
var layer;
function create() {
map = game.add.tilemap('tilemap');
map.addTilesetImage('basic', 'tiles');
layer = map.createLayer('Background');
layer2 = map.createLayer('Walls');
layer.resizeWorld();
game.physics.startSystem(Phaser.Physics.P2JS);
game.physics.p2.setBoundsToWorld(true, true, true, true, false);
map.setCollision(1, true, "Walls");
game.physics.p2.convertTilemap(map, "Walls");
player = game.add.sprite(game.world.centerX, game.world.centerY, 'player');
game.physics.p2.enable(player);
player.body.fixedRotation = true;
player.body.clearShapes();
player.body.addRectangle(20, 0, 0, 0);
cursors = game.input.keyboard.createCursorKeys();
game.camera.follow(player);
//player.body.debug = true;
}
function update() {
player.body.setZeroVelocity();
if (cursors.up.isDown)
{
player.body.moveUp(300)
}
else if (cursors.down.isDown)
{
player.body.moveDown(300);
}
if (cursors.left.isDown)
{
player.body.velocity.x = -300;
}
else if (cursors.right.isDown)
{
player.body.moveRight(300);
}
if (player.x > 248 && player.x < 311 && player.y < 25)
{
console.log("Door opened");
}
}
function render() {
game.debug.cameraInfo(game.camera, 32, 32);
game.debug.spriteCoords(player, 32, 500);
}

Issue with scoping, when calling a function in a callback

when clicking inside the canvas it will generate a ball and move to the clicked location
when the ball get's to its location I want it to remove itself. But i think i have a problem
with the scope when calling the removeBall() function.
You can find a working example her: jsfiddle
/*
* Main app logic
*/
function Main() {
this.canvas = "canvas";
this.stage = null;
this.WIDTH = 0;
this.HEIGHT = 0;
this.init();
}
Main.prototype.init = function() {
console.clear();
this.stage = new createjs.Stage(this.canvas);
this.resize();
//start game loop
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", this.gameLoop);
//click event handler
this.stage.on("stagemousedown", function(evt) {
main.fireBall(evt);
});
};
Main.prototype.fireBall = function(evt) {
var bal = new Bal(evt.stageX, evt.stageY);
};
Main.prototype.resize = function() {
//resize the canvas to take max width
this.WIDTH = window.innerWidth;
this.HEIGHT = Math.floor(window.innerWidth * 9 / 16);
this.stage.canvas.width = this.WIDTH;
this.stage.canvas.height = this.HEIGHT;
};
Main.prototype.gameLoop = function() {
//game loop
main.stage.update();
};
/*
* Ball logic
*/
function Bal(toX, toY) {
this.toX = toX ;
this.toY = toY;
this.widthPerc = 8;
this.init();
}
Bal.prototype.width = function() {
return Math.floor(main.stage.canvas.width / 100 * this.widthPerc);
};
Bal.prototype.init = function() {
//create a new ball
this.ball = new createjs.Shape();
this.ball.graphics.beginFill("green").drawCircle(0, 0, this.width());
this.ball.x = (main.stage.canvas.width / 2) - (this.width() / 2);
this.ball.y = main.stage.canvas.height - 20;
main.stage.addChild(this.ball);
this.move();
};
Bal.prototype.move = function() {
//create a tween to cliked coordinates
createjs.Tween.get(this.ball).to({
x: this.toX ,
y: this.toY ,
scaleX:0.4,scaleY:0.4,
rotation: 180
},
750, //speed
createjs.Ease.none
).call(this.removeBall); // <---- How can i pass the correct scope to the called function?
};
Bal.prototype.removeBall = function() {
//try to remove the ball
main.stage.removeChild(this.ball);
};
var main = new Main();
The solution above using bind works, however there is a much better solution. Bind is not available in all browsers (most notably Safari 5.1, which is a modern browser). http://kangax.github.io/es5-compat-table/#Function.prototype.bind
TweenJS has built-in support for scoping functions when using call(). Just pass the scope as the 3rd argument.
Ball.prototype.move = function() {
console.log(this.toX +","+this.toY);
createjs.Tween.get(this.ball).to({
x: this.toX ,
y: this.toY ,
scaleX:0.4,scaleY:0.4,
rotation: 180
},
750, //speed
createjs.Ease.none
).call(this.removeBall, null, this);
};
You can also pass an array of function arguments as the second parameter.
Tween.call(this.removeBall, [this.ball], this);
Ok found a solution! using the bind() functionality.
Bal.prototype.move = function() {
console.log(this.toX +","+this.toY);
createjs.Tween.get(this.ball).to({
x: this.toX ,
y: this.toY ,
scaleX:0.4,scaleY:0.4,
rotation: 180
},
750, //speed
createjs.Ease.none
).call(this.removeBall.bind(this));
};

Categories