Add player debris

This commit is contained in:
Matt Low 2020-01-29 04:02:14 +04:00
parent f083a40682
commit 0d323a69bc
6 changed files with 113 additions and 5 deletions

View File

@ -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;

View File

@ -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
}

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<PositionComponent> positionMapper;
ComponentMapper<ModelComponent> modelMapper;
ComponentMapper<BulletComponent> bulletMapper;
ComponentMapper<DebrisComponent> 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();
}
}
}
}