Jump to content

P2 Not Colliding With World Bounds


Recommended Posts

So I'm trying to setup a ragdoll, and right now I'm just doing some basic stuff where:

 

-I create a head and body.

-Connect them via a joint

-add them to figure group

-load the figure group

 

But for some reason they won't collide with world bounds. 

I'm including some of my code:

 

Group:

'use strict';var Head = require('./head');var Body = require('./body');var Figure = function(game, parent) {  Phaser.Group.call(this, game, parent);  this.head = new Head(this.game,0,0,0);  this.add(this.head);  this.topBody = new Body(this.game, 34,34,0);  this.add(this.topBody);  var hbConstraint = game.physics.p2.createDistanceConstraint(this.head, this.topBody, 34);  };Figure.prototype = Object.create(Phaser.Group.prototype);Figure.prototype.constructor = Figure;Figure.prototype.update = function() {    // write your prefab's specific update code here  };module.exports = Figure;

Head piece:

'use strict';var Head = function(game, x, y, frame) {  Phaser.Sprite.call(this, game, x, y, 'Head', frame);  this.anchor.setTo(0.5,0.5);  this.game.physics.p2.enableBody(this);  this.body.clearShapes();  this.body.loadPolygon('headPhysics', 'Head');  this.body.collideWorldBounds = true;  this.game.physics.p2.updateBoundsCollisionGroup();  };Head.prototype = Object.create(Phaser.Sprite.prototype);Head.prototype.constructor = Head;Head.prototype.update = function() {    // write your prefab's specific update code here  };module.exports = Head;

Any idea what I'm doing wrong?

Link to post
Share on other sites
  • 3 weeks later...

Also having a problem with collideWorldBounds working in the p2 physics engine.

 

It worked perfectly with ARCADE, but as I am creating more of a top-down than a platform, I changed to p2, and cannot seem to find an equivalent. The sprite now just walks off the screen.

 

Here is my code;

function create() {    game.physics.startSystem(Phaser.Physics.P2JS);    map = game.add.tilemap('equi');    map.addTilesetImage('image', 'tiles');    layer1 = map.createLayer('background');    layer2 = map.createLayer('foreground');    layer1.resizeWorld();	    map.setCollision(27);	    game.physics.p2.convertTilemap(map, layer2);    player = game.add.sprite(20, 20, 'charc');    game.physics.p2.enable(player);    player.body.setZeroDamping();	    player.body.fixedRotation = true;    player.body.collideWorldBounds = true;	    game.camera.follow(player);	    player.animations.add('down', [0, 1, 2], 10);     player.animations.add('left', [12, 13, 14], 10);    player.animations.add('right', [24, 25, 26], 10);    player.animations.add('up', [36, 37, 38], 10);	    cursors = game.input.keyboard.createCursorKeys();    }

All the examples I have looked at have a boundary or barrier to prevent the sprite from disappearing off screen, so I am starting to becoming a bit stumped with this too. Obviously missing something somewhere, can anyone spot what it is? Using 2.0.4.

 

Sorry I can't help with the original post, but thought I'd best post here rather than make another thread on the same subject. Thanks.

Link to post
Share on other sites

Lots of the P2 examples use world boundary collision (I don't think any have barriers in fact!)

 

Here's one such example: http://examples.phaser.io/_site/view_full.html?d=p2%20physics&f=world+move.js&t=world%20move

 

This is all you need for world boundary collision in P2:

    game.world.setBounds(0, 0, 1600, 1200);    game.physics.startSystem(Phaser.Physics.P2JS);

setBounds called before startSystem. And that's it basically.

Link to post
Share on other sites

The Tilemap and Tilemap gravity examples both use a boundary and they were the two I was concentrating on as using a tilemap. Although I have been through so many examples and code today >.< I did go through the other P2 examples and spotted;

 game.world.setBounds(0, 0, 1600, 1200);

in a number of scripts, so I added it in to try. It didn't fix the boundary collision so figured it was not that.

Have just added it in again to the very top of my code above and sure enough it's still not working. I can post a link so you can see exactly what I mean if that if more helpful?

 

Got collision working with the tilemaps, its just the boundary :/

 

Cheers.

Link to post
Share on other sites

This is the code I am using:

function create() {    game.world.setBounds(0, 0, 1600, 1600);    game.physics.startSystem(Phaser.Physics.P2JS);    map = game.add.tilemap('equi');    map.addTilesetImage('image', 'tiles');    layer1 = map.createLayer('background');    layer2 = map.createLayer('foreground');    layer1.resizeWorld();	    map.setCollision(27);	    game.physics.p2.convertTilemap(map, layer2);    player = game.add.sprite(20, 20, 'charc');    game.physics.p2.enable(player);    player.body.setZeroDamping();	    player.body.fixedRotation = true;    player.body.collideWorldBounds = true;	    game.camera.follow(player);	    player.animations.add('down', [0, 1, 2], 10);     player.animations.add('left', [12, 13, 14], 10);    player.animations.add('right', [24, 25, 26], 10);    player.animations.add('up', [36, 37, 38], 10);	    cursors = game.input.keyboard.createCursorKeys();    }

This is the result: The sprite is able to walk through the boundary, but collides correctly with the cacti.

 

http://eponaweb.com/test.html

Link to post
Share on other sites

Removed the following line;

player.body.collideWorldBounds = true;

but has not fixed issue. Sprite still able to walk off screen. Thanks for your help and suggestions so far rich. I will have another delve into the examples and see if I can spot anything else.

 

Cheers.

Link to post
Share on other sites

Not sure if it is related, but when the screen loads, only half the sprite appears. 

player = game.add.sprite(0, 0, 'charc');

To make the sprite appear inside the screen onload, I have to change the above parameters to 20, 20. Could this be linked?

 

 

Going through examples trying out different scenarios atm so will report back if I find anything.

Link to post
Share on other sites

Ok both the 2 issues;

 

1) Sprite appearing half off screen when loading

2) No world boundary

 

seem to be linked to the tilemaps. I have stripped down my code to just a very basic walking sprite on a screen, no tiles/maps, just background colour.

var game = new Phaser.Game(512, 384, Phaser.AUTO, '', { preload: preload, create: create, update: update }); function preload() { game.load.spritesheet('charc', 'assets/char01.png', 32, 48);  } var charc;var cusrors; function create() {  game.world.setBounds(0, 0, 1600, 1600); game.physics.startSystem(Phaser.Physics.P2JS); game.stage.backgroundColor = '#006500'; player = game.add.sprite(0, 0, 'charc'); game.physics.p2.enable(player); game.camera.follow(player); player.animations.add('down', [0, 1, 2], 10); player.animations.add('left', [12, 13, 14], 10);player.animations.add('right', [24, 25, 26], 10);player.animations.add('up', [36, 37, 38], 10); cursors = game.input.keyboard.createCursorKeys();    } function update() { player.body.setZeroVelocity();  if (cursors.left.isDown)    {        player.body.moveLeft(200);         player.animations.play('left');    }    else if (cursors.right.isDown)    {        player.body.moveRight(200);         player.animations.play('right');    }else if (cursors.up.isDown)    {        player.body.moveUp(200);         player.animations.play('up');    }else if (cursors.down.isDown)    {        player.body.moveDown(200);        player.animations.play('down');    }    else    {        player.animations.stop();            }     }

Although stripping tilemaps out has located where the problem lies, another one has sprung up. The sprite now appears to randomly stop on the screen asthough there are invisible boundries :(

 

http://eponaweb.com/test2.html

 

I've obviously broke it or not using it correctly. Anyone spot my mistake? Am I correct to stick to P2 for this style of game?

Link to post
Share on other sites

Here is the world boundary test I was using. One sprite, one background (just so you can see it moving around the world).

 

This works fine for me, how about you?

 

Note that I spawn the sprite within the world boundary to avoid it popping outside of the bounds.

 

You can drop this example into the examples repo, it uses assets readily found in there.

var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update });function preload() {    game.load.image('stars', 'assets/misc/starfield.jpg');    game.load.spritesheet('ship', 'assets/sprites/humstar.png', 32, 32);}var ship;var starfield;var cursors;function create() {    //  Our world size is 1600 x 1200 pixels    game.world.setBounds(0, 0, 1600, 1200);    //  Enable P2 and it will use the updated world size    game.physics.startSystem(Phaser.Physics.P2JS);    starfield = game.add.tileSprite(0, 0, 800, 600, 'stars');    starfield.fixedToCamera = true;	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');    //  Create our physics body. The 'true' parameter enables visual debugging.	game.physics.p2.enable(ship, true);    //  Alternatively create a circle for the ship instead (which more accurately matches its size)    // ship.body.setCircle(28);	game.camera.follow(ship);    cursors = game.input.keyboard.createCursorKeys();}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;    }}
Link to post
Share on other sites

Thanks for the reply. 

 

Re: spawning sprite, that works, I wasn't sure if it should work at a default of 0,0 or not, but set it 30,30 and spawns fine. Cheers.

 

Re: world boundary collision. Yep the above code works fine for me too, but it uses an image as the background. As soon as I replace the image with a tilemap, the boundary collision no longer works. See ship going off on the left-side of screen below.

 

tilesheet_ex.jpg

 

I have also replicated this issue in the Tilemap Gravity and Tilemap example scripts in the P2 section. There is a gap in the left side of the tiled boundary. If you jump the sprite into the gap, it just disappears as shown below;

 

tilemap_gravity.jpg

 

 

I would guess there is something missing for world boundary collision when using a tilemap in P2, but I just can't seem to find it. I have tried all of the P2 example scripts, chopped and changed things, but still no joy  :wacko:

 

Any further ideas?

 

 

BTW, have only been using Phaser for a week and I love it already. Massive kudos to everyone working on and contributing to it :)
Link to post
Share on other sites
  • 2 weeks later...

Yeah I put together this test for it the other day which shows how to get it working as expected:

var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });function preload() {    game.load.tilemap('map', 'assets/tilemaps/maps/collision_test.json', null, Phaser.Tilemap.TILED_JSON);    game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png');    game.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png');    game.load.image('tiles2', 'assets/tilemaps/tiles/tiles2.png');    game.load.image('ship', 'assets/sprites/thrust_ship2.png');}var ship;var map;var layer;var cursors;function create() {    game.physics.startSystem(Phaser.Physics.P2JS);    game.stage.backgroundColor = '#2d2d2d';    map = game.add.tilemap('map');    map.addTilesetImage('ground_1x1');    map.addTilesetImage('walls_1x2');    map.addTilesetImage('tiles2');        layer = map.createLayer('Tile Layer 1');    layer.resizeWorld();    //  Set the tiles for collision.    //  Do this BEFORE generating the p2 bodies below.    map.setCollisionBetween(1, 12);    //  Convert the tilemap layer into bodies. Only tiles that collide (see above) are created.    //  This call returns an array of body objects which you can perform addition actions on if    //  required. There is also a parameter to control optimising the map build.    game.physics.p2.convertTilemap(map, layer);    ship = game.add.sprite(200, 200, 'ship');    game.physics.p2.enable(ship);    game.camera.follow(ship);    //  By default the ship will collide with the World bounds,    //  however because you have changed the size of the world (via layer.resizeWorld) to match the tilemap    //  you need to rebuild the physics world boundary as well. The following    //  line does that. The first 4 parameters control if you need a boundary on the left, right, top and bottom of your world.    //  The final parameter (false) controls if the boundary should use its own collision group or not. In this case we don't require    //  that, so it's set to false. But if you had custom collision groups set-up then you would need this set to true.    game.physics.p2.setBoundsToWorld(true, true, true, true, false);    //  Even after the world boundary is set-up you can still toggle if the ship collides or not with this:    // ship.body.collideWorldBounds = false;    cursors = game.input.keyboard.createCursorKeys();}function update() {    if (cursors.left.isDown)    {        ship.body.rotateLeft(100);    }    else if (cursors.right.isDown)    {        ship.body.rotateRight(100);    }    else    {        ship.body.setZeroRotation();    }    if (cursors.up.isDown)    {        ship.body.thrust(400);    }    else if (cursors.down.isDown)    {        ship.body.reverse(400);    }}function render() {}
Link to post
Share on other sites

hey rich.. thx for that example.. this works as expected..  BUT if i want to use collisionGroups there seems to be something missing..

just setting the 5th parameter of setBoundsToWorld to true changes nothing..  my objects are not colliding with any bounds..

 

what am i missing?  

 

i just added collisiongroups to the example and defined two objects to be in this collision groups.. they collide with eachother but not with the bounds...

Link to post
Share on other sites

ok rich.. i figured it out after reading the examples again (which didn't help at all) and half an hour trial and error method..

 

what i came up with confuses me a LOT..

 

i do NOT need to set bounds to world.. (as long as i'm ok with the fact that my world has all 4 bounds..)   or update the bounds collision group (as it's done in the examples)

//game.physics.p2.setBoundsToWorld(true, true, true, true, true);//game.physics.p2.updateBoundsCollisionGroup();

i just had to define my collisiongroups (for players and enemies) AFTER i call  

somelayer.resizeWorld();

(also setBoundsToWorld() needs to be placed after the line above if i want it to work..)

 

 

:huh:

Link to post
Share on other sites
  • 2 months later...

hmm..  my post above is still accurate..  i definitely need to be careful where in my code i set the collision groups.. otherwise the bounds will NOT work..   i need to write the following lines in this order:

layerforeground = map.createLayer('foreground'); layerforeground.resizeWorld();  game.physics.p2.setBoundsToWorld();playerCG = game.physics.p2.createCollisionGroup();

if i create the playerGC before the line setBoundsToWorld .. nothing.. no bounds are set...

 

does this make sense?

Link to post
Share on other sites
  • 3 months later...

Hi..!

I have worldBoundCollision Problem it tried to exactly copy paste code of example of wolrdBoundCollision (http://examples.phaser.io/_site/view_full.html?d=p2%20physics&f=world+move.js&t=world%20move)

But it's not working please help me out

 

Here is my source code

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<!doctype html>
<html>
<head>
    <script src="phaser.min.js"></script>
   
 
    </head>
    <body>
 
<script type="text/javascript">
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('ball', 'assets/sprites/shinyball.png');
 
}
 
var ship;
var starfield;
var cursors;
 
function create() {
 
    game.world.setBounds(0, 0, 1600, 1200);
 
    game.physics.startSystem(Phaser.Physics.P2JS);
    game.physics.p2.defaultRestitution = 0.9;
 
    starfield = game.add.tileSprite(0, 0, 800, 600, 'stars');
    starfield.fixedToCamera = true;
 
    balls = game.add.group();
    balls.enableBody = true;
    balls.physicsBodyType = Phaser.Physics.P2JS;
 
    for (var i = 0; i < 50; i++)
    {
        var ball = balls.create(game.world.randomX, game.world.randomY, 'ball');
        ball.body.setCircle(16);
    }
 
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');
 
    //  Create our physics body - a 28px radius circle. Set the 'false' parameter below to 'true' to enable debugging
game.physics.p2.enable(ship, false);
    ship.body.setCircle(28);
 
game.camera.follow(ship);
 
    cursors = game.input.keyboard.createCursorKeys();
 
}
 
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() {
 
}
</script>
 
 
    </body>
</html>
Link to post
Share on other sites

HAVING problem with world bounds i exactly copy paste code  AS rich Mentaioned but the collision not works please help me out here is complete code

 

 

 

<!doctype html>
<html>
<head>
    <script src="phaser.min.js"></script>
   
 
    </head>
    <body>
 
<script>
 
var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update });
 
function preload() {
 
    game.load.image('stars', 'assets/misc/starfield.jpg');
    game.load.spritesheet('ship', 'assets/sprites/humstar.png', 32, 32);
 
}
 
var ship;
var starfield;
var cursors;
 
function create() {
 
    //  Our world size is 1600 x 1200 pixels
    game.world.setBounds(0, 0, 1600, 1200);
 
    //  Enable P2 and it will use the updated world size
    game.physics.startSystem(Phaser.Physics.P2JS);
 
    starfield = game.add.tileSprite(0, 0, 800, 600, 'stars');
    starfield.fixedToCamera = true;
 
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');
 
    //  Create our physics body. The 'true' parameter enables visual debugging.
game.physics.p2.enable(ship, true);
 
    //  Alternatively create a circle for the ship instead (which more accurately matches its size)
    // ship.body.setCircle(28);
 
game.camera.follow(ship);
 
    cursors = game.input.keyboard.createCursorKeys();
 
}
 
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;
    }
 
}
 
</script>
 
 
    </body>
</html>
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...