diff --git a/core/src/com/me/asteroids/EntityFactory.java b/core/src/com/me/asteroids/EntityFactory.java index 0370706..5bccb23 100644 --- a/core/src/com/me/asteroids/EntityFactory.java +++ b/core/src/com/me/asteroids/EntityFactory.java @@ -5,11 +5,14 @@ import com.badlogic.gdx.math.Vector2; import com.me.asteroids.components.AccelerationComponent; import com.me.asteroids.components.AsteroidComponent; import com.me.asteroids.components.BulletComponent; +import com.me.asteroids.components.DebrisComponent; import com.me.asteroids.components.ModelComponent; import com.me.asteroids.components.PlayerComponent; -import com.me.asteroids.components.model.PolygonModel; import com.me.asteroids.components.PositionComponent; import com.me.asteroids.components.VelocityComponent; +import com.me.asteroids.components.model.LineModel; +import com.me.asteroids.components.model.Model; +import com.me.asteroids.components.model.PolygonModel; import com.me.common.ecs.Engine; import com.me.common.ecs.Entity; @@ -18,6 +21,9 @@ import static com.me.asteroids.Constants.rand; public class EntityFactory { private static final Vector2 tmp = new Vector2(); + private static final Vector2 tmp2 = new Vector2(); + private static final Vector2 tmpA = new Vector2(); + private static final Vector2 tmpB = new Vector2(); private static Entity createEntity(Engine engine) { Entity entity = engine.createEntity(); @@ -59,6 +65,68 @@ public class EntityFactory { return player; } + + private static LineModel[] getLineModels(Model playerModel) { + float[] vertices = playerModel.getVertices(); + Vector2 position = playerModel.getPosition(); + + LineModel[] models = new LineModel[(vertices.length / 2)]; + for (int i = 0, n = vertices.length; i < n; i += 2) { + int bIndex = i + 2 == n? 0 : i + 2; + + // tmpA, tmpB = points relative to 0 + tmpA.set(vertices[i] - position.x, vertices[i + 1] - position.y); + tmpB.set(vertices[bIndex] - position.x, vertices[bIndex + 1] - position.y); + + tmp.set(tmpB).sub(tmpA).scl(0.5f); // Cut line segment in half + tmp2.set(tmpA).add(tmp); // Find center of line segment + + tmpA.sub(tmp2); // make tmpA, tmpB relative to line center + tmpB.sub(tmp2); + + LineModel model = new LineModel(Color.WHITE); + model.setVertices(new float[] { + tmpA.x, tmpA.y, + tmpB.x, tmpB.y, + }); + model.setPosition(tmp2.add(position)); // Offset position to new line center + + models[i / 2] = model; + } + return models; + } + + public static Entity[] createPlayerDebris(Engine engine, Entity player) { + Vector2 playerVelocity = player.getComponent(VelocityComponent.class).velocity; + PositionComponent playerPosition = player.getComponent(PositionComponent.class); + LineModel[] models = getLineModels(player.getComponent(ModelComponent.class).model); + Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(10)); + + Entity[] entities = new Entity[models.length]; + for (int i = 0, n = models.length; i < n; i++) { + ModelComponent model = new ModelComponent(); + model.model = models[i]; + + PositionComponent position = new PositionComponent(); + position.position = model.model.getPosition(); + position.rotation = 90; + + VelocityComponent velocity = new VelocityComponent(); + velocity.velocity = new Vector2(models[i].getPosition()).sub(explosionCenter).nor().rotate(rand.nextFloat(-45,45)).scl(rand.nextFloat(75,100)); + velocity.velocity.add(tmp2.set(playerVelocity).scl(0.75f)); + velocity.angularVelocity = rand.nextFloat(-360, 360); + + Entity entity = createEntity(engine); + entity.addComponent(position); + entity.addComponent(velocity); + entity.addComponent(model); + entity.addComponent(new DebrisComponent()); + entities[i] = entity; + } + return entities; + } + + public static Entity createBullet(Engine engine, Entity player) { float[] modelVertices = player.getComponent(ModelComponent.class).model.getVertices(); float rotation = player.getComponent(PositionComponent.class).rotation; diff --git a/core/src/com/me/asteroids/components/BulletComponent.java b/core/src/com/me/asteroids/components/BulletComponent.java index b00e70f..bc28109 100644 --- a/core/src/com/me/asteroids/components/BulletComponent.java +++ b/core/src/com/me/asteroids/components/BulletComponent.java @@ -3,4 +3,5 @@ package com.me.asteroids.components; import com.me.common.ecs.Component; public class BulletComponent implements Component { + // TODO: See PlayerComponent's TODO } diff --git a/core/src/com/me/asteroids/components/DebrisComponent.java b/core/src/com/me/asteroids/components/DebrisComponent.java new file mode 100644 index 0000000..50744c5 --- /dev/null +++ b/core/src/com/me/asteroids/components/DebrisComponent.java @@ -0,0 +1,7 @@ +package com.me.asteroids.components; + +import com.me.common.ecs.Component; + +public class DebrisComponent implements Component { + // TODO: See PlayerComponent's TODO +} diff --git a/core/src/com/me/asteroids/components/model/LineModel.java b/core/src/com/me/asteroids/components/model/LineModel.java index 45ebc4d..391e436 100644 --- a/core/src/com/me/asteroids/components/model/LineModel.java +++ b/core/src/com/me/asteroids/components/model/LineModel.java @@ -92,7 +92,7 @@ public class LineModel implements Model { float maxX = vertices[0]; float maxY = vertices[1]; - for (int i = 0, n = vertices.length; i < n; i += 2) { + for (int i = 2, n = vertices.length; i < n; i += 2) { float x = vertices[i]; float y = vertices[i+1]; minX = x < minX ? x : minX; @@ -107,4 +107,5 @@ public class LineModel implements Model { aabb.height = maxY - minY; } + } diff --git a/core/src/com/me/asteroids/components/model/PolygonModel.java b/core/src/com/me/asteroids/components/model/PolygonModel.java index 4478228..f3c7ddb 100644 --- a/core/src/com/me/asteroids/components/model/PolygonModel.java +++ b/core/src/com/me/asteroids/components/model/PolygonModel.java @@ -88,4 +88,17 @@ public class PolygonModel implements Model { return model.contains(point); } + public boolean contains(float x, float y) { + return model.contains(x, y); + } + + public boolean contains(float[] vertices) { + for (int i = 0, n = vertices.length; i < n; i += 2) { + if (model.contains(vertices[i], vertices[i + 1])) { + return true; + } + } + return false; + } + } diff --git a/core/src/com/me/asteroids/screens/GameScreen.java b/core/src/com/me/asteroids/screens/GameScreen.java index 0fdeeef..b8f1842 100644 --- a/core/src/com/me/asteroids/screens/GameScreen.java +++ b/core/src/com/me/asteroids/screens/GameScreen.java @@ -11,12 +11,14 @@ import com.me.asteroids.Graphics; import com.me.asteroids.components.AccelerationComponent; import com.me.asteroids.components.AsteroidComponent; import com.me.asteroids.components.BulletComponent; +import com.me.asteroids.components.DebrisComponent; import com.me.asteroids.components.ModelComponent; import com.me.asteroids.components.PlayerComponent; -import com.me.asteroids.components.model.PolygonModel; import com.me.asteroids.components.PositionComponent; import com.me.asteroids.components.VelocityComponent; +import com.me.asteroids.components.model.PolygonModel; import com.me.asteroids.events.BulletAsteroidCollisionEvent; +import com.me.asteroids.events.PlayerASteroidCollisionEvent; import com.me.asteroids.events.ScreenWrapEvent; import com.me.asteroids.systems.AsteroidSpawningSystem; import com.me.asteroids.systems.CollisionSystem; @@ -55,6 +57,7 @@ public class GameScreen extends Screen implements Listener { engine.registerComponentClass(PlayerComponent.class); engine.registerComponentClass(BulletComponent.class); engine.registerComponentClass(AsteroidComponent.class); + engine.registerComponentClass(DebrisComponent.class); engine.registerComponentClass(PositionComponent.class); engine.registerComponentClass(VelocityComponent.class); engine.registerComponentClass(AccelerationComponent.class); @@ -97,18 +100,20 @@ public class GameScreen extends Screen implements Listener { ComponentMapper positionMapper; ComponentMapper modelMapper; ComponentMapper bulletMapper; + ComponentMapper debrisMapper; EventListener(Engine engine) { this.positionMapper = engine.getComponentMapper(PositionComponent.class); this.modelMapper = engine.getComponentMapper(ModelComponent.class); this.bulletMapper = engine.getComponentMapper(BulletComponent.class); + this.debrisMapper = engine.getComponentMapper(DebrisComponent.class); } @EventHandler public void onScreenWrap(ScreenWrapEvent event) { - if (bulletMapper.has(event.entity)) { + if (bulletMapper.has(event.entity) || debrisMapper.has(event.entity)) { // Remove bullets when they leave the screen - //event.setCancelled(true); + event.setCancelled(true); event.entity.remove(); } } @@ -126,6 +131,19 @@ public class GameScreen extends Screen implements Listener { } } + @EventHandler + public void onPlayerAsteroidCollision(PlayerASteroidCollisionEvent event) { + PolygonModel asteroid = (PolygonModel) modelMapper.get(event.getAsteroid()).model; + PolygonModel player = (PolygonModel) modelMapper.get(event.getPlayer()).model; + + if (asteroid.contains(player.getVertices()) || player.contains(asteroid.getVertices())) { + event.getPlayer().deactivate(); + for (Entity debris : EntityFactory.createPlayerDebris(engine, event.getPlayer())) { + debris.activate(); + } + } + } + }