2017-04-25 10 views
0

Distance継手(Processingを使用し、box2dを使用)によって一連のパーティクルが接続されています。粒子は一定の大きさでなければならない。私は粒子の鎖にレンガを投げ、レンガは跳ね返りたい。現時点では、レンガはパーティクルからはね返りますが、ジョイントでは跳ね返りません。どうすればそうすることができますか?マイMCVE:box2dのDistanceジョイントとの衝突を可能にする方法

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


} 
+0

パーティクル列に隙間がないと思われましたか?私はそれがあなたが何を描いているのかを達成する方法だと信じています。あまりにも簡単かもしれません。 –

+0

あなたが望むように十分に細い長方形のポリゴンでギャップを埋めるのか? –

+0

はい。問題は、十分な力で、箱が隙間から脱出することです。また、最終的にパーティクルは、正弦波でレンガを下方向に押すために2つのストリングとして配置され、同じチェーンのパーティクル間のストレッチによってレンガが逃げる間隙が作られます。 –

答えて

0

回答:

あなたがすることはできません。ではない正確に。

関節は衝突検出に参加しません。したがって、身体は関節自身から跳ね返ることはできません。

身体の間に隙間を残さないような方法で身体を縛ることは、身体がその身体の列を通過できないようにするように思われます。それはときどきあります。しかしいつもではない。

追加情報:

例えば橋のテストベッドのケースを取ります。ブリッジの上に落ちるボディ(テストの一部として)は、ブリッジのボディピースから跳ね返ります。彼らは回転ジョイントで結ばれています。しかし、私が十分な力で橋に「爆弾」を打つためにスペースバーを使用すると、それは橋を構成する体を通過します。これは、私が橋のボディパーツを弾丸ボディに設定したとしても起こります。

ここの近くブリッジを介して取得し、「爆弾」のアップスナップショットです:

Bomb getting through in Bridge Test

ブリッジのセグメントは、爆弾は、それを介して取得できるようにする場所のノックアウトたどっているが。

距離ジョイントは、回転ジョイントよりも優れています。私はそれがしかしそれはわかりません。

関連する問題