AlexArroyoDuque

It is possible to scale the polygon with P2 physics?

Recommended Posts

scale the sprite BEFORE you apply physics to it..    game.physics.p2.enable(spriteX);   reads the size at the time and creates the collision rectangle..  if you scale the sprite afterwards it's to late!  the rectangle is already created in an unscaled size.. 

 

btw.

you can rescale the rectangle at any time with..  spriteX.body.setRectangle(width, height);

Share this post


Link to post
Share on other sites
Thank you very much for your answers!

I have another question about this.

In the earlier version (1.1.6), it was possible to use setPolygon and thus collision size escalated correctly. Is possible to use something like setPolygon instead of taking data from a JSON with loadPolygon?

Share this post


Link to post
Share on other sites

In my game it looks like this:

var mySpriteScale = 0.5;var polygons = [ [0,0], [0,100], [200,100], [200,0]];// Here I scalefor(var i=0; i<polygons.length; i++){    polygons[i][0] *= mySpriteScale;    polygons[i][1] *= mySpriteScale;}mySprite.setPolygon(options, polygons);

It works well.

Share this post


Link to post
Share on other sites

I was curious how to do this as well. Here's a function I put together that works, though I'm not sure how performant it is. You can run this in create() to take an existing polygon you've added with game.load.physics() in preload() and copy it, scaled. Then, you use the 'newPhysicsKey' with game.body.loadPolygon():

function resizePolygon(originalPhysicsKey, newPhysicsKey, shapeKey, scale) {      newData = [];      $.each(game.cache._physics[originalPhysicsKey].data, function (key, values) {        $.each(values, function (key2, values2) {          shapeArray = [];          $.each(values2.shape, function (key3, values3) {            shapeArray.push(values3 * scale);          });          newData.push({shape: shapeArray});        });      });      var item = {};      item[shapeKey] = newData;      game.load.physics(newPhysicsKey, '', item);    }

This should provide some good leads on doing this in realtime, which I'll probably tackle next.

 

Cheers!

Share this post


Link to post
Share on other sites

I was curious how to do this as well. Here's a function I put together that works, though I'm not sure how performant it is. You can run this in create() to take an existing polygon you've added with game.load.physics() in preload() and copy it, scaled. Then, you use the 'newPhysicsKey' with game.body.loadPolygon():

function resizePolygon(originalPhysicsKey, newPhysicsKey, shapeKey, scale) {      newData = [];      $.each(game.cache._physics[originalPhysicsKey].data, function (key, values) {        $.each(values, function (key2, values2) {          shapeArray = [];          $.each(values2.shape, function (key3, values3) {            shapeArray.push(values3 * scale);          });          newData.push({shape: shapeArray});        });      });      var item = {};      item[shapeKey] = newData;      game.load.physics(newPhysicsKey, '', item);    }

This should provide some good leads on doing this in realtime, which I'll probably tackle next.

 

Cheers!

I couldn't use this code, the $ symbol wasn't recognized in my code.

 

I rewrote it a little bit and now is working fine.

function resizePolygon(originalPhysicsKey, newPhysicsKey, shapeKey, scale){var newData = [];var data = this.game.cache.getPhysicsData(originalPhysicsKey, shapeKey);for (var i = 0; i < data.length; i++) {var vertices = [];for (var j = 0; j < data[i].shape.length; j += 2) {vertices[j] = data[i].shape[j] * scale;vertices[j+1] = data[i].shape[j+1] * scale; }newData.push({shape : vertices});}var item = {};item[shapeKey] = newData;game.load.physics(newPhysicsKey, '', item);//debugPolygon(newPhysicsKey, shapeKey);}

Share this post


Link to post
Share on other sites

This is an old question (I ended up here through a Google search), but there's a new answer. Rich added the ability to add polygon data directly through the loadPolygon function in 2015 (set the first argument to null and the second argument is the polygon JSON data).

To apply the polygon while also scaling your sprite, you can iterate over the polygon shape data, apply the scale factor, and then apply the polygon to the already-scaled sprite using loadPolygon.

For example:

// Set your scale factor
var scale = someMathToDetermineScale();

// Load the polygon shapes file
game.load.json('physicsJSON', 'assets/physics/physics.json');

// Scale the physics data
// IMPORTANT - Do this one and only one time or the data will be scaled more than once
// because the JSON cache is persistent throughout the various states of your Phaser app.
var alreadyDidThisOnce = false; // pseudo-code, do this some better way
if (!alreadyDidThisOnce) {
	alreadyDidThisOnce = true;
	var physicsJSON = game.cache.getJSON('physicsJSON');
	for (var label in physicsJSON) {
		var shapes = physicsJSON[label];
		for (var i = 0, aryLen = shapes.length; i < aryLen; i++) {
			for (var c = 0, aryLen2 = shapes[i].shape.length; c < aryLen2; c++) {
				shapes[i].shape[c] = Math.round(shapes[i].shape[c] * scale, 1);
			}
		}
	}
}

// Add the scaled sprite
sprite = game.add.sprite(x, y, 'spriteName');
sprite.scale.setTo(scale, scale);

// Apply the scaled physics data
sprite.body.clearShapes();
sprite.body.loadPolygon(null, physicsJSON['polygonName']);

 

 

 

Share this post


Link to post
Share on other sites

I found quite similar solution, but with less code.

You just load your json file with "game.load.json("your_key","your_path");"

than set a global variable, that will be avalible for the whole programme. "var your-var;"

in the create method, save the json data to that variable "your-var = game.cache.getJSON("your_key");"

than here comes the function, i tried to do it with little bit of code, so i know that this function could be done better, but it has the main functionality:

*only works for json file made in physics_editor* for other types of json file, you have to rebiuld the function little bit.

function resize_polygon(character_key, scale){
    
    shape = vour-var[character_key];
    for (var i = 0; i < shape.length; i++) {
        console.log(shape["shape"]);
        for(var j = 0;j < shape["shape"].length;j++){
            shape["shape"][j] = shape["shape"][j]*scale;

        }


    }
}

when you want to call the function, just use name of the sprite polygon coords name and scale as parameters.

you can use this fucntion as many times as you want.

than when you want to apply the polygons on your sprite, call the function like this:

"your_sprite.body.loadPolygon(null,your-var["name of the sprite used in the json file"]);

Hope i helped you little bit.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.