How to create 2D physics blob similar to the "Sushi Cat Game" using javascript physics engine?

775 views Asked by At

I am trying to create HTML5 game that similar to Sushi Cat game. I followed a similar tutorial from Emanuele Feronato's blog post and then came up with the structure like the picture A in this image, where the gray orbits are allowed to penetrate each other, and the red lines are distantConstraint.

But the problem is when the blob fell from a high place (or hitting corner), it becomes like in picture B.

I tried to use spring, different constraint force, smaller orbits, but they are not working properly.

My questions:

  1. What is the solution for this? Or where can I find the solution on the web?

  2. Is there any other js physics engine that has a specific feature to do this task?

3

There are 3 answers

3
Blindman67 On

Remove the symmetry

Just add some additional constraints to the points. The current symmetry of the shape means that round and folded in half are both valid and relaxed configurations.

Radial constraints.

Using one of the lines from the center to the outside as a referance, give each spoke an offset angle from that line.

Then each outside point will be moved as follows.

Get angle of ref line.

var ang = Math.atan2(refLine.p2.y - refLine.p1.y, refLine.p2.x - refLine.p1.x);

Then for each line move the end point towards its desired relative angle position.

// line is a spoke line with a property angle that is the angle from the
// reference line
var x = refLine.p1.x;  // get center point
var y = refLine.p2.y;
// get position relative to ref ang
line.x = Math.cos(line.angle + ang) * line.length + x;
line.y = Math.sin(line.angle + ang) * line.length + y;

Do that for each spoked line and apply it after you apply the line length constraints.

In referance to the image you gave the line from center to 12 o'clock is the reference line then the other spoked lines will have angles restrained as follows.

  • 1 o'clock is 30deg from ref
  • 2 o'clock is 60
  • 3 is 90 so on to 6 at 180deg

And the other direction

  • 11 o'clock is -30deg from ref
  • 10 o'clock is -60 and so on

You will be able to ignore the 6 o'clock line incase giving it a constraint makes the object want to roll to the right.

Only one

This now means that there is only one solution to the possible states rather than the many that you had.

0
baumschubser On

Constant Volume Joint may be what you are looking for. As its name suggests, it tries to maintain the volume it has upon creation despite impulses from outside, much like a water balloon. Here is a demo.

A working example with Box2dweb can be found here.

If you are interested in creating blobs with the creative application of more standard joints, this article comes to my mind.

0
schteppe On

The reason why the blob folds into itself, is because gravity will squish the blob points and the distance joints will find a new valid configuration. The job of the distance joint is just to maintain a given distance between two points, and it doesn't really do anything to prevent the self-folding.

An alternative approach is using Prismatic Joints (also called "slider joints"). With prismatic joints, the outer blob circles would slide along an axis radially from the center of the blob. To make the blob springy, you could add some kind of springs between the blob center and the circles. If the blob still self-folds, you could add limits to the prismatic joints, so the circles can only slide a certain distance.

This video demonstrates prismatic joints in a similar fashion, using the RUBE physics editor (using box2d under the hood).

A similar scene was made using p2.js physics engine, read more here. (direct link to demo). The part of the code that constructs the Prismatic Joints in the p2.js demo is:

// Constrain the capsule body to the center body.
// A prismatic constraint lets it move radially from the center body along one axis
var prismatic = new p2.PrismaticConstraint(wheelBody, body, {
  localAnchorA :  [0, 0],
  localAnchorB :  [0, 0],
  localAxisA :    [Math.cos(angle), Math.sin(angle)],
  disableRotationalLock: true, // Let the capsule rotate around its own axis
  collideConnected: true
});

In JavaScript, there are several ports of Box2D available which have the Prismatic Joint. p2.js has PrismaticConstraint.