Add constructors to Components, useful for more terse entity creation

This commit is contained in:
Matt Low 2020-02-01 17:04:06 +04:00
parent 69d5caf24d
commit 749e378a03
8 changed files with 239 additions and 83 deletions

View File

@ -21,6 +21,10 @@ import com.me.common.ecs.Entity;
import java.util.Arrays; import java.util.Arrays;
import static com.me.asteroids.Components.ASTEROID;
import static com.me.asteroids.Components.MODEL;
import static com.me.asteroids.Components.POSITION;
import static com.me.asteroids.Components.VELOCITY;
import static com.me.asteroids.Constants.rand; import static com.me.asteroids.Constants.rand;
public class EntityFactory { public class EntityFactory {
@ -31,6 +35,7 @@ public class EntityFactory {
private static final Vector2 tmpB = new Vector2(); private static final Vector2 tmpB = new Vector2();
private static final ColliderComponent COLLIDER = new ColliderComponent(); private static final ColliderComponent COLLIDER = new ColliderComponent();
private static final DebrisComponent DEBRIS = new DebrisComponent();
private static Entity createEntity(Engine engine) { private static Entity createEntity(Engine engine) {
Entity entity = engine.createEntity(); Entity entity = engine.createEntity();
@ -41,17 +46,10 @@ public class EntityFactory {
} }
public static Entity createPlayer(Engine engine) { public static Entity createPlayer(Engine engine) {
PositionComponent position = new PositionComponent(); VelocityComponent velocity = new VelocityComponent(0f, 0f, 0f, 10f);
position.position = new Vector2(Constants.HALF_WIDTH, Constants.HALF_HEIGHT);
position.rotation = 90;
VelocityComponent velocity = new VelocityComponent(); ModelComponent playerModel = new ModelComponent(new PolygonModel(Color.WHITE));
velocity.velocity = new Vector2(0f, 0f); playerModel.setVertices(new float[]{
velocity.maxVelocity = 10f;
ModelComponent model = new ModelComponent();
model.model = new PolygonModel(Color.WHITE);
model.model.setVertices(new float[]{
0f, 0.5f, // tip 0f, 0.5f, // tip
-5/16f, -0.5f, // bottom left -5/16f, -0.5f, // bottom left
-1/8f, -5/16f, // indent -1/8f, -5/16f, // indent
@ -59,34 +57,27 @@ public class EntityFactory {
5/16f, -0.5f, // bottom right 5/16f, -0.5f, // bottom right
}); });
AccelerationComponent accel = new AccelerationComponent(); ModelComponent afterburnerModel = new ModelComponent(new LineModel(Color.BLUE));
accel.acceleration = new Vector2(0, 1f); afterburnerModel.setVertices(new float[]{
ModelComponent afterBurnerModel = new ModelComponent();
afterBurnerModel.model = new LineModel(Color.BLUE);
afterBurnerModel.model.setVertices(new float[] {
-2/16f, -5/16f, -2/16f, -5/16f,
0f, -0.8f, 0f, -0.8f,
2/16f, -5/16f 2/16f, -5/16f
}); });
PositionComponent afterBurnerPosition = new PositionComponent();
afterBurnerPosition.position = new Vector2(Constants.HALF_WIDTH, Constants.HALF_HEIGHT);
afterBurnerPosition.rotation = 90;
Entity player = createEntity(engine); Entity player = createEntity(engine);
Entity afterBurner = createEntity(engine); Entity afterBurner = createEntity(engine);
afterBurner.addComponent(afterBurnerPosition);
afterBurner.addComponent(velocity);
afterBurner.addComponent(afterBurnerModel);
player.addComponent(position); player.addComponent(new PositionComponent(Constants.HALF_WIDTH, Constants.HALF_HEIGHT, 90));
player.addComponent(velocity); player.addComponent(velocity);
player.addComponent(model); player.addComponent(playerModel);
player.addComponent(accel); player.addComponent(new AccelerationComponent(0f, 1f));
player.addComponent(COLLIDER); player.addComponent(COLLIDER);
player.addComponent(new PlayerComponent(afterBurner)); player.addComponent(new PlayerComponent(afterBurner));
afterBurner.addComponent(new PositionComponent(Constants.HALF_WIDTH, Constants.HALF_HEIGHT, 90));
afterBurner.addComponent(velocity);
afterBurner.addComponent(afterburnerModel);
return player; return player;
} }
@ -120,35 +111,31 @@ public class EntityFactory {
} }
public static Entity[] createDebris(Engine engine, Entity entity) { public static Entity[] createDebris(Engine engine, Entity entity) {
Vector2 playerVelocity = entity.getComponent(VelocityComponent.class).velocity; Vector2 playerVelocity = VELOCITY.get(entity).velocity;
PositionComponent playerPosition = entity.getComponent(PositionComponent.class); PositionComponent playerPosition = POSITION.get(entity);
LineModel[] models = getLineModels(entity.getComponent(ModelComponent.class).model); LineModel[] models = getLineModels(MODEL.get(entity).model);
Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(0.125f)); Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(0.125f));
Entity[] entities = new Entity[models.length]; Entity[] entities = new Entity[models.length];
for (int i = 0, n = models.length; i < n; i++) { for (int i = 0, n = models.length; i < n; i++) {
ModelComponent model = new ModelComponent(); ModelComponent model = new ModelComponent(models[i]);
model.model = models[i];
PositionComponent position = new PositionComponent();
position.position = new Vector2(model.model.getPosition());
position.rotation = 90;
VelocityComponent velocity = new VelocityComponent(); VelocityComponent velocity = new VelocityComponent();
velocity.velocity = new Vector2(models[i].getPosition()) velocity.set(new Vector2(models[i].getPosition())
.sub(explosionCenter) .sub(explosionCenter)
.nor() // Direction from explosion center to center of piece .nor() // Direction from explosion center to center of piece
.rotate(rand.nextFloat(-15, 15)) // Slightly alter the direction each piece flies off in .rotate(rand.nextFloat(-15, 15)) // Slightly alter the direction each piece flies off in
.scl(rand.nextFloat(2f, 2.5f)) // Give each piece a slightly different speed .scl(rand.nextFloat(2f, 2.5f)) // Give each piece a slightly different speed
.add(tmp2.set(playerVelocity).scl(0.75f)); // Maintain 75% of the player's velocity at impact .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 velocity.angularVelocity = rand.nextFloat(-60, 60); // Make each piece spin at a different rate
Entity debris = createEntity(engine); Entity debris = createEntity(engine);
debris.addComponent(position); debris.addComponent(new PositionComponent(new Vector2(model.getPosition()), 90));
debris.addComponent(velocity); debris.addComponent(velocity);
debris.addComponent(model); debris.addComponent(model);
debris.addComponent(DEBRIS);
debris.addComponent(new DecayComponent(rand.nextFloat(0.5f, 2.5f))); debris.addComponent(new DecayComponent(rand.nextFloat(0.5f, 2.5f)));
debris.addComponent(new DebrisComponent());
entities[i] = debris; entities[i] = debris;
} }
return entities; return entities;
@ -159,30 +146,22 @@ public class EntityFactory {
float[] modelVertices = player.getComponent(ModelComponent.class).model.getVertices(); float[] modelVertices = player.getComponent(ModelComponent.class).model.getVertices();
float rotation = player.getComponent(PositionComponent.class).rotation; float rotation = player.getComponent(PositionComponent.class).rotation;
Vector2 direction = Utils.setUnitVectorAngle(tmp, rotation); PositionComponent position = new PositionComponent(modelVertices[0], modelVertices[1], rotation);
ModelComponent model = new ModelComponent(new PolygonModel(Color.YELLOW));
VelocityComponent velocity = new VelocityComponent(); model.setVertices(new float[]{
velocity.velocity = new Vector2(direction).scl(12.5f);
PositionComponent position = new PositionComponent();
position.position = new Vector2(modelVertices[0], modelVertices[1]);
position.rotation = rotation;
ModelComponent model = new ModelComponent();
model.model = new PolygonModel(Color.YELLOW);
model.model.setVertices(new float[]{
1/40f, 0f, 1/40f, 0f,
-1/40f, 0f, -1/40f, 0f,
-1/40f, -4/40f, -1/40f, -4/40f,
1/40f, -4/40f, 1/40f, -4/40f,
}); });
model.model.setRotation(position.rotation); model.setRotation(position.rotation);
model.model.setPosition(position.position); model.setPosition(position.position);
Vector2 direction = Utils.setUnitVectorAngle(tmp, rotation);
Entity bullet = createEntity(engine); Entity bullet = createEntity(engine);
bullet.addComponent(position); bullet.addComponent(position);
bullet.addComponent(velocity); bullet.addComponent(new VelocityComponent(new Vector2(direction).scl(12.5f)));
bullet.addComponent(model); bullet.addComponent(model);
bullet.addComponent(COLLIDER); bullet.addComponent(COLLIDER);
bullet.addComponent(new BulletComponent()); bullet.addComponent(new BulletComponent());
@ -192,13 +171,9 @@ public class EntityFactory {
public static Entity createAsteroid(Engine engine) { public static Entity createAsteroid(Engine engine) {
// Creates an asteroid entity with position and velocity unset - the AsteroidSpawningSystem // Creates an asteroid entity with position and velocity unset - the AsteroidSpawningSystem
// is responsible for setting its position and velocity // is responsible for setting its position and velocity
PositionComponent position = new PositionComponent(); ModelComponent model = new ModelComponent(new PolygonModel(Color.WHITE));
VelocityComponent velocity = new VelocityComponent();
ModelComponent model = new ModelComponent();
model.model = new PolygonModel(Color.WHITE);
float size = rand.nextFloat(1f, 1.75f); float size = rand.nextFloat(1f, 1.75f);
model.model.setVertices(new AsteroidFactory() model.setVertices(new AsteroidFactory()
.setVertexCount(32) .setVertexCount(32)
.setSize(size) .setSize(size)
.setSizeVariation(size * 0.5f) .setSizeVariation(size * 0.5f)
@ -206,8 +181,8 @@ public class EntityFactory {
.generate()); .generate());
Entity asteroid = createEntity(engine); Entity asteroid = createEntity(engine);
asteroid.addComponent(position); asteroid.addComponent(new PositionComponent());
asteroid.addComponent(velocity); asteroid.addComponent(new VelocityComponent());
asteroid.addComponent(model); asteroid.addComponent(model);
asteroid.addComponent(COLLIDER); asteroid.addComponent(COLLIDER);
asteroid.addComponent(new AsteroidComponent()); asteroid.addComponent(new AsteroidComponent());
@ -224,8 +199,8 @@ public class EntityFactory {
} }
public static Entity[] splitAsteroidIntoChunks(Engine engine, Entity asteroid, int chunkCount, float chunkScale) { public static Entity[] splitAsteroidIntoChunks(Engine engine, Entity asteroid, int chunkCount, float chunkScale) {
Vector2 asteroidVelocity = asteroid.getComponent(VelocityComponent.class).velocity; Vector2 asteroidVelocity = VELOCITY.get(asteroid).velocity;
Model asteroidModel = asteroid.getComponent(ModelComponent.class).model; ModelComponent asteroidModel = MODEL.get(asteroid);
Vector2 asteroidPosition = asteroidModel.getPosition(); Vector2 asteroidPosition = asteroidModel.getPosition();
float[] scaledVertices = scaleAndRelativizeVertices(asteroidPosition, asteroidModel.getVertices(), chunkScale); float[] scaledVertices = scaleAndRelativizeVertices(asteroidPosition, asteroidModel.getVertices(), chunkScale);
@ -237,30 +212,23 @@ public class EntityFactory {
for (int i = 0; i < chunkCount; i++) { for (int i = 0; i < chunkCount; i++) {
Vector2 chunkPosition = tmp2.set(asteroidPosition).add(tmp.scl(0.5f)); Vector2 chunkPosition = tmp2.set(asteroidPosition).add(tmp.scl(0.5f));
ModelComponent model = new ModelComponent(); ModelComponent model = new ModelComponent(new PolygonModel(asteroidModel.getColor()));
model.model = new PolygonModel(asteroidModel.getColor()); model.setVertices(Arrays.copyOf(scaledVertices, scaledVertices.length));
model.model.setVertices(Arrays.copyOf(scaledVertices, scaledVertices.length)); model.setPosition(chunkPosition);
model.model.setPosition(chunkPosition);
PositionComponent position = new PositionComponent();
position.position = new Vector2(chunkPosition);
position.rotation = 90;
VelocityComponent velocity = new VelocityComponent(); VelocityComponent velocity = new VelocityComponent();
velocity.velocity = new Vector2(tmp).nor().rotate(rand.nextFloat(-45, 45)).scl(asteroidVelocity.len() * 1.10f); velocity.set(tmp);
velocity.velocity.nor().rotate(rand.nextFloat(-45, 45)).scl(asteroidVelocity.len() * 1.10f);
velocity.angularVelocity = rand.nextFloat(-30, 30); velocity.angularVelocity = rand.nextFloat(-30, 30);
AsteroidComponent asteroidComponent = new AsteroidComponent();
asteroidComponent.generation = asteroid.getComponent(AsteroidComponent.class).generation + 1;
angle += angleStep; angle += angleStep;
Utils.setUnitVectorAngleRad(tmp, angle); Utils.setUnitVectorAngleRad(tmp, angle);
Entity split = createEntity(engine); Entity split = createEntity(engine);
split.addComponent(model); split.addComponent(model);
split.addComponent(position); split.addComponent(new PositionComponent(new Vector2(chunkPosition), 90));
split.addComponent(velocity); split.addComponent(velocity);
split.addComponent(asteroidComponent); split.addComponent(new AsteroidComponent(ASTEROID.get(asteroid).generation + 1));
split.addComponent(COLLIDER); split.addComponent(COLLIDER);
entities[i] = split; entities[i] = split;
} }

View File

@ -7,4 +7,41 @@ public class AccelerationComponent implements Component {
public Vector2 acceleration; public Vector2 acceleration;
public AccelerationComponent() {
this(0f, 0f);
}
public AccelerationComponent(float x, float y) {
this(new Vector2(x, y));
}
public AccelerationComponent(Vector2 acceleration) {
this.acceleration = acceleration;
}
public float getX() {
return acceleration.x;
}
public float getY() {
return acceleration.y;
}
public void setX(float x) {
acceleration.x = x;
}
public void setY(float y) {
acceleration.y = y;
}
public void set(Vector2 vector) {
set(vector.x, vector.y);
}
public void set(float x, float y) {
acceleration.x = x;
acceleration.y = y;
}
} }

View File

@ -6,4 +6,12 @@ public class AsteroidComponent implements Component {
public int generation; public int generation;
public AsteroidComponent() {
this(0);
}
public AsteroidComponent(int generation) {
this.generation = generation;
}
} }

View File

@ -1,5 +1,9 @@
package com.me.asteroids.components; package com.me.asteroids.components;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.me.asteroids.components.model.Model; import com.me.asteroids.components.model.Model;
import com.me.common.ecs.Component; import com.me.common.ecs.Component;
@ -7,4 +11,52 @@ public class ModelComponent implements Component {
public Model model; public Model model;
public ModelComponent(Model model) {
this.model = model;
}
public Color getColor() {
return model.getColor();
}
public ModelComponent setVertices(float[] vertices) {
model.setVertices(vertices);
return this;
}
public float[] getVertices() {
return model.getVertices();
}
public ModelComponent setPosition(Vector2 position) {
model.setPosition(position);
return this;
}
public Vector2 getPosition() {
return model.getPosition();
}
public ModelComponent setRotation(float degrees) {
model.setRotation(degrees);
return this;
}
public float getRotation() {
return model.getRotation();
}
public ModelComponent setScale(float scale) {
model.setScale(scale);
return this;
}
public float getScale() {
return model.getScale();
}
public Rectangle getBoundingBox() {
return model.getBoundingBox();
}
} }

View File

@ -8,4 +8,42 @@ public class PositionComponent implements Component {
public Vector2 position; public Vector2 position;
public float rotation; public float rotation;
public PositionComponent() {
this(0f, 0f, 0f);
}
public PositionComponent(float x, float y, float rotation) {
this(new Vector2(x, y), rotation);
}
public PositionComponent(Vector2 position, float rotation) {
this.position = position;
this.rotation = rotation;
}
public float getX() {
return position.x;
}
public float getY() {
return position.y;
}
public void setX(float x) {
position.x = x;
}
public void setY(float y) {
position.y = y;
}
public void set(Vector2 vector) {
set(vector.x, vector.y);
}
public void set(float x, float y) {
position.x = x;
position.y = y;
}
} }

View File

@ -7,7 +7,61 @@ public class VelocityComponent implements Component {
public Vector2 velocity; public Vector2 velocity;
public float angularVelocity; public float angularVelocity;
public float maxVelocity;
public float maxVelocity = Float.MAX_VALUE; public VelocityComponent() {
this(0f, 0f, 0f);
}
public VelocityComponent(Vector2 vector) {
this(vector, 0f);
}
public VelocityComponent(float x, float y) {
this(x, y, 0f);
}
public VelocityComponent(float x, float y, float angularVelocity) {
this(x, y, angularVelocity, Float.MAX_VALUE);
}
public VelocityComponent(float x, float y, float angularVelocity, float maxVelocity) {
this(new Vector2(x, y), angularVelocity, maxVelocity);
}
public VelocityComponent(Vector2 velocity, float angularVelocity) {
this(velocity, angularVelocity, Float.MAX_VALUE);
}
public VelocityComponent(Vector2 velocity, float angularVelocity, float maxVelocity) {
this.velocity = velocity;
this.angularVelocity = angularVelocity;
this.maxVelocity = maxVelocity;
}
public float getX() {
return velocity.x;
}
public float getY() {
return velocity.y;
}
public void setX(float x) {
velocity.x = x;
}
public void setY(float y) {
velocity.y = y;
}
public void set(Vector2 vector) {
set(vector.x, vector.y);
}
public void set(float x, float y) {
velocity.x = x;
velocity.y = y;
}
} }

View File

@ -87,9 +87,9 @@ public class GameDataSystem extends EntitySystem implements Listener {
private void resetPlayer() { private void resetPlayer() {
Entity player = engine.getEntities().get(1); Entity player = engine.getEntities().get(1);
PositionComponent position = POSITION.get(player); PositionComponent position = POSITION.get(player);
position.set(Constants.HALF_WIDTH, Constants.HALF_HEIGHT);
position.rotation = 90; position.rotation = 90;
position.position.set(Constants.HALF_WIDTH, Constants.HALF_HEIGHT); VELOCITY.get(player).set(0, 0);
VELOCITY.get(player).velocity.set(0, 0);
player.activate(); player.activate();
} }

View File

@ -29,7 +29,6 @@ public class MovementSystem extends EntitySystem {
public void processEntity(Entity entity, float dt) { public void processEntity(Entity entity, float dt) {
PositionComponent positionComponent = POSITION.get(entity); PositionComponent positionComponent = POSITION.get(entity);
VelocityComponent velocityComponent = VELOCITY.get(entity); VelocityComponent velocityComponent = VELOCITY.get(entity);
Vector2 velocity = velocityComponent.velocity; Vector2 velocity = velocityComponent.velocity;
AccelerationComponent accelComponent = ACCELERATION.get(entity); AccelerationComponent accelComponent = ACCELERATION.get(entity);