Java 如何在box2d中允许与距离关节碰撞
我有一系列粒子通过距离关节连接(使用Java 如何在box2d中允许与距离关节碰撞,java,box2d,Java,Box2d,我有一系列粒子通过距离关节连接(使用Processing和box2d)。粒子必须有一定的大小。我想把砖块扔到粒子链上,让砖块弹开。此时,砖块会从颗粒上反弹,但不会从接缝上反弹。我怎样才能让他们这样做。我的MCVE: import shiffman.box2d.*; import org.jbox2d.common.*; import org.jbox2d.dynamics.joints.*; import org.jbox2d.collision.shapes.*; import org.jbo
Processing
和box2d
)。粒子必须有一定的大小。我想把砖块扔到粒子链上,让砖块弹开。此时,砖块会从颗粒上反弹,但不会从接缝上反弹。我怎样才能让他们这样做。我的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();
}
}
导入shiffman.box2d.*;
导入org.jbox2d.common.*;
导入org.jbox2d.dynamics.joints.*;
导入org.jbox2d.collision.shapes.*;
导入org.jbox2d.collision.shapes.Shape;
导入org.jbox2d.dynamics.*;
导入org.jbox2d.dynamics.contacts.*;
导入org.jbox2d.particle.ParticleGroupDef;
导入org.jbox2d.particle.ParticleSystem;
导入org.jbox2d.particle.ParticleType;
导入org.jbox2d.particle.ParticleDef;
导入org.jbox2d.collision.shapes.CircleShape;
导入org.jbox2d.collision.shapes.PolygonShape;
导入org.jbox2d.common.Vec2;
导入org.jbox2d.dynamics.Body;
导入org.jbox2d.dynamics.BodyDef;
导入org.jbox2d.dynamics.BodyType;
//参考我们的box2d世界
box2d处理box2d;
粒子系统;
ParticleDef pd=新ParticleDef();
桥梁;
int粒子=10;//桥中粒子的数量
ParticleDef pdef=新ParticleDef();
//所有矩形的列表
阵列列表框;
无效设置(){
尺寸(10401060);
光滑的();
//初始化box2d物理并创建世界
box2d=新的box2d处理(此);
box2d.createWorld();
//使桥的总长度、点数、x起点位置
桥=新桥(宽度,颗粒,200);
//创建阵列列表
Box=新的ArrayList();
}
作废提款(){
背景(255);
//我们必须始终跨越时间!
box2d.step();
//单击鼠标时,添加新的长方体对象
如果(鼠标按下){
框p=新框(mouseX,mouseY);
加上(p);
}
//显示所有框
用于(框b:框){
b、 显示();
}
//离开屏幕的框,我们将删除它们(注意,它们必须从box2d世界和我们的列表中删除)
对于(int i=box.size()-1;i>=0;i--){
框b=框。获取(i);
if(b.done()){
盒子。移除(i);
}
}
bridge.display();
填充(0);
浮动移动_1=300;
对于(inti=0;i回答:
你不能,不完全是
关节不参与碰撞检测。因此身体不能从关节本身反弹
以一种在身体之间不留空隙的方式将身体和关节连接在一起似乎可以确保一个身体不能通过那一串身体。有时是这样,但不总是这样
其他信息:
以桥梁试验台为例。落在桥梁上的物体(作为试验的一部分)会从桥梁的主体部分反弹。它们通过旋转关节连接。但是如果我使用空格键发射“炸弹”在桥上,有足够的力,它通过组成桥的主体。即使我把桥的主体部分设置为子弹体,这种情况也会发生
这是一个“炸弹”通过大桥的快照特写:
桥的一部分被撞坏了,使得炸弹得以通过
距离关节可能比旋转关节更好。但是我不知道它会更好。你考虑过在你的粒子串中没有任何间隙吗?我相信这是实现你所描述的目的的一种方法。可能也是最简单的方法。也许可以用矩形多边形填充间隙,这些多边形足够窄,看起来像你想要的样子?是的。问题是,如果有足够的力,盒子就会从缝隙中逃逸出来。此外,最终粒子会排列成两条线,以正弦波的形式向下推动砖块,同一链条的粒子之间的拉伸也会产生缝隙,砖块穿过缝隙escape@LouisLangholtz你的意思是将多边形附加到关节上吗?我没有现在,BOX2D2.3.3.2连接体是可以连接到连接的。是不是在你使用的端口上那么明显?或者做的不同?我不太熟悉java版本的C++代码。