package fi.hbp.angr.models; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.closeTo; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.not; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.physics.box2d.Body; import com.badlogic.gdx.physics.box2d.BodyDef; import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; import com.badlogic.gdx.physics.box2d.FixtureDef; import com.badlogic.gdx.physics.box2d.PolygonShape; import com.badlogic.gdx.physics.box2d.World; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.utils.GdxNativesLoader; import fi.hbp.angr.logic.DamageModel; import fi.hbp.angr.logic.GameState; import fi.hbp.angr.logic.ModelContactListener; import fi.hbp.angr.logic.TestDamageModelForce; public class ExplosionTest { World world; GameState gameState; ModelContactListener listener; protected class TestActor extends Actor implements Destructible { DamageModel dm; boolean destroyed = false; Body body; public TestActor(Body body, boolean enableDM) { this.body = body; body.setUserData(this); if (enableDM) { dm = new TestDamageModelForce(); dm.setHealth(1.0f); } } @Override public DamageModel getDatamageModel() { return dm; } @Override public void setDestroyed() { destroyed = true; } @Override public boolean isDestroyed() { return destroyed; } @Override public Body getBody() { return body; } } protected TestActor spawnBox(float x, float y, BodyType bt, boolean enDM) { PolygonShape ps = new PolygonShape(); ps.setAsBox(1.0f, 1.0f); FixtureDef fd = new FixtureDef(); fd.shape = ps; fd.density = 5.0f; BodyDef bd = new BodyDef(); bd.type = bt; bd.position.set(x, y); bd.active = true; Body body = world.createBody(bd); body.createFixture(fd); TestActor actor = new TestActor(body, enDM); return actor; } @BeforeClass public static void setUpBeforeClass() throws Exception { GdxNativesLoader.load(); } @AfterClass public static void tearDownAfterClass() throws Exception { } @Before public void setUp() throws Exception { world = new World(new Vector2(0.0f, -9.8f), true); gameState = new GameState(); gameState.addPoints(100, false); listener = new ModelContactListener(gameState); world.setContactListener(listener); /* Create a ground box */ BodyDef groundBodyDef = new BodyDef(); groundBodyDef.position.set(0.0f, -10.0f); Body groundBody = world.createBody(groundBodyDef); PolygonShape groundBox = new PolygonShape(); groundBox.setAsBox(50.0f, 10.0f); groundBody.createFixture(groundBox, 0.0f); } @After public void tearDown() throws Exception { } @Test public void testDoExplosion() { int steps = 15000; /* Spawn actors */ TestActor actor1 = spawnBox(1.0f, 1.1f, BodyType.DynamicBody, false); TestActor actor2 = spawnBox(3.0f, 1.1f, BodyType.DynamicBody, true); TestActor actor3 = spawnBox(6.0f, 1.1f, BodyType.DynamicBody, true); TestActor actor4 = spawnBox(45.0f, 1.1f, BodyType.DynamicBody, true); Explosion ex = new Explosion(actor1.getBody()); ex.doExplosion(); do { world.step(0.1f, 6, 2); } while (--steps > 0); /* Assert health status */ assertThat(((Destructible)actor2).getDatamageModel().getHealth(), lessThan(0.0f)); assertThat(((Destructible)actor2).isDestroyed(), equalTo(true)); assertThat(((Destructible)actor4).getDatamageModel().getHealth(), greaterThan(0.3f)); assertThat(((Destructible)actor4).isDestroyed(), not(equalTo(true))); /* Assert positions */ assertThat("Explosion source keeps its position", (double)actor1.getBody().getPosition().x, closeTo(1.0f, 0.01f)); assertThat("Fixture body close to explosion is moved by explosion force", (double)actor2.getBody().getPosition().x, not(closeTo(3.0f, 0.1f))); assertThat("Fixture body close to explosion is moved by explosion force", (double)actor3.getBody().getPosition().x, not(closeTo(6.0f, 0.1f))); assertThat("Bodies far away are still in original position", (double)actor4.getBody().getPosition().x, closeTo(45.0f, 0.01f)); } }