@Override public void endContact(Contact contact) { Fixture fixA = contact.getFixtureA(); Fixture fixB = contact.getFixtureB(); if ((fixA.isSensor()) && (fixA.getUserData() != null)) { B2Controller b2c = (B2Controller) fixA.getUserData(); b2c.removeBody(fixB.getBody()); } else if ((fixB.isSensor()) && (fixB.getUserData() != null)) { B2Controller b2c = (B2Controller) fixB.getUserData(); b2c.removeBody(fixA.getBody()); } }
@Override public boolean reportFixture(Fixture fixture) { // if the hit fixture's body is the ground body // we ignore it if (fixture.getBody() == groundBody) return true; // if the hit point is inside the fixture of the body // we report it if (fixture.testPoint(testPoint.x, testPoint.y)) { hitBody = fixture.getBody(); return false; } else return true; }
private boolean checkSensor(Fixture sensor, Fixture other) { final SensorType type = (SensorType) sensor.getUserData(); final Object sensorData = sensor.getBody().getUserData(); final Object otherData = other.getBody().getUserData(); if (type == null) return false; switch (type) { case SCORE: if (otherData instanceof Player) { events.queueEvent(EventType.PLAYER_SCORED, sensorData); } return true; default: break; } return false; }
public void setDirtsActive(boolean dirtsActive) { this.dirtsActive = dirtsActive; for (Fixture fixture : dirts) { // fixture.setSensor(dirtsActive); fixture.getBody().setActive(dirtsActive); } }
@Override public boolean reportFixture(Fixture fixture) { // if the hit point is inside the fixture of the body // we report it if (fixture.testPoint(testPoint.x, testPoint.y)) { hitBody = fixture.getBody(); return false; } else return true; }
// called when two fixtures start to collide @Override public void beginContact(Contact c) { Fixture fa = c.getFixtureA(); Fixture fb = c.getFixtureB(); if (fa == null || fb == null) { return; } if (fa.getUserData() != null && fa.getUserData().equals("foot")) { numFootContacts++; } if (fb.getUserData() != null && fb.getUserData().equals("foot")) { numFootContacts++; } if (fa.getUserData() != null && fa.getUserData().equals("crystal")) { bodiesToRemove.add(fa.getBody()); } if (fb.getUserData() != null && fb.getUserData().equals("crystal")) { bodiesToRemove.add(fb.getBody()); } }
@Override public final float reportRayFixture( Fixture fixture, Vector2 point, Vector2 normal, float fraction) { if (!globalContactFilter(fixture) || !contactFilter(fixture) || (ignoreBody && fixture.getBody() == getBody())) return -1; // if (fixture.isSensor()) // return -1; mx[m_index] = point.x; my[m_index] = point.y; f[m_index] = fraction; return fraction; }
@Override public void update(float delta) { super.update(delta); xSpring.value = getBody().getPosition().x; if (state == BossState.WAITING) { xSpring.target = -50; getBody().setTransform(-50, 0, 0); if (GameScreen.i.getBossState() == GameScreen.BossState.FIGHTING) { GameScreen.i.getBoss().setName(""); state = BossState.COMING; GameScreen.i.setFreezeControls(true); timer = 0; } } else if (state == BossState.COMING) { float last = timer; timer += delta; if (timer > 3 && last <= 3) { xSpring.target = -15; GameScreen.i.getBoss().setName("HEY..."); } if (timer > 6 && last <= 6) { xSpring.target = -8; GameScreen.i.getBoss().setName("YOU"); GameScreen.i.getBoss().setHealth(1.05f); } if (timer > 7 && last <= 7) { xSpring.target = -4; GameScreen.i.getBoss().setName("YOU SHOULD"); } if (timer > 8 && last <= 8) { xSpring.target = 0; GameScreen.i.getBoss().setName("YOU SHOULD PROBABLY"); GameScreen.i.getBoss().setHealth(1.1f); } if (timer > 11 && last <= 11) { GameScreen.i.getBoss().setName("RRRUUUUUUUNNNNNN!!!!"); GameScreen.i.setFreezeControls(false); GameScreen.i.getPlayer().setSpeed(30); GameScreen.i.getBoss().setHealth(99999f); } if (timer > 11.5f) { state = BossState.RUN; } } else if (state == BossState.RUN) { float last = timer; timer += delta; xSpring.target += delta * 20; float limit = GameScreen.i.getPlayer().getBody().getPosition().x - 25f; if (xSpring.target < limit) { xSpring.target = limit + (float) Math.sin(timer * 2) * 2; } color = Palette.HIGHLIGHT .cpy() .lerp(Palette.HIGHLIGHT2, (float) (0.5f + Math.sin(timer * 6) * 0.5f)); if (MathUtils.floor(last) != MathUtils.floor(timer)) size.getVelocity().x = 100; if (MathUtils.floor(last + 0.5f) != MathUtils.floor(timer + 0.5f)) size.getVelocity().x = -100; float lastSub = subtimer; subtimer += delta; if (substate == SubState.ROOT) { if (subtimer > 2) { substate = Array.with( // SubState.BULLETS, SubState.SWEEP) .random(); subtimer = 0; } } else if (substate == SubState.BULLETS) { substate = SubState.ROOT; } else if (substate == SubState.SWEEP) { if (MathUtils.floor(lastSub * 0.8f) != MathUtils.floor(subtimer * 0.8f)) { // BossSweep sweep = new BossSweep(this, MathUtils.random(1, 3) * 2); // GameScreen.i.getEntities().add(sweep); } if (subtimer > 3) { subtimer = 0; substate = SubState.ROOT; } } } xSpring.update(delta); getBody().setLinearVelocity(xSpring.velocity, 0); if (GameScreen.i.getCollisionTracker().getCollisions().containsKey(fixture) && state == BossState.RUN) { for (Fixture fix : GameScreen.i.getCollisionTracker().getCollisions().get(fixture)) { Object ud = fix.getBody().getUserData(); if (ud instanceof Player) { ((Player) ud).damage(damageOnTouch, getBody().getPosition()); } } } }
@Override public void create() { float w = Gdx.graphics.getWidth(); float h = Gdx.graphics.getHeight(); Gdx.input.setInputProcessor(this); mB2Controllers = new Array<B2Controller>(); mCamPos = new Vector3(); mCurrentPos = new Vector3(); camera = new OrthographicCamera(100, 100 * h / w); camera.position.set(50, 50, 0); camera.zoom = 1.8f; camera.update(); loader = new RubeSceneLoader(); scene = loader.loadScene(Gdx.files.internal("data/palmcontrollers.json")); debugRender = new Box2DDebugRenderer(); batch = new SpriteBatch(); polygonBatch = new PolygonSpriteBatch(); textureMap = new HashMap<String, Texture>(); textureRegionMap = new HashMap<Texture, TextureRegion>(); createSpatialsFromRubeImages(scene); createPolySpatialsFromRubeFixtures(scene); mWorld = scene.getWorld(); // configure simulation settings mVelocityIter = scene.velocityIterations; mPositionIter = scene.positionIterations; if (scene.stepsPerSecond != 0) { mSecondsPerStep = 1f / scene.stepsPerSecond; } mWorld.setContactListener(this); // // example of custom property handling // Array<Body> bodies = scene.getBodies(); if ((bodies != null) && (bodies.size > 0)) { for (int i = 0; i < bodies.size; i++) { Body body = bodies.get(i); String gameInfo = (String) scene.getCustom(body, "GameInfo", null); if (gameInfo != null) { System.out.println("GameInfo custom property: " + gameInfo); } } } // Instantiate any controllers that are in the scene Array<Fixture> fixtures = scene.getFixtures(); if ((fixtures != null) && (fixtures.size > 0)) { for (int i = 0; i < fixtures.size; i++) { Fixture fixture = fixtures.get(i); int controllerType = (Integer) scene.getCustom(fixture, "ControllerType", 0); switch (controllerType) { case B2Controller.BUOYANCY_CONTROLLER: // only allow polygon buoyancy controllers for now.. if (fixture.getShape().getType() == Shape.Type.Polygon) { float bodyHeight = fixture.getBody().getPosition().y; // B2BuoyancyController b2c = new B2BuoyancyController(); // need to calculate the fluid surface height for the buoyancy controller PolygonShape shape = (PolygonShape) fixture.getShape(); shape.getVertex(0, mTmp); float maxHeight = mTmp.y + bodyHeight; // initialize the height, transforming to 'world' // coordinates // find the maxHeight for (int j = 1; j < shape.getVertexCount(); j++) { shape.getVertex(j, mTmp); maxHeight = Math.max(maxHeight, mTmp.y + bodyHeight); // transform to world coordinates } B2BuoyancyController b2c = new B2BuoyancyController( B2BuoyancyController.DEFAULT_SURFACE_NORMAL, // assume up (Vector2) scene.getCustom( fixture, "ControllerVelocity", B2BuoyancyController.DEFAULT_FLUID_VELOCITY), mWorld.getGravity(), maxHeight, fixture.getDensity(), (Float) scene.getCustom( fixture, "LinearDrag", B2BuoyancyController.DEFAULT_LINEAR_DRAG), (Float) scene.getCustom( fixture, "AngularDrag", B2BuoyancyController.DEFAULT_ANGULAR_DRAG)); fixture.setUserData(b2c); // reference back to the controller from the fixture (see // beginContact/endContact) mB2Controllers.add(b2c); // add it to the list so it can be stepped later } break; case B2Controller.GRAVITY_CONTROLLER: { B2GravityController b2c = new B2GravityController(); b2c = new B2GravityController( (Vector2) scene.getCustom( fixture, "ControllerVelocity", B2GravityController.DEFAULT_GRAVITY)); fixture.setUserData(b2c); mB2Controllers.add(b2c); } break; } } } scene.printStats(); scene.clear(); // no longer need any scene references }
/** * @param f - fixture that is affected * @return true if force was applied, false otherwise. */ private boolean ApplyToFixture(Fixture f) { float shapeDensity = mUseDensity ? f.getDensity() : mFluidDensity; // don't bother with buoyancy on sensors or fixtures with no density if (f.isSensor() || (shapeDensity == 0)) { return false; } Body body = f.getBody(); mAreac.set(Vector2.Zero); mMassc.set(Vector2.Zero); float area = 0; // Get shape for displacement area calculations Shape shape = f.getShape(); mSC.set(Vector2.Zero); float sarea; switch (shape.getType()) { case Circle: sarea = B2ShapeExtensions.ComputeSubmergedArea( (CircleShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Chain: sarea = B2ShapeExtensions.ComputeSubmergedArea( (ChainShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Edge: sarea = B2ShapeExtensions.ComputeSubmergedArea( (EdgeShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Polygon: sarea = B2ShapeExtensions.ComputeSubmergedArea( (PolygonShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; default: sarea = 0; break; } area += sarea; mAreac.x += sarea * mSC.x; mAreac.y += sarea * mSC.y; float mass = sarea * shapeDensity; mMassc.x += sarea * mSC.x * shapeDensity; mMassc.y += sarea * mSC.y * shapeDensity; mAreac.x /= area; mAreac.y /= area; mMassc.x /= mass; mMassc.y /= mass; if (area < Float.MIN_VALUE) { return false; } if (DEBUG_BUOYANCY) { // Run debug w/HCR to see the effects of different fluid densities / linear drag mFluidDensity = 2f; mLinearDrag = 5; mAngularDrag = 2; } // buoyancy force. mTmp.set(mGravity).scl(-mFluidDensity * area); body.applyForce(mTmp, mMassc, true); // multiply by -density to invert gravity // linear drag. mTmp.set( body.getLinearVelocityFromWorldPoint(mAreac).sub(mFluidVelocity).mul(-mLinearDrag * area)); body.applyForce(mTmp, mAreac, true); // angular drag. float bodyMass = body.getMass(); if (bodyMass < 1) // prevent a huge torque from being generated... { bodyMass = 1; } float torque = -body.getInertia() / bodyMass * area * body.getAngularVelocity() * mAngularDrag; body.applyTorque(torque, true); return true; }
/** * Method is called on every collision between two Box2D bodies. Behaviour of certain body * collisions are defined in this method. Collisions between bodies are defined and accessed by * means of bitwise or-ing their category bits. */ @Override public void beginContact(Contact c) { Fixture fa = c.getFixtureA(); Fixture fb = c.getFixtureB(); int collisionDefinition = fa.getFilterData().categoryBits | fb.getFilterData().categoryBits; switch (collisionDefinition) { // foot collides with floor case B2DVars.BIT_PLAYER_FOOT | B2DVars.BIT_BLOCKS: numJumps++; break; // Player collides with student, deal damage to player or kill enemy case B2DVars.BIT_PLAYER | B2DVars.BIT_STUDENT: System.out.println("hit!"); playerStudentCollisionCount++; Vector2 playerPosition, playerVelocity, studentPosition; Body player, student; if (fa.getUserData().equals("player")) { player = fa.getBody(); playerPosition = fa.getBody().getPosition(); playerVelocity = fa.getBody().getLinearVelocity(); student = fb.getBody(); studentPosition = fb.getBody().getPosition(); } else { player = fb.getBody(); playerPosition = fb.getBody().getPosition(); playerVelocity = fb.getBody().getLinearVelocity(); student = fa.getBody(); studentPosition = fa.getBody().getPosition(); } // Player hits enemy from above, 0.1 offset is to ensure player is significantly above enemy if (playerPosition.y - 0.1 > studentPosition.y && playerVelocity.y <= 0) { Game.ass.getAudio("kill").play(1.0f); bodiesToKill.add(student); player.setLinearVelocity(player.getLinearVelocity().x, 2f); } else { ((Player) player.getUserData()).damagePlayer(); Game.ass.getAudio("hit").play(1.0f); Vector2 point = new Vector2(playerPosition.x, playerPosition.y); if (playerPosition.x < studentPosition.x) { player.applyLinearImpulse(new Vector2(-30f, 0), point, true); } else { player.applyLinearImpulse(new Vector2(30f, 0), point, true); } } break; // player collides with coin case B2DVars.BIT_PLAYER | B2DVars.BIT_COINS: if (fa.getUserData().equals("coin")) { // delete coin bodiesToKill.add(fa.getBody()); Game.ass.getAudio("coin").play(1.0f); } else { bodiesToKill.add(fb.getBody()); Game.ass.getAudio("coin").play(1.0f); } break; // player collides with end of level region case B2DVars.BIT_PLAYER | B2DVars.BIT_END: if (fa.getUserData().equals("end")) { Player playerB = (Player) fb.getBody().getUserData(); if (playerB.getNumCoins() == playerB.getNumCoinsToCollect()) { playerB.setLevelCompleteBool(true); break; } playerB.setLevelCompleteBool(false); break; } else { Player playerA = (Player) fa.getBody().getUserData(); if (playerA.getNumCoins() == playerA.getNumCoinsToCollect()) { playerA.setLevelCompleteBool(true); break; } playerA.setLevelCompleteBool(false); break; } } }