Jump to content

It is possible to scale the polygon with P2 physics?


AlexArroyoDuque
 Share

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);

Link to comment
Share on other sites

  • 1 month later...

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.

Link to comment
Share on other sites

  • 4 months later...

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!

Link to comment
Share on other sites

  • 1 month later...

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);}
Link to comment
Share on other sites

  • 2 years later...

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']);

 

 

 

Link to comment
Share on other sites

  • 2 weeks later...

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.

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...