@Override protected void bodyDefB4CreationCallback(BodyDef def) { super.bodyDefB4CreationCallback(def); // def.linearDamping = 0.15f; def.linearDamping = 0.25f; def.isBullet = true; def.angularDamping = 0.9f; // def.fixedRotation = true; }
/** * Create a new paddle. * * @param world The world the paddle will be added to. * @param y The height of the paddle (starts centered on the x) * @param mode The keys that will move this paddle */ public Paddle(World world, int y, MovementMode mode) { Mode = mode; // Respond to the keyboard KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); manager.addKeyEventDispatcher(this); // Add the physics body BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(world.Bounds.width / 2, y); bd.linearDamping = 0.0f; bd.angularDamping = 0.01f; FixtureDef fd = new FixtureDef(); fd.shape = new PolygonShape(); ((PolygonShape) fd.shape).setAsBox(SIZE.width / 2, SIZE.height / 2); fd.density = 0.1f; fd.friction = 0.0f; fd.restitution = 1.0f; j2dBody = world.j2dWorld.createBody(bd); j2dBody.createFixture(fd); j2dBody.setUserData(this); // Limit it to only x movement BodyDef gbd = new BodyDef(); gbd.type = BodyType.STATIC; bd.position.set(world.Bounds.width / 2, y); PrismaticJointDef pjd = new PrismaticJointDef(); pjd.collideConnected = true; pjd.initialize( j2dBody, world.j2dWorld.createBody(gbd), j2dBody.getWorldCenter(), new Vec2(1.0f, 0.0f)); world.j2dWorld.createJoint(pjd); }
/** * Rozbije objekt. Upravi objekt world tak, ze vymaze triesteny objekt a nahradi ho fragmentami na * zaklade nastaveneho materialu a clenskych premennych. * * @param dt casova dlzka framu */ public void smash(float dt) { if (contact == null) { // riesi sa staticky prvok, ktory ma priliz maly obsah b1.setType(BodyType.DYNAMIC); return; } World w = b1.m_world; Shape s = f1.m_shape; Polygon p = f1.m_polygon; if (p == null) { switch (s.m_type) { case POLYGON: PolygonShape ps = (PolygonShape) s; Vec2[] vertices = ps.m_vertices; p = new Polygon(); for (int i = 0; i < ps.m_count; ++i) { p.add(vertices[ps.m_count - i - 1]); } break; case CIRCLE: CircleShape cs = (CircleShape) s; p = new Polygon(); float radius = cs.m_radius; double u = Math.PI * 2 / CIRCLEVERTICES; radius = (float) Math.sqrt(u / Math.sin(u)) * radius; // upravim radius tak, aby bola zachovana velkost obsahu Vec2 center = cs.m_p; for (int i = 0; i < CIRCLEVERTICES; ++i) { double j = u * i; // uhol float sin = (float) Math.sin(j); float cos = (float) Math.cos(j); Vec2 v = new Vec2(sin, cos).mulLocal(radius).addLocal(center); p.add(v); } break; default: throw new RuntimeException("Dany typ tvaru nepodporuje stiepenie"); } } float mConst = f1.m_material.m_rigidity / normalImpulse; // sila v zavislosti na pevnosti telesa boolean fixA = f1 == contact.m_fixtureA; // true, ak f2 je v objekte contact ako m_fixtureA float oldAngularVelocity = fixA ? contact.m_angularVelocity_bodyA : contact.m_angularVelocity_bodyB; Vec2 oldLinearVelocity = fixA ? contact.m_linearVelocity_bodyA : contact.m_linearVelocity_bodyB; b1.setAngularVelocity( (b1.m_angularVelocity - oldAngularVelocity) * mConst + oldAngularVelocity); b1.setLinearVelocity( b1.m_linearVelocity.sub(oldLinearVelocity).mulLocal(mConst).addLocal(oldLinearVelocity)); if (!w.isFractured(f2) && b2.m_type == BodyType.DYNAMIC && !b2.m_fractureTransformUpdate) { // ak sa druhy objekt nerozbija, tak sa jej nahodia // povodne hodnoty (TREBA MODIFIKOVAT POHYB OBJEKTU, // KTORY SPOSOBUJE ROZPAD) oldAngularVelocity = !fixA ? contact.m_angularVelocity_bodyA : contact.m_angularVelocity_bodyB; oldLinearVelocity = !fixA ? contact.m_linearVelocity_bodyA : contact.m_linearVelocity_bodyB; b2.setAngularVelocity( (b2.m_angularVelocity - oldAngularVelocity) * mConst + oldAngularVelocity); b2.setLinearVelocity( b2.m_linearVelocity.sub(oldLinearVelocity).mulLocal(mConst).addLocal(oldLinearVelocity)); b2.setTransform( b2.m_xf0.p.add(b2.m_linearVelocity.mul(dt)), b2.m_xf0.q.getAngle()); // osetruje jbox2d od posuvania telesa pri rieseni kolizie b2.m_fractureTransformUpdate = true; } Vec2 localPoint = Transform.mulTrans(b1.m_xf, point); Vec2 b1Vec = b1.getLinearVelocityFromWorldPoint(point); Vec2 b2Vec = b2.getLinearVelocityFromWorldPoint(point); Vec2 localVector = b2Vec.subLocal(b1Vec); localVector.mulLocal(dt); Polygon[] fragment; try { fragment = m.split(p, localPoint, localVector, normalImpulse); // rodeli to } catch (RuntimeException ex) { return; } if (fragment.length == 1) { // nerozbilo to na ziadne fragmenty return; } // definuje tela fragmentov - tie maju vsetky rovnaku definiciu (preberaju parametre z povodneho // objektu) BodyDef bodyDef = new BodyDef(); bodyDef.position.set(b1.m_xf.p); // pozicia bodyDef.angle = b1.m_xf.q.getAngle(); // otocenie bodyDef.fixedRotation = b1.isFixedRotation(); bodyDef.angularDamping = b1.m_angularDamping; bodyDef.allowSleep = b1.isSleepingAllowed(); FixtureDef fd = new FixtureDef(); fd.friction = f1.m_friction; // trenie fd.restitution = f1.m_restitution; // odrazivost fd.isSensor = f1.m_isSensor; fd.density = f1.m_density; // odstrani fragmentacne predmety/cele teleso ArrayList<Fixture> fixtures = new ArrayList<>(); if (f1.m_polygon != null) { for (Fixture f = b1.m_fixtureList; f != null; f = f.m_next) { if (f.m_polygon == f1.m_polygon) { fixtures.add(f); } } } else { fixtures.add(f1); } for (Fixture f : fixtures) { b1.destroyFixture(f); } if (b1.m_fixtureCount == 0) { w.destroyBody(b1); } // prida fragmenty do simulacie MyList<Body> newbodies = new MyList<>(); for (Polygon pg : fragment) { // vytvori tela, prida fixtury, poriesi konvexnu dekompoziciu if (pg.isCorrect()) { if (pg instanceof Fragment) { Polygon[] convex = pg.convexDecomposition(); bodyDef.type = BodyType.DYNAMIC; for (Polygon pgx : convex) { Body f_body = w.createBody(bodyDef); pgx.flip(); PolygonShape ps = new PolygonShape(); ps.set(pgx.getArray(), pgx.size()); fd.shape = ps; fd.polygon = null; fd.material = f1.m_material.m_fragments; // rekurzivne stiepenie f_body.createFixture(fd); f_body.setAngularVelocity(b1.m_angularVelocity); f_body.setLinearVelocity(b1.getLinearVelocityFromLocalPoint(f_body.getLocalCenter())); newbodies.add(f_body); } } else { fd.material = f1.m_material.m_fragments; // rekurzivne stiepenie bodyDef.type = b1.getType(); Body f_body = w.createBody(bodyDef); PolygonFixture pf = new PolygonFixture(pg); f_body.createFixture(pf, fd); f_body.setLinearVelocity(b1.getLinearVelocityFromLocalPoint(f_body.getLocalCenter())); f_body.setAngularVelocity(b1.m_angularVelocity); newbodies.add(f_body); } } } // zavola sa funkcia z fraction listeneru (pokial je nadefinovany) FractureListener fl = w.getContactManager().m_fractureListener; if (fl != null) { fl.action(m, normalImpulse, newbodies); } }