paulo

Destructible terrain + physics (walking on holes)

Recommended Posts

Hello,

I'm trying to implement the code from this tutorial in a game I'm making. Actually I can make the holes on the texture using bitmapData. This is how I'm doing:

 

this.bmd = game.make.bitmapData(360, 150);
this.bmd.copy('ground'); //ground = image key

//Makes two "holes"
this.bmd.blendDestinationOut();
this.bmd.circle(50, 10, 20, 'rgba(0, 0, 0, 255');
this.bmd.circle(70, 10, 20, 'rgba(0, 0, 0, 255');
this.bmd.blendReset();
this.bmd.update();

this.ground = this.add.sprite(0, 630, this.bmd);
this.game.physics.arcade.enable(this.ground);
this.ground.body.allowGravity = false;
this.ground.body.immovable = true;

However, when I move my player, it walks like if there's no hole on the ground:

DoCh-uGdQeesjsFAf7fb6g.png

 

How can I fix this?

 

Share this post


Link to post
Share on other sites

The physics body is just a simple rectangle and it's not affected by any changes to the texture.

If you can keep track of the leftmost, bottom, and rightmost edges of the holes, then you can use three dummy sprites for the physics.

Share this post


Link to post
Share on other sites

You have to create your own collision detection for this. You need 1 point minimum and just check if a pixel exists in the location of the point, if it does stop the sprite, otherwise let gravity take control.

Share this post


Link to post
Share on other sites

If you have a static terrain you can do something like this:


The code is not very clean unfortunately, but it works. The idea is to create a physical path along the edge of the map using p2 physics and A path building algorithm (marching squares). The original source code for the algorithm. The tank does not really have the correct turret attached,  but the bullet still fire. The downside is this is expensive (performance).

A general example :

 

Share this post


Link to post
Share on other sites

Here is the optimized example:

You can set the edgeDistance for each shape to a lower number, so if you have simple shapes (simple rectangular platforms etc) you can dramatically reduce the amount of p2 bodies, again consider performance carefully, this is still expensive...

Share this post


Link to post
Share on other sites

@samid737 it's really optimized! so faster.

 

But there is a problem. When making some holes, some parts of the images get distorced/moved a bit. Look:

Normal:

_kF_1ZJ0REWhKqT6mGLOXA.png

 

With three holes:

sOdhTfe1SNWSPbcAomwBbA.png

 

This is a real problem in the game I want to create.

Do you know how to fix it?

Share this post


Link to post
Share on other sites

@paulo thats still A limitation, it is not really optimized for curvature. you can try to increase the edgeDistance and use linear interpolation:

var px = game.math.linearInterpolation(points.x,i)
var py = game.math.linearInterpolation(points.y,i)

 You can also try switching to capsules instead of lines in the buildPhysicsContour:

var points={'x':[],'y':[]};//empty data set(used in interpolation)
var edgeDistance=0.03;//interpolation accuracy lower is less accurate
var edgeSize=3;
var source=null; 

//.......

function buildPhysicsContour(element,index,polygon,source,originalsprite,edgeSize){
    if(index<polygon.length){
        point2=index<polygon.length-1?polygon[index+1]:polygon[0];
        point1=element;
        distanceToNext=magnitude(point2[0],point1[0],point2[1],point1[1]);
        angleRadians = Math.atan2(point2[1] - point1[1], point2[0] - point1[0]);
        line=game.add.sprite(point1[0]+originalsprite.x,point1[1]+originalsprite.y);
        game.physics.p2.enable(line,true);
        line.body.static=true;
        line.body.clearShapes();
        line.body.addCapsule(distanceToNext,edgeSize,distanceToNext/2);
        line.body.rotation=angleRadians;
        source.contour_group.add(line);
    }
}

You can provide any 2d array --> [[x1,y1],[x2,y2] ]to the buildContour function, so another option would be to provide the shape data manually:

polygon = [[100,100],[[300,100],[300,200],[300,100]] ; //clockwise or anti clockwise

// 0  ------> 1
// ∧          |
// |          ∨
// 3 <------  2

 

Share this post


Link to post
Share on other sites

@samid737  Soooo much better than the others, but it crashes when destroying the last part of a shape. Try destroying the bear for example.

 

Edit: It looks that this problem is happening even with the first examples you posted here.

Share this post


Link to post
Share on other sites

 That is how the algorithm currently works, it will start at one point and draw one closed surface.. Completely forgot that you can also use this for polygon building, Phaser has A built in addPolygon function:

Just to demonstrate, its not really stable (collisions work in v2.8.1 +), if you try to eat the left ear and then right then 5/10 times it will fail to eat.... Probably some fault in the way I set up the bitmapData.. Maybe you can work something out. I'l see if I can improve the example..

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.