Implement asteroids breaking apart
Rename createPlayerDebris -> createDebris to make it clear it's not only for the player entity. Add Constants.ASTEROID_SPAWN_COUNT Slow down asteroids, tweak sizing
This commit is contained in:
parent
d140959fdc
commit
3b1c075102
@ -15,5 +15,6 @@ public class Constants {
|
||||
public static final int HALF_HEIGHT = HEIGHT / 2;
|
||||
|
||||
public static final float ASTEROID_SPAWN_DELAY = 1f;
|
||||
public static final int ASTEROID_SPAWN_COUNT = 4;
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.me.asteroids;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.me.asteroids.components.AccelerationComponent;
|
||||
import com.me.asteroids.components.AsteroidComponent;
|
||||
@ -16,6 +17,8 @@ import com.me.asteroids.components.model.PolygonModel;
|
||||
import com.me.common.ecs.Engine;
|
||||
import com.me.common.ecs.Entity;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.me.asteroids.Constants.rand;
|
||||
|
||||
public class EntityFactory {
|
||||
@ -94,10 +97,10 @@ public class EntityFactory {
|
||||
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);
|
||||
public static Entity[] createDebris(Engine engine, Entity entity) {
|
||||
Vector2 playerVelocity = entity.getComponent(VelocityComponent.class).velocity;
|
||||
PositionComponent playerPosition = entity.getComponent(PositionComponent.class);
|
||||
LineModel[] models = getLineModels(entity.getComponent(ModelComponent.class).model);
|
||||
Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(5));
|
||||
|
||||
Entity[] entities = new Entity[models.length];
|
||||
@ -118,12 +121,12 @@ public class EntityFactory {
|
||||
.add(tmp2.set(playerVelocity).scl(0.75f)); // Maintain 75% of the player's velocity at impact
|
||||
velocity.angularVelocity = rand.nextFloat(-60, 60); // Make each piece spin at a different rate
|
||||
|
||||
Entity entity = createEntity(engine);
|
||||
entity.addComponent(position);
|
||||
entity.addComponent(velocity);
|
||||
entity.addComponent(model);
|
||||
entity.addComponent(new DebrisComponent());
|
||||
entities[i] = entity;
|
||||
Entity debris = createEntity(engine);
|
||||
debris.addComponent(position);
|
||||
debris.addComponent(velocity);
|
||||
debris.addComponent(model);
|
||||
debris.addComponent(new DebrisComponent());
|
||||
entities[i] = debris;
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
@ -170,11 +173,11 @@ public class EntityFactory {
|
||||
|
||||
ModelComponent model = new ModelComponent();
|
||||
model.model = new PolygonModel(Color.WHITE);
|
||||
int size = rand.nextInt(30, 60);
|
||||
int size = rand.nextInt(45, 75);
|
||||
model.model.setVertices(new AsteroidFactory()
|
||||
.setVertexCount(rand.nextInt(16, 24))
|
||||
.setVertexCount(32)
|
||||
.setSize(size)
|
||||
.setSizeVariation(size * 0.7f)
|
||||
.setSizeVariation(size * 0.5f)
|
||||
.sizeRelativeToLast()
|
||||
.generate());
|
||||
|
||||
@ -186,4 +189,57 @@ public class EntityFactory {
|
||||
return asteroid;
|
||||
}
|
||||
|
||||
private static float[] scaleAndRelativizeVertices(Vector2 position, float[] vertices, float scale) {
|
||||
float[] ret = new float[vertices.length];
|
||||
for (int j = 0, n = vertices.length; j < n; j += 2) {
|
||||
ret[j] = (vertices[j] - position.x) * scale;
|
||||
ret[j + 1] = (vertices[j + 1] - position.y) * scale;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Entity[] splitAsteroidIntoChunks(Engine engine, Entity asteroid, int chunkCount, float chunkScale) {
|
||||
Vector2 asteroidVelocity = asteroid.getComponent(VelocityComponent.class).velocity;
|
||||
Model asteroidModel = asteroid.getComponent(ModelComponent.class).model;
|
||||
Vector2 asteroidPosition = asteroidModel.getPosition();
|
||||
float[] scaledVertices = scaleAndRelativizeVertices(asteroidPosition, asteroidModel.getVertices(), chunkScale);
|
||||
|
||||
float angle = rand.nextFloat() * MathUtils.PI2;
|
||||
float angleStep = MathUtils.PI2 / chunkCount;
|
||||
Utils.setUnitVectorAngleRad(tmp, angle);
|
||||
|
||||
Entity[] entities = new Entity[chunkCount];
|
||||
for (int i = 0; i < chunkCount; i++) {
|
||||
Vector2 chunkPosition = tmp2.set(asteroidPosition).add(tmp.scl(25));
|
||||
|
||||
ModelComponent model = new ModelComponent();
|
||||
model.model = new PolygonModel(asteroidModel.getColor());
|
||||
model.model.setVertices(Arrays.copyOf(scaledVertices, scaledVertices.length));
|
||||
model.model.setPosition(chunkPosition);
|
||||
|
||||
PositionComponent position = new PositionComponent();
|
||||
position.position = new Vector2(chunkPosition);
|
||||
position.rotation = 90;
|
||||
|
||||
VelocityComponent velocity = new VelocityComponent();
|
||||
velocity.velocity = new Vector2(tmp).nor().rotate(rand.nextFloat(-45, 45)).scl(asteroidVelocity.len() * 1.10f);
|
||||
velocity.angularVelocity = rand.nextFloat(-30, 30);
|
||||
|
||||
AsteroidComponent asteroidComponent = new AsteroidComponent();
|
||||
asteroidComponent.generation = asteroid.getComponent(AsteroidComponent.class).generation + 1;
|
||||
|
||||
angle += angleStep;
|
||||
Utils.setUnitVectorAngleRad(tmp, angle);
|
||||
|
||||
Entity split = createEntity(engine);
|
||||
split.addComponent(model);
|
||||
split.addComponent(position);
|
||||
split.addComponent(velocity);
|
||||
split.addComponent(asteroidComponent);
|
||||
entities[i] = split;
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,5 +3,7 @@ package com.me.asteroids.components;
|
||||
import com.me.common.ecs.Component;
|
||||
|
||||
public class AsteroidComponent implements Component {
|
||||
// TODO: See PlayerComponent's TODO
|
||||
|
||||
public int generation;
|
||||
|
||||
}
|
||||
|
@ -101,12 +101,14 @@ public class GameScreen extends Screen implements Listener {
|
||||
ComponentMapper<ModelComponent> modelMapper;
|
||||
ComponentMapper<BulletComponent> bulletMapper;
|
||||
ComponentMapper<DebrisComponent> debrisMapper;
|
||||
ComponentMapper<AsteroidComponent> asteroidMapper;
|
||||
|
||||
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);
|
||||
this.asteroidMapper = engine.getComponentMapper(AsteroidComponent.class);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -127,7 +129,18 @@ public class GameScreen extends Screen implements Listener {
|
||||
// AABBs intersect but let's only consider it a hit if the bullet's position
|
||||
// is actually inside the asteroid
|
||||
event.getBullet().remove();
|
||||
int generation = asteroidMapper.get(event.getAsteroid()).generation;
|
||||
if (generation < 2) {
|
||||
for (Entity shard : EntityFactory.splitAsteroidIntoChunks(engine, event.getAsteroid(), 2, 2/3f)) {
|
||||
shard.activate();
|
||||
}
|
||||
} else {
|
||||
for (Entity debris : EntityFactory.createDebris(engine, event.getAsteroid())) {
|
||||
debris.activate();
|
||||
}
|
||||
}
|
||||
event.getAsteroid().remove();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +151,7 @@ public class GameScreen extends Screen implements Listener {
|
||||
|
||||
if (asteroid.contains(player.getVertices()) || player.contains(asteroid.getVertices())) {
|
||||
event.getPlayer().deactivate();
|
||||
for (Entity debris : EntityFactory.createPlayerDebris(engine, event.getPlayer())) {
|
||||
for (Entity debris : EntityFactory.createDebris(engine, event.getPlayer())) {
|
||||
debris.activate();
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public class AsteroidSpawningSystem extends BaseSystem {
|
||||
model.setPosition(position);
|
||||
|
||||
VelocityComponent velocityComponent = velocityMapper.get(asteroid);
|
||||
velocityComponent.velocity = new Vector2().setToRandomDirection().scl(rand.nextFloat(125, 175));
|
||||
velocityComponent.velocity = new Vector2().setToRandomDirection().scl(rand.nextFloat(75, 125));
|
||||
velocityComponent.angularVelocity = rand.nextFloat(-30, 30);
|
||||
|
||||
asteroid.activate();
|
||||
@ -83,7 +83,7 @@ public class AsteroidSpawningSystem extends BaseSystem {
|
||||
}
|
||||
}
|
||||
|
||||
if (asteroidCount++ < 6 && (asteroidSpawnDelay -= dt) <= 0) {
|
||||
if (asteroidCount++ < Constants.ASTEROID_SPAWN_COUNT && (asteroidSpawnDelay -= dt) <= 0) {
|
||||
spawnAsteroid();
|
||||
asteroidSpawnDelay = Constants.ASTEROID_SPAWN_DELAY;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user