@Override public void start() { super.start(); environment = new Continuous2D(1.0, config.getEnvironmentWidth(), config.getEnvironmentHeight()); drawProxy = new DrawProxy(environment.getWidth(), environment.getHeight()); environment.setObjectLocation(drawProxy, new Double2D()); physicsWorld = new World(new Vec2()); placementArea = new PlacementArea((float) environment.getWidth(), (float) environment.getHeight()); placementArea.setSeed(config.getSimulationSeed()); schedule.reset(); System.gc(); physicsWorld.setContactListener(contactListener); // Create ALL the objects createWalls(); createTargetArea(); robotFactory.placeInstances( placementArea.new ForType<>(), physicsWorld, config.getTargetAreaPlacement()); config.getResourceFactory().placeInstances(placementArea.new ForType<>(), physicsWorld); // Now actually add the objects that have been placed to the world and schedule for (PhysicalObject object : placementArea.getPlacedObjects()) { drawProxy.registerDrawable(object.getPortrayal()); schedule.scheduleRepeating(object); } schedule.scheduleRepeating( simState -> physicsWorld.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS)); }
/** * Creates a fixture and attach it to this body. Use this function if you need to set some fixture * parameters, like friction. Otherwise you can create the fixture directly from a shape. If the * density is non-zero, this function automatically updates the mass of the body. Contacts are not * created until the next time step. * * @param def the fixture definition. * @warning This function is locked during callbacks. */ public final Fixture createFixture(FixtureDef def) { assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return null; } // djm TODO from pool? Fixture fixture = new Fixture(); fixture.create(this, def); if ((m_flags & e_activeFlag) == e_activeFlag) { BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase; fixture.createProxy(broadPhase, m_xf); } fixture.m_next = m_fixtureList; m_fixtureList = fixture; ++m_fixtureCount; fixture.m_body = this; // Adjust mass properties if needed. if (fixture.m_density > 0.0f) { resetMassData(); } // Let the world know we have a new fixture. This will cause new contacts // to be created at the beginning of the next time step. m_world.m_flags |= World.NEW_FIXTURE; return fixture; }
/** * Notification that this body is being added to the world * * @param world The world this body is being added to */ void addToWorld(World world) { org.jbox2d.dynamics.World jboxWorld = world.getJBoxWorld(); jboxBody = jboxWorld.createBody(jboxBodyDef); shape.createInBody(this); if (!staticBody) { jboxBody.setMassFromShapes(); } else { jboxBody.m_type = org.jbox2d.dynamics.Body.e_staticType; } }
private Body initPhysicsBody(World world, float x, float y) { BodyDef bodyDef = new BodyDef(); bodyDef.type = BodyType.DYNAMIC; bodyDef.position = new Vec2(0, 0); Body body = world.createBody(bodyDef); PolygonShape shape = new PolygonShape(); Transform fx = new Transform(); fx.position.set(100f, 100f); shape.centroid(fx); shape.setAsBox( sprite.layer().width() * GameScreen.M_PER_PIXEL / 2, sprite.layer().height() * GameScreen.M_PER_PIXEL / 2); FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shape; fixtureDef.density = 0.4f; fixtureDef.friction = 0.1f; fixtureDef.restitution = 0f; body.createFixture(fixtureDef); body.setLinearDamping(0.2f); body.setTransform(new Vec2(x, y), 0f); // MassData md = body.getMassData(); // massD.center.set(2f, 0); body.setMassData(massD); return body; }
/** 创建多边形物体 */ private void createBody() { // 定义物体的形状是多边形形状 PolygonShape shape = new PolygonShape(); shape.set(vecs, edge); // 设置多边形物体的一些固定的物理属性 FixtureDef fd = new FixtureDef(); fd.shape = shape; // 固定设置参数 fd.density = 5.0f; // 密度 fd.friction = 0.3f; // 摩擦系数 fd.restitution = restitution; // 恢复系数 BodyDef bd = new BodyDef(); bd.position.set(x, y); bd.type = BodyType.DYNAMIC; bd.angle = angle; bd.allowSleep = true; bd.setAwake(true); // 根据bodyDef创建物体到世界中 body = world.createBody(bd); // 设置好物体的固定属性 body.createFixture(fd); }
public void update(GameContainer arg0, int arg1) throws SlickException { world.step(timeStep, velocityIterations, positionIterations); Fixture fa = cDetect.fa; Fixture fb = cDetect.fb; if (fa != null && fb != null) { player1.checkDeleteFixture(fa, fb); player2.checkDeleteFixture(fa, fb); asteroids.damageAsteroid(fa); asteroids.damageAsteroid(fb); } player1.batteryLeft = 100f; player1.calcForce(input, arg1, player2.player.getPosition()); player2.calcForceCPU( player1.player.getPosition(), asteroids.asteroids, new ArrayList<Vec2>(), arg1); player1.checkDeath(); player2.checkDeath(); if (player1.dead) { over = true; } if (player2.dead) { winner += 1; // In this case, winner will be used to determine score world.destroyBody(player2.player); player2 = new ShipCPU(player2Ship, world, tr, level); float jX = tr.width / tr.xscale; float jY = tr.height / tr.yscale; float max = jY / 2 - 15; float min = -jY / 2 + 15; float p2Y = (float) (Math.random() * (max - min) + min); player2.player.setTransform(new Vec2(jX / 2 - 15, p2Y), (float) Math.PI / 2); } if (input.isKeyDown(Input.KEY_ESCAPE)) { over = true; } }
/** * Set the mass properties to override the mass properties of the fixtures. Note that this changes * the center of mass position. Note that creating or destroying fixtures can also alter the mass. * This function has no effect if the body isn't dynamic. * * @param massData the mass properties. */ public final void setMassData(MassData massData) { // TODO_ERIN adjust linear velocity and torque to account for movement of center. assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return; } if (m_type != BodyType.DYNAMIC) { return; } m_invMass = 0.0f; m_I = 0.0f; m_invI = 0.0f; m_mass = massData.mass; if (m_mass <= 0.0f) { m_mass = 1f; } m_invMass = 1.0f / m_mass; if (massData.I > 0.0f && (m_flags & e_fixedRotationFlag) == 0) { m_I = massData.I - m_mass * Vec2.dot(massData.center, massData.center); assert (m_I > 0.0f); m_invI = 1.0f / m_I; } final Vec2 oldCenter = m_world.getPool().popVec2(); // Move center of mass. oldCenter.set(m_sweep.c); m_sweep.localCenter.set(massData.center); // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter); Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0); m_sweep.c.set(m_sweep.c0); // Update center of mass velocity. // m_linearVelocity += Cross(m_angularVelocity, m_sweep.c - oldCenter); final Vec2 temp = m_world.getPool().popVec2(); temp.set(m_sweep.c).subLocal(oldCenter); Vec2.crossToOut(m_angularVelocity, temp, temp); m_linearVelocity.addLocal(temp); m_world.getPool().pushVec2(2); }
private static void fractureCheck( final Fixture f1, final Fixture f2, final float iml, World w, Contact contact, int i) { materials.clear(); for (Material m = f1.m_material; m != null; m = m.m_fragments) { if (materials.contains(m)) { return; } if (m.m_rigidity < iml) { f1.m_body.m_fractureTransformUpdate = f2.m_body.m_fractureTransformUpdate = false; if (f1.m_body.m_massArea > Material.MINMASSDESCTRUCTION) { WorldManifold wm = new WorldManifold(); contact.getWorldManifold(wm); // vola sa iba raz w.addFracture(new Fracture(f1, f2, m, contact, iml, new Vec2(wm.points[i]))); } else if (f1.m_body.m_type != BodyType.DYNAMIC) { w.addFracture(new Fracture(f1, f2, m, null, 0, null)); } } materials.add(m); } }
/** * Set the position of the body's origin and rotation. This breaks any contacts and wakes the * other bodies. Manipulating a body's transform may cause non-physical behavior. * * @param position the world position of the body's local origin. * @param angle the world rotation in radians. */ public final void setTransform(Vec2 position, float angle) { assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return; } m_xf.R.set(angle); m_xf.position.set(position); // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter); Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0); m_sweep.c.set(m_sweep.c0); m_sweep.a0 = m_sweep.a = angle; BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase; for (Fixture f = m_fixtureList; f != null; f = f.m_next) { f.synchronize(broadPhase, m_xf, m_xf); } m_world.m_contactManager.findNewContacts(); }
public Planetoid(Sprite s, BodyDef bodyDef, World world, float mass, float forceFactor) { this.sprite = s; this.pBody = world.createBody(bodyDef); CircleShape circle = new CircleShape(); circle.m_radius = this.sprite.getWidth() / Globals.PHYS_RATIO / Globals.magicBoundRatio; FixtureDef fixDef = new FixtureDef(); fixDef.shape = circle; pBody.createFixture(fixDef); pBody.m_mass = mass; this.forceFactor = forceFactor; }
@Override Body initPhysicsBody(World world, float x, float y, float width, float height, float angle) { FixtureDef fixtureDef = new FixtureDef(); BodyDef bodyDef = new BodyDef(); bodyDef.type = BodyType.DYNAMIC; bodyDef.position = new Vec2(0, 0); Body body = world.createBody(bodyDef); CircleShape circleShape = new CircleShape(); circleShape.m_radius = RADIUS; fixtureDef.shape = circleShape; fixtureDef.density = 0.4f; fixtureDef.friction = 1f; fixtureDef.restitution = 0.0f; circleShape.m_p.set(0, 0); body.createFixture(fixtureDef); // body.setLinearDamping(0.2f); body.setTransform(new Vec2(x, y), angle); return body; }
public void initWorld() { Vec2 gravity = new Vec2(0.0f, 9.8f); world = new World(gravity); // ground FixtureDef groundFixtureDef = new FixtureDef(); PolygonShape groundShape = new PolygonShape(); groundShape.setAsBox(20f, 0.1f); groundFixtureDef.shape = groundShape; groundFixtureDef.density = 25.0f; groundFixtureDef.filter = new Filter(); groundFixtureDef.filter.categoryBits = 0x0001; BodyDef groundBodyDef = new BodyDef(); groundBodyDef.position = new Vec2(0.0f, 3f); groundBodyDef.angle = 0.0f; groundBodyDef.type = BodyType.STATIC; groundBody = world.createBody(groundBodyDef); groundFixture = groundBody.createFixture(groundFixtureDef); }
public void init(GameContainer container) throws SlickException { if (container instanceof AppGameContainer) { app = (AppGameContainer) container; } over = false; input = container.getInput(); Vec2 gravity = new Vec2(0.0f, 0.0f); world = new World(gravity, true); player1 = new ShipBuild(player1Ship, world, tr); player2 = new ShipCPU(player2Ship, world, tr, level); // thats the time in ms for shooting float jX = tr.width / tr.xscale; float jY = tr.height / tr.yscale; float max = jY / 2 - 15; float min = -jY / 2 + 15; asteroids = new AsteroidSpawner(world, tr); asteroids.genAsteroids(jX / 2 - 40, max - 25); float p1Y = (float) (Math.random() * (max - min) + min); float p2Y = (float) (Math.random() * (max - min) + min); player1.player.setTransform(new Vec2(-jX / 2 + 15, p1Y), 3 * (float) Math.PI / 2); player2.player.setTransform(new Vec2(jX / 2 - 15, p2Y), (float) Math.PI / 2); player1.inputForward = Input.KEY_W; // E; player1.inputLeft = Input.KEY_A; // W; player1.inputRight = Input.KEY_D; // R; player1.inputShoot = Input.KEY_SPACE; // A; player1.inputBackward = Input.KEY_S; cDetect = new CollideTest(player1, player2, world); world.setContactListener(cDetect); }
/** * Destroy a fixture. This removes the fixture from the broad-phase and destroys all contacts * associated with this fixture. This will automatically adjust the mass of the body if the body * is dynamic and the fixture has positive density. All fixtures attached to a body are implicitly * destroyed when the body is destroyed. * * @param fixture the fixture to be removed. * @warning This function is locked during callbacks. */ public final void destroyFixture(Fixture fixture) { assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return; } assert (fixture.m_body == this); // Remove the fixture from this body's singly linked list. assert (m_fixtureCount > 0); Fixture node = m_fixtureList; Fixture last = null; // java change boolean found = false; while (node != null) { if (node == fixture) { node = fixture.m_next; found = true; break; } last = node; node = node.m_next; } // You tried to remove a shape that is not attached to this body. assert (found); // java change, remove it from the list if (last == null) { m_fixtureList = fixture.m_next; } else { last.m_next = fixture.m_next; } // Destroy any contacts associated with the fixture. ContactEdge edge = m_contactList; while (edge != null) { Contact c = edge.contact; edge = edge.next; Fixture fixtureA = c.getFixtureA(); Fixture fixtureB = c.getFixtureB(); if (fixture == fixtureA || fixture == fixtureB) { // This destroys the contact and removes it from // this body's contact list. m_world.m_contactManager.destroy(c); } } if ((m_flags & e_activeFlag) == e_activeFlag) { assert (fixture.m_proxy != null); BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase; fixture.destroyProxy(broadPhase); } else { assert (fixture.m_proxy == null); } fixture.destroy(); fixture.m_body = null; fixture.m_next = null; fixture = null; --m_fixtureCount; // Reset the mass data. resetMassData(); }
public void step(float step_speed) { world.step(step_speed, 10, 10); }
/** * This resets the mass properties to the sum of the mass properties of the fixtures. This * normally does not need to be called unless you called setMassData to override the mass and you * later want to reset the mass. */ public final void resetMassData() { // Compute mass data from shapes. Each shape has its own density. m_mass = 0.0f; m_invMass = 0.0f; m_I = 0.0f; m_invI = 0.0f; m_sweep.localCenter.setZero(); // Static and kinematic bodies have zero mass. if (m_type == BodyType.STATIC || m_type == BodyType.KINEMATIC) { // m_sweep.c0 = m_sweep.c = m_xf.position; m_sweep.c.set(m_xf.position); m_sweep.c0.set(m_xf.position); return; } assert (m_type == BodyType.DYNAMIC); // Accumulate mass over all fixtures. final Vec2 center = m_world.getPool().popVec2(); center.setZero(); final Vec2 temp = m_world.getPool().popVec2(); final MassData massData = pmd; for (Fixture f = m_fixtureList; f != null; f = f.m_next) { if (f.m_density == 0.0f) { continue; } f.getMassData(massData); m_mass += massData.mass; // center += massData.mass * massData.center; temp.set(massData.center).mulLocal(massData.mass); center.addLocal(temp); m_I += massData.I; } // Compute center of mass. if (m_mass > 0.0f) { m_invMass = 1.0f / m_mass; center.mulLocal(m_invMass); } else { // Force all dynamic bodies to have a positive mass. m_mass = 1.0f; m_invMass = 1.0f; } if (m_I > 0.0f && (m_flags & e_fixedRotationFlag) == 0) { // Center the inertia about the center of mass. m_I -= m_mass * Vec2.dot(center, center); assert (m_I > 0.0f); m_invI = 1.0f / m_I; } else { m_I = 0.0f; m_invI = 0.0f; } Vec2 oldCenter = m_world.getPool().popVec2(); // Move center of mass. oldCenter.set(m_sweep.c); m_sweep.localCenter.set(center); // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter); Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0); m_sweep.c.set(m_sweep.c0); // Update center of mass velocity. // m_linearVelocity += Cross(m_angularVelocity, m_sweep.c - oldCenter); temp.set(m_sweep.c).subLocal(oldCenter); Vec2.crossToOut(m_angularVelocity, temp, temp); m_linearVelocity.addLocal(temp); m_world.getPool().pushVec2(3); }
/** * Notification that this body is being removed from the world * * @param world The world this body is being removed from */ void removeFromWorld(World world) { userData = null; org.jbox2d.dynamics.World jboxWorld = world.getJBoxWorld(); jboxWorld.destroyBody(jboxBody); }
private void addWorldContactListener(World world) { world.setContactListener( new ContactListener() { public void result(ContactResult point) { // System.out.println("Result contact"); } // @Override public void remove(ContactPoint point) { // System.out.println("remove contact"); } // @Override public void persist(ContactPoint point) { // System.out.println("persist contact"); } // @Override public void add(ContactPoint point) { // /* Shape shape1 = point.shape1; Shape shape2 = point.shape2; final Body body1 = shape1.getBody(); final Body body2 = shape2.getBody(); Object userData1 = body1.getUserData(); Object userData2 = body2.getUserData(); if (userData1 instanceof IPhysicsComponent && userData2 instanceof IPhysicsComponent) { // Check for ball/star collision IPhysicsComponent physObj1 = (IPhysicsComponent) userData1; IPhysicsComponent physObj2 = (IPhysicsComponent) userData2; // System.out.println("Collided: " + mt4jObj1 + " with " + mt4jObj2); if (physObj1 instanceof MTComponent && physObj2 instanceof MTComponent) { MTComponent comp1 = (MTComponent) physObj1; MTComponent comp2 = (MTComponent) physObj2; // Check if one of the components is the BALL MTComponent ball = isHit("ball", comp1, comp2); final MTComponent theBall = ball; // Check if one of the components is the GOAL MTComponent goal1 = isHit("goal1", comp1, comp2); MTComponent goal2 = isHit("goal2", comp1, comp2); // Check if a puck was involved MTComponent bluePuck = isHit("blue", comp1, comp2); MTComponent redPuck = isHit("red", comp1, comp2); // Check if a border was hit MTComponent border = null; if (comp1.getName() != null && comp1.getName().startsWith("border")) { border = comp1; } else if (comp2.getName() != null && comp2.getName().startsWith("border")) { border = comp2; } if (ball != null) { // CHECK IF BALL HIT A PADDLE if (enableSound && (bluePuck != null || redPuck != null)) { // System.out.println("PUCK HIT BALL!"); /* triggerSound(paddleHit); */ } // Check if BALL HIT A GOAL if (goal1 != null || goal2 != null) { // BALL HIT A GOAL if (goal1 != null) { System.out.println("GOAL FOR PLAYER 2!"); scorePlayer2++; } else if (goal2 != null) { System.out.println("GOAL FOR PLAYER 1!"); scorePlayer1++; } // Update scores updateScores(); // Play goal sound // triggerSound(goalHit); if (scorePlayer1 >= 15 || scorePlayer2 >= 15) { reset(); } else { // Reset ball if (theBall.getUserData("resetted") == null) { // To make sure that we call destroy only once theBall.setUserData("resetted", true); app.invokeLater( new Runnable() { public void run() { IPhysicsComponent a = (IPhysicsComponent) theBall; a.getBody() .setXForm( new Vec2( getMTApplication().width / 2f / scale, getMTApplication().height / 2f / scale), a.getBody().getAngle()); // a.getBody().setLinearVelocity(new Vec2(0,0)); a.getBody() .setLinearVelocity( new Vec2( ToolsMath.getRandom(-8, 8), ToolsMath.getRandom(-8, 8))); a.getBody().setAngularVelocity(0); theBall.setUserData("resetted", null); } }); } } } // If ball hit border Play sound if (enableSound && border != null) { /* triggerSound(wallHit); */ } } } } else { // if at lest one if the colliding bodies' userdata is not a physics shape } // */ } }); }
public void newBody(BodyDef bodyDef, World world) { this.pBody = world.createBody(bodyDef); }
/** * 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); } }
public void destroyBody() { world.destroyBody(getBody()); }
public void start() { Vec2 gravity = new Vec2(0, 0); World world = new World(gravity); BodyDef groundBodyDef = new BodyDef(); groundBodyDef.position.set(0, -25); Body groundBody = world.createBody(groundBodyDef); PolygonShape groundBox = new PolygonShape(); groundBox.setAsBox(900, 10); groundBody.createFixture(groundBox, 0); // Dynamic Body BodyDef bodyDef = new BodyDef(); bodyDef.type = BodyType.DYNAMIC; bodyDef.position.set(0, 0); Body body = world.createBody(bodyDef); PolygonShape dynamicBox = new PolygonShape(); dynamicBox.setAsBox(12, 12); FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = dynamicBox; fixtureDef.density = 1f; fixtureDef.friction = 0.3f; body.createFixture(fixtureDef); // Setup world float timeStep = 1.0f / 60.0f; int velocityIterations = 6; int positionIterations = 2; body.setLinearVelocity(new Vec2(15.0f, -15.0f)); body.setLinearDamping(2f); Vec2 f = body.getWorldVector(new Vec2(0.0f, -30.0f)); Vec2 p = body.getWorldPoint(body.getLocalCenter().add(new Vec2(-.2f, 0f))); // body.applyForce(new Vec2(-200,-200),new Vec2(-200,200)); try { Display.setDisplayMode(new DisplayMode(screen_width, screen_height)); Display.create(); } catch (LWJGLException e) { e.printStackTrace(); System.exit(0); } lastFPS = getTime(); // standardBall[0] = new Ball(400,200,0,12); // standardBall[1] = new Ball(100,210,2,12); // standardBall[0].addImpulse(-10,0); standardBall[0] = new Ball(200, 300, 0, 12); standardBall[1] = new Ball(415, 100, 2, 12); standardBall[0].addImpulse(10, -9.99f); standardBall[2] = new Ball(620, 270, 2, 12); standardBall[3] = new Ball(640, 290, 2, 12); standardBall[4] = new Ball(660, 310, 2, 12); standardBall[5] = new Ball(680, 330, 2, 12); standardBall[6] = new Ball(620, 230, 2, 12); standardBall[7] = new Ball(640, 210, 2, 12); standardBall[8] = new Ball(660, 190, 2, 12); standardBall[9] = new Ball(680, 170, 2, 12); standardBall[10] = new Ball(640, 250, 1, 12); standardBall[11] = new Ball(660, 230, 2, 12); standardBall[12] = new Ball(660, 270, 2, 12); standardBall[13] = new Ball(680, 290, 2, 12); standardBall[14] = new Ball(680, 210, 2, 12); standardBall[15] = new Ball(680, 250, 2, 12); standardTable = new Table(0, 0, 800, 400, 25, 15); // init OpenGL GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); GL11.glOrtho(0, 900, 0, 500, 1, -1); GL11.glMatrixMode(GL11.GL_MODELVIEW); while (!Display.isCloseRequested()) { int delta = getDelta(); world.step(timeStep, velocityIterations, positionIterations); Vec2 position = body.getPosition(); float angle = body.getAngle(); // System.out.printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle); // Clear the screen and depth buffer GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); standardTable.draw(); for (int i = 0; i < NUMBER_OF_BALLS; i++) { standardBall[i].draw(); standardBall[i].update(delta); } standardBall[0].setX((position.x * 20) + offset_x); standardBall[0].setY((position.y * 20) + offset_y); update(delta); Display.update(); Display.sync(60); } Display.destroy(); }