Nikola
Nikola

Reputation: 15048

Move the sprite but don't collide with other sprites in the scene in Phaser

I'm referring to the official example on Phaser.io site, but have copied it here for reference below. What I want, and repeatedly fail to achieve is that the moving (with keyboard keys) starfield sprite would not collide with other vegies sprites.

I did go through the docs and looked here on SO and their forum, and it seems that the solutions should be easy enough; to just put the following code in the update() function:

game.world.bringToTop(sprite);

But, for some reason this is not working for me, so please tell me what I'm doing wrong.

var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update });

function preload() {

	game.load.image('sky', 'assets/skies/sky4.png');
    game.load.image('starfield', 'assets/misc/starfield.jpg');
    game.load.spritesheet('veggies', 'assets/sprites/fruitnveg64wh37.png', 64, 64);

}

var sprite;
var cursors;
var veggies;

function create() {

    game.add.image(0, 0, 'sky');

	//	Enable p2 physics
	game.physics.startSystem(Phaser.Physics.P2JS);

    //  Make things a bit more bouncey
    game.physics.p2.defaultRestitution = 0.8;

    //  Add a sprite
    sprite = game.add.tileSprite(300, 450, 200, 50, 'starfield');

    //  Enable if for physics. This creates a default rectangular body.
	game.physics.p2.enable(sprite);

    veggies = game.add.group();
    veggies.enableBody = true;
    veggies.physicsBodyType = Phaser.Physics.P2JS;

    var vegFrames = [ 1, 3, 4, 8 ];

    for (var i = 0; i < 10; i++)
    {
        var veg = veggies.create(game.world.randomX, game.world.randomY, 'veggies', game.rnd.pick(vegFrames));
        veg.body.setCircle(26);
    }

    text = game.add.text(20, 20, 'move with arrow keys', { fill: '#ffffff' });

    cursors = game.input.keyboard.createCursorKeys();

}

function update() {

	sprite.body.setZeroVelocity();
	game.world.bringToTop(veggies);

    if (cursors.left.isDown)
    {
    	sprite.body.moveLeft(400);
        sprite.tilePosition.x -= 8;
    }
    else if (cursors.right.isDown)
    {
    	sprite.body.moveRight(400);
        sprite.tilePosition.x += 8;
    }

    if (cursors.up.isDown)
    {
    	sprite.body.moveUp(400);
        sprite.tilePosition.y -= 8;
    }
    else if (cursors.down.isDown)
    {
    	sprite.body.moveDown(400);
        sprite.tilePosition.y += 8;
    }

}

edit: Solution which worked in the end thanks to SirSandman's answer:

var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });

function preload() {

    game.load.image('stars', 'assets/misc/starfield.jpg');
    game.load.spritesheet('ship', 'assets/sprites/humstar.png', 32, 32);
    game.load.image('panda', 'assets/sprites/spinObj_01.png');
    game.load.image('sweet', 'assets/sprites/spinObj_06.png');

}

var ship;
var starfield;
var cursors;

function create() {

    //  Enable P2
    game.physics.startSystem(Phaser.Physics.P2JS);

    //  Turn on impact events for the world, without this we get no collision callbacks
    game.physics.p2.setImpactEvents(true);

    game.physics.p2.restitution = 0.8;

    //  Create our collision groups. One for the player, one for the pandas
    var playerCollisionGroup = game.physics.p2.createCollisionGroup();
    var pandaCollisionGroup = game.physics.p2.createCollisionGroup();

    //  This part is vital if you want the objects with their own collision groups to still collide with the world bounds
    //  (which we do) - what this does is adjust the bounds to use its own collision group.
    game.physics.p2.updateBoundsCollisionGroup();

    starfield = game.add.tileSprite(0, 0, 800, 600, 'stars');
    starfield.fixedToCamera = true;

    var pandas = game.add.group();
    pandas.enableBody = true;
    pandas.physicsBodyType = Phaser.Physics.P2JS;

    for (var i = 0; i < 4; i++)
    {
        var panda = pandas.create(game.world.randomX, game.world.randomY, 'panda');
        panda.body.setRectangle(40, 40);

        //  Tell the panda to use the pandaCollisionGroup 
        panda.body.setCollisionGroup(pandaCollisionGroup);

        //  Pandas will collide against themselves and the player
        //  If you don't set this they'll not collide with anything.
        //  The first parameter is either an array or a single collision group.
        panda.body.collides(pandaCollisionGroup);
        panda.body.velocity.x = 500;
        panda.body.velocity.y = 500;
    }

    //  Create our ship sprite
    ship = game.add.sprite(200, 200, 'ship');
    ship.scale.set(2);
    ship.smoothed = false;
    ship.animations.add('fly', [0,1,2,3,4,5], 10, true);
    ship.play('fly');

    game.physics.p2.enable(ship, false);
    ship.body.setCircle(28);
    ship.body.fixedRotation = true;

    //  Set the ships collision group
    ship.body.setCollisionGroup(playerCollisionGroup);

    //  The ship will collide with the pandas, and when it strikes one the hitPanda callback will fire, causing it to alpha out a bit
    //  When pandas collide with each other, nothing happens to them.
    
    game.camera.follow(ship);

    cursors = game.input.keyboard.createCursorKeys();

}

function hitPanda(body1, body2) {

    //  body1 is the space ship (as it's the body that owns the callback)
    //  body2 is the body it impacted with, in this case our panda
    //  As body2 is a Phaser.Physics.P2.Body object, you access its own (the sprite) via the sprite property:
    body2.sprite.alpha -= 0.1;

}

function update() {

    ship.body.setZeroVelocity();

    if (cursors.left.isDown)
    {
        ship.body.moveLeft(200);
    }
    else if (cursors.right.isDown)
    {
        ship.body.moveRight(200);
    }

    if (cursors.up.isDown)
    {
        ship.body.moveUp(200);
    }
    else if (cursors.down.isDown)
    {
        ship.body.moveDown(200);
    }

    if (!game.camera.atLimit.x)
    {
        starfield.tilePosition.x += (ship.body.velocity.x * 16) * game.time.physicsElapsed;
    }

    if (!game.camera.atLimit.y)
    {
        starfield.tilePosition.y += (ship.body.velocity.y * 16) * game.time.physicsElapsed;
    }

}

function render() {

    game.debug.text('Collide with the Pandas!', 32, 32);

}

Upvotes: 0

Views: 2446

Answers (1)

SirSandmann
SirSandmann

Reputation: 300

I P2 you have to set the Collisiongroups in contrast to arcarde. I think you have to set a collisiongroup for the sprite like that:

 var veggCollisionGroup = game.physics.p2.createCollisionGroup();

and then define with which other groups this group shell collide like that in the Loop:

veggies.body.setCollisionGroup(veggCollisionGroup);
veggies.body.collides(veggCollisionGroup); 

And then the your tilesprite should collide with your other tilesprites.

Source: http://phaser.io/examples/v2/p2-physics/collision-groups if i should be wrong you will find your answer in the examples. :)

Upvotes: 1

Related Questions