void playerControl(LudumDare26Game.ControlsState controlsState) { boolean doStop = !(controlsState.leftPressed || controlsState.rightPressed); final Body body = getBody(); float linearDamping = 0; if (doStop) { body.setAngularVelocity(0); // linearDamping = 10f; Vec2 linearVelocity = body.getLinearVelocity(); linearVelocity.x *= 0.9; // body.applyForce(new Vec2(v, 0), body.getPosition()); body.setLinearVelocity(linearVelocity); } else { Vec2 linearVelocity = body.getLinearVelocity(); final int dir = (controlsState.leftPressed ? -1 : 0) + (controlsState.rightPressed ? 1 : 0); float v = linearVelocity.x; v += dir * MOVE_ACC; v = Math.max(-MOVE_SPEED, Math.min(v, MOVE_SPEED)); linearVelocity.x = v; // body.applyForce(new Vec2(v, 0), body.getPosition()); body.setLinearVelocity(linearVelocity); // linearDamping = 1f; } body.setLinearDamping(linearDamping); }
// Constructor Box(PApplet parent, PBox2D box2d, float x, float y, float w_, float h_, boolean lock) { this.parent = parent; this.box2d = box2d; w = w_; h = h_; // Define and create the body BodyDef bd = new BodyDef(); bd.position.set(box2d.coordPixelsToWorld(new Vec2(x, y))); if (lock) bd.type = BodyType.STATIC; else bd.type = BodyType.DYNAMIC; body = box2d.createBody(bd); // Define the shape -- a (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 = 0.3f; fd.restitution = 0.5f; body.createFixture(fd); // Give it some initial random velocity body.setLinearVelocity(new Vec2(parent.random(-5, 5), parent.random(2, 5))); body.setAngularVelocity(parent.random(-5, 5)); }
/** * Set the angular velocity (the speed at which it rotates) * * @param vel The angular velocity to apply */ public void setAngularVelocity(float vel) { checkBody(); jboxBody.setAngularVelocity(vel); }
/** * 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); } }