We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I have a series of particles attached by a Distance Joint (using Processing with box2d). The particles have to be a certain size. I want to throw bricks at the chain of particles and for the bricks to bounce off. At the moment the bricks bounce off the particles but not the joint. How can I make them do so. My MCVE:
import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;
import org.jbox2d.particle.ParticleGroupDef;
import org.jbox2d.particle.ParticleSystem;
import org.jbox2d.particle.ParticleType;
import org.jbox2d.particle.ParticleDef;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
// A reference to our box2d world
Box2DProcessing box2d;
ParticleSystem particleSystem;
ParticleDef pd=new ParticleDef();
Bridge bridge;
int PARTICLES = 10; // the amount of particles in your bridge
ParticleDef pdef=new ParticleDef();
// A list for all of our rectangles
ArrayList<Box> boxes;
void setup() {
size(1040,1060);
smooth();
// Initialize box2d physics and create the world
box2d = new Box2DProcessing(this);
box2d.createWorld();
// Make the bridge total length,number of points,x start position
bridge = new Bridge(width,PARTICLES,200);
// Create ArrayLists
boxes = new ArrayList<Box>();
}
void draw() {
background(255);
// We must always step through time!
box2d.step();
// When the mouse is clicked, add a new Box object
if (mousePressed) {
Box p = new Box(mouseX,mouseY);
boxes.add(p);
}
// Display all the boxes
for (Box b: boxes) {
b.display();
}
// Boxes that leave the screen, we delete them (note they have to be deleted from both the box2d world and our list
for (int i = boxes.size()-1; i >= 0; i--) {
Box b = boxes.get(i);
if (b.done()) {
boxes.remove(i);
}
}
bridge.display();
fill(0);
float move_1=300;
for (int i=0; i<10; i++){
bridge.particles.get(i).body.setTransform(box2d.coordPixelsToWorld(move_1+10,i*20+70), 0);
}
}
// A rectangular box
class Box {
// We need to keep track of a Body and a width and height
Body body;
float w;
float h;
// Constructor
Box(float x, float y) {
w = random(4,16);
h = random(4,16);
// Add the box to the box2d world
makeBody(new Vec2(x,y),w,h);
}
// This function removes the particle from the box2d world
void killBody() {
box2d.destroyBody(body);
}
// Is the particle ready for deletion?
boolean done() {
// Let's find the screen position of the particle
Vec2 pos = box2d.getBodyPixelCoord(body);
// Is it off the bottom of the screen?
if (pos.y > height+w*h) {
killBody();
return true;
}
return false;
}
// Drawing the box
void display() {
// We look at each body and get its screen position
Vec2 pos = box2d.getBodyPixelCoord(body);
// Get its angle of rotation
float a = body.getAngle();
rectMode(CENTER);
pushMatrix();
translate(pos.x,pos.y);
rotate(-a);
fill(175);
stroke(0);
rect(0,0,w,h);
popMatrix();
}
// This function adds the rectangle to the box2d world
void makeBody(Vec2 center, float w_, float h_) {
// Define a polygon (this is what we use for a rectangle)
PolygonShape sd = new PolygonShape();
float box2dW = box2d.scalarPixelsToWorld(w_/2);
float box2dH = box2d.scalarPixelsToWorld(h_/2);
sd.setAsBox(box2dW, box2dH);
// Define a fixture
FixtureDef fd = new FixtureDef();
fd.shape = sd;
// Parameters that affect physics
fd.density = 1;
fd.friction = 300;
fd.restitution = 0.0;
// Define the body and make it from the shape
BodyDef bd = new BodyDef();
bd.type = BodyType.DYNAMIC;
bd.position.set(box2d.coordPixelsToWorld(center));
body = box2d.createBody(bd);
body.createFixture(fd);
// Give it some initial random velocity
body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5)));
}
}
// Series of Particles connected with distance joints
class Bridge {
// Bridge properties
float totalLength; // How long
int numPoints; // How many points in a line
int NewCurvepoints; // How many points in a curve for the top of the stomach
// Our chain is a list of particles
ArrayList<Particle> particles;
// Chain constructor
Bridge(float l, int n,int start) {
totalLength = l;
numPoints = n;
NewCurvepoints=n;
particles = new ArrayList();
float len = totalLength / numPoints;
// Add particles to the chain
for(int i=0; i < PARTICLES; i++) {
// Make a new particle
Particle p = null;
//x,y,radius,fixed
p = new Particle(start,i*len,7,3);
particles.add(p);
if (i > 0) {
DistanceJointDef djd = new DistanceJointDef();
Particle previous = particles.get(i-1);
djd.bodyA = previous.body;
djd.bodyB = p.body;
djd.length = box2d.scalarPixelsToWorld(len/40);
line(djd.bodyA.getPosition().x,djd.bodyA.getPosition().y,djd.bodyB.getPosition().x,djd.bodyB.getPosition().y);
djd.frequencyHz = 0;
djd.dampingRatio = 0;
DistanceJoint dj = (DistanceJoint) box2d.world.createJoint(djd);
}
}
}
// // Draw the bridge
void display() { for(int i=0; i < particles.size()-1; i++) {
Vec2 pos1 = box2d.getBodyPixelCoord(particles.get(i).body);
Vec2 pos2 = box2d.getBodyPixelCoord(particles.get(i+1).body);
stroke(0);
strokeWeight(2);
line(pos1.x,pos1.y,pos2.x,pos2.y);
}
for (Particle p: particles) {
p.display();
}
}
}
class Particle {
// We need to keep track of a Body and a radius
Body body;
float r;
color col;
Particle(float x, float y, float r_, int fixed) {
r = r_;
// Define a body
BodyDef bd = new BodyDef();
bd.fixedRotation=true;
if (fixed==1) bd.type = BodyType.STATIC;
else if (fixed==2) bd.type = BodyType.KINEMATIC;
else if (fixed==3) bd.type = BodyType.DYNAMIC;
// Set its position
bd.position = box2d.coordPixelsToWorld(x,y);
body = box2d.world.createBody(bd);
// Make the body's shape a circle
CircleShape cs = new CircleShape();
cs.m_radius = box2d.scalarPixelsToWorld(r);
FixtureDef fd = new FixtureDef();
fd.shape = cs;
// Parameters that affect physics
fd.density = 0;
fd.friction = 0;
fd.restitution = -90;
body.createFixture(fd);
col = color(175);
//determine how it moves
}
//
void display() {
// We look at each body and get its screen position
Vec2 pos = box2d.getBodyPixelCoord(body);
// Get its angle of rotation
float a = body.getAngle();
pushMatrix();
translate(pos.x,pos.y);
rotate(a);
fill(col);
stroke(0);
strokeWeight(1);
ellipse(0,0,r*2,r*2);
// Let's add a line so we can see the rotation
line(0,0,r,0);
popMatrix();
}
}