Add Model interface to be used for ModelComponent instead of Polygon
Allows shapes other than Polygons to be used a Model Add PolygonModel and LineModel implementations
This commit is contained in:
parent
b9e63dea26
commit
3918f8c1f5
@ -1,7 +1,6 @@
|
||||
package com.me.asteroids;
|
||||
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Polygon;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
import static com.me.asteroids.Constants.rand;
|
||||
@ -89,7 +88,7 @@ public final class AsteroidFactory {
|
||||
return size;
|
||||
}
|
||||
|
||||
public Polygon generate() {
|
||||
public float[] generate() {
|
||||
validate();
|
||||
|
||||
float angleStep = MathUtils.PI2 / vertexCount;
|
||||
@ -114,7 +113,7 @@ public final class AsteroidFactory {
|
||||
dir.rotateRad(angleStep);
|
||||
}
|
||||
|
||||
return new Polygon(vertices);
|
||||
return vertices;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
package com.me.asteroids;
|
||||
|
||||
import com.badlogic.gdx.math.Polygon;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
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.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.common.ecs.Engine;
|
||||
@ -36,14 +37,15 @@ public class EntityFactory {
|
||||
velocity.maxVelocity = 400f;
|
||||
|
||||
ModelComponent model = new ModelComponent();
|
||||
model.model = new Polygon(new float[] {
|
||||
model.model = new PolygonModel(Color.WHITE);
|
||||
model.model.setVertices(new float[] {
|
||||
0f, 4f, // tip
|
||||
-2.5f, -4f, // bottom left
|
||||
-1f, -2.5f, // indent
|
||||
1f, -2.5f, // indent
|
||||
2.5f, -4f, // bottom right
|
||||
});
|
||||
model.model.scale(5);
|
||||
model.model.setScale(5);
|
||||
|
||||
AccelerationComponent accel = new AccelerationComponent();
|
||||
accel.acceleration = new Vector2(0,1f);
|
||||
@ -58,7 +60,7 @@ public class EntityFactory {
|
||||
}
|
||||
|
||||
public static Entity createBullet(Engine engine, Entity player) {
|
||||
float[] modelVertices = player.getComponent(ModelComponent.class).model.getTransformedVertices();
|
||||
float[] modelVertices = player.getComponent(ModelComponent.class).model.getVertices();
|
||||
float rotation = player.getComponent(PositionComponent.class).rotation;
|
||||
|
||||
Vector2 direction = Utils.setUnitVectorAngle(tmp, rotation);
|
||||
@ -71,14 +73,15 @@ public class EntityFactory {
|
||||
position.rotation = rotation;
|
||||
|
||||
ModelComponent model = new ModelComponent();
|
||||
model.model = new Polygon(new float[] {
|
||||
model.model = new PolygonModel(Color.YELLOW);
|
||||
model.model.setVertices(new float[] {
|
||||
1f, 0f,
|
||||
-1f, 0f,
|
||||
-1f, -4f,
|
||||
1f, -4f,
|
||||
});
|
||||
model.model.setRotation(position.rotation);
|
||||
model.model.setPosition(position.position.x, position.position.y);
|
||||
model.model.setPosition(position.position);
|
||||
|
||||
|
||||
Entity bullet = createEntity(engine);
|
||||
@ -96,13 +99,14 @@ public class EntityFactory {
|
||||
VelocityComponent velocity = new VelocityComponent();
|
||||
|
||||
ModelComponent model = new ModelComponent();
|
||||
model.model = new PolygonModel(Color.WHITE);
|
||||
int size = rand.nextInt(30, 60);
|
||||
model.model = new AsteroidFactory()
|
||||
model.model.setVertices(new AsteroidFactory()
|
||||
.setVertexCount(rand.nextInt(16, 24))
|
||||
.setSize(size)
|
||||
.setSizeVariation(size * 0.7f)
|
||||
.generate();
|
||||
model.aabb = model.model.getBoundingRectangle();
|
||||
.sizeRelativeToLast()
|
||||
.generate());
|
||||
|
||||
Entity asteroid = createEntity(engine);
|
||||
asteroid.addComponent(position);
|
||||
|
@ -3,8 +3,6 @@ package com.me.asteroids;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
import java.lang.Math;
|
||||
|
||||
public final class Utils {
|
||||
|
||||
private static final Vector2 tmp = new Vector2();
|
||||
|
@ -1,11 +1,10 @@
|
||||
package com.me.asteroids.components;
|
||||
|
||||
import com.badlogic.gdx.math.Polygon;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.me.asteroids.components.model.Model;
|
||||
import com.me.common.ecs.Component;
|
||||
|
||||
public class ModelComponent implements Component {
|
||||
|
||||
public Polygon model;
|
||||
public Rectangle aabb;
|
||||
public Model model;
|
||||
|
||||
}
|
||||
|
110
core/src/com/me/asteroids/components/model/LineModel.java
Normal file
110
core/src/com/me/asteroids/components/model/LineModel.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.me.asteroids.components.model;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.badlogic.gdx.math.Polyline;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
public class LineModel implements Model {
|
||||
|
||||
private Vector2 tmp = new Vector2();
|
||||
|
||||
private Color color;
|
||||
|
||||
private Polyline model;
|
||||
private Rectangle aabb;
|
||||
|
||||
private boolean dirty = true;
|
||||
|
||||
public LineModel(Color color) {
|
||||
this.color = color;
|
||||
this.model = new Polyline();
|
||||
this.aabb = new Rectangle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVertices(float[] vertices) {
|
||||
model.setVertices(vertices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getVertices() {
|
||||
return model.getTransformedVertices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(Vector2 position) {
|
||||
model.setPosition(position.x, position.y);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 getPosition() {
|
||||
return tmp.set(model.getX(), model.getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotation(float degrees) {
|
||||
model.setRotation(degrees);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRotation() {
|
||||
return model.getRotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScale(float scale) {
|
||||
model.setScale(scale, scale);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getScale() {
|
||||
return model.getScaleX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getBoundingBox() {
|
||||
if (dirty) {
|
||||
updateBoundingBox();
|
||||
dirty = false;
|
||||
}
|
||||
return aabb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ShapeRenderer renderer) {
|
||||
renderer.polyline(getVertices());
|
||||
}
|
||||
|
||||
private void updateBoundingBox() {
|
||||
float[] vertices = getVertices();
|
||||
float minX = vertices[0];
|
||||
float minY = vertices[1];
|
||||
float maxX = vertices[0];
|
||||
float maxY = vertices[1];
|
||||
|
||||
for (int i = 0, n = vertices.length; i < n; i += 2) {
|
||||
float x = vertices[i];
|
||||
float y = vertices[i+1];
|
||||
minX = x < minX ? x : minX;
|
||||
maxX = x > maxX ? x : maxX;
|
||||
minY = y < minY ? y : minY;
|
||||
maxY = y > maxY ? y : maxY;
|
||||
}
|
||||
|
||||
aabb.x = minX;
|
||||
aabb.y = minY;
|
||||
aabb.width = maxX - minX;
|
||||
aabb.height = maxY - minY;
|
||||
}
|
||||
|
||||
}
|
32
core/src/com/me/asteroids/components/model/Model.java
Normal file
32
core/src/com/me/asteroids/components/model/Model.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.me.asteroids.components.model;
|
||||
|
||||
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;
|
||||
|
||||
public interface Model {
|
||||
|
||||
Color getColor();
|
||||
|
||||
void setVertices(float[] vertices);
|
||||
|
||||
float[] getVertices();
|
||||
|
||||
void setPosition(Vector2 position);
|
||||
|
||||
Vector2 getPosition();
|
||||
|
||||
void setRotation(float degrees);
|
||||
|
||||
float getRotation();
|
||||
|
||||
void setScale(float scale);
|
||||
|
||||
float getScale();
|
||||
|
||||
Rectangle getBoundingBox();
|
||||
|
||||
void render(ShapeRenderer render);
|
||||
|
||||
}
|
91
core/src/com/me/asteroids/components/model/PolygonModel.java
Normal file
91
core/src/com/me/asteroids/components/model/PolygonModel.java
Normal file
@ -0,0 +1,91 @@
|
||||
package com.me.asteroids.components.model;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.badlogic.gdx.math.Polygon;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
public class PolygonModel implements Model {
|
||||
|
||||
private Vector2 tmp = new Vector2();
|
||||
|
||||
private Color color;
|
||||
|
||||
private Polygon model;
|
||||
private Rectangle aabb;
|
||||
|
||||
private boolean dirty = true;
|
||||
|
||||
public PolygonModel(Color color) {
|
||||
this.color = color;
|
||||
this.model = new Polygon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVertices(float[] vertices) {
|
||||
model.setVertices(vertices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getVertices() {
|
||||
return model.getTransformedVertices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(Vector2 position) {
|
||||
model.setPosition(position.x, position.y);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 getPosition() {
|
||||
return tmp.set(model.getX(), model.getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotation(float degrees) {
|
||||
model.setRotation(degrees);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRotation() {
|
||||
return model.getRotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScale(float scale) {
|
||||
model.setScale(scale, scale);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getScale() {
|
||||
return model.getScaleX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getBoundingBox() {
|
||||
if (dirty) {
|
||||
aabb = model.getBoundingRectangle();
|
||||
dirty = false;
|
||||
}
|
||||
return aabb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ShapeRenderer renderer) {
|
||||
renderer.polygon(getVertices());
|
||||
}
|
||||
|
||||
public boolean contains(Vector2 point) {
|
||||
return model.contains(point);
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Polygon;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.me.asteroids.Constants;
|
||||
import com.me.asteroids.EntityFactory;
|
||||
@ -14,6 +13,7 @@ import com.me.asteroids.components.AsteroidComponent;
|
||||
import com.me.asteroids.components.BulletComponent;
|
||||
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.events.BulletAsteroidCollisionEvent;
|
||||
@ -116,9 +116,9 @@ public class GameScreen extends Screen implements Listener {
|
||||
@EventHandler
|
||||
public void onBulletAsteroidCollision(BulletAsteroidCollisionEvent event) {
|
||||
Vector2 bulletPosition = positionMapper.get(event.getBullet()).position;
|
||||
Polygon asteroidModel = modelMapper.get(event.getAsteroid()).model;
|
||||
|
||||
if (asteroidModel.contains(bulletPosition)) {
|
||||
PolygonModel model = (PolygonModel) modelMapper.get(event.getAsteroid()).model;
|
||||
if (model.contains(bulletPosition)) {
|
||||
// AABBs intersect but let's only consider it a hit if the bullet's position
|
||||
// is actually inside the asteroid
|
||||
event.getBullet().remove();
|
||||
|
@ -1,11 +1,13 @@
|
||||
package com.me.asteroids.systems;
|
||||
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.me.asteroids.Constants;
|
||||
import com.me.asteroids.EntityFactory;
|
||||
import com.me.asteroids.Utils;
|
||||
import com.me.asteroids.components.AsteroidComponent;
|
||||
import com.me.asteroids.components.model.Model;
|
||||
import com.me.asteroids.components.ModelComponent;
|
||||
import com.me.asteroids.components.PositionComponent;
|
||||
import com.me.asteroids.components.VelocityComponent;
|
||||
@ -53,12 +55,13 @@ public class AsteroidSpawningSystem extends BaseSystem {
|
||||
private void spawnAsteroid() {
|
||||
Entity asteroid = EntityFactory.createAsteroid(engine);
|
||||
|
||||
ModelComponent model = modelMapper.get(asteroid);
|
||||
Model model = modelMapper.get(asteroid).model;
|
||||
Rectangle aabb = model.getBoundingBox();
|
||||
|
||||
Vector2 position
|
||||
= positionMapper.get(asteroid).position
|
||||
= getRandomSpawnLocation(model.aabb.getWidth(), model.aabb.getHeight());
|
||||
model.model.setPosition(position.x, position.y);
|
||||
model.aabb = model.model.getBoundingRectangle();
|
||||
= getRandomSpawnLocation(aabb.getWidth(), aabb.getHeight());
|
||||
model.setPosition(position);
|
||||
|
||||
VelocityComponent velocityComponent = velocityMapper.get(asteroid);
|
||||
velocityComponent.velocity = new Vector2().setToRandomDirection().scl(rand.nextFloat(125, 175));
|
||||
|
@ -3,7 +3,6 @@ package com.me.asteroids.systems;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.me.asteroids.EventFactory;
|
||||
import com.me.asteroids.components.ModelComponent;
|
||||
import com.me.asteroids.events.CollisionEvent;
|
||||
import com.me.common.ecs.ComponentMapper;
|
||||
import com.me.common.ecs.Engine;
|
||||
import com.me.common.ecs.Entity;
|
||||
@ -23,12 +22,12 @@ public class CollisionSystem extends EntitySystem {
|
||||
Entity[] entities = getEntities().items;
|
||||
for (int i = 0, n = getEntities().size; i < n-1; i++) {
|
||||
Entity entityA = entities[i];
|
||||
Rectangle aabbA = modelMapper.get(entityA).aabb;
|
||||
Rectangle aabbA = modelMapper.get(entityA).model.getBoundingBox();
|
||||
|
||||
for (int j = i + 1; j < n; j++) {
|
||||
Entity entityB = entities[j];
|
||||
|
||||
Rectangle aabbB = modelMapper.get(entityB).aabb;
|
||||
Rectangle aabbB = modelMapper.get(entityB).model.getBoundingBox();
|
||||
if (aabbA.overlaps(aabbB)) {
|
||||
engine.callEvent(EventFactory.getNewCollisionEvent(entityA, entityB));
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
package com.me.asteroids.systems;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.badlogic.gdx.math.Polygon;
|
||||
import com.me.asteroids.Graphics;
|
||||
import com.me.asteroids.components.model.Model;
|
||||
import com.me.asteroids.components.ModelComponent;
|
||||
import com.me.common.ecs.ComponentMapper;
|
||||
import com.me.common.ecs.Engine;
|
||||
@ -24,16 +23,15 @@ public class ModelRenderSystem extends EntitySystem {
|
||||
|
||||
@Override
|
||||
public void preProcess() {
|
||||
renderer.setColor(Color.WHITE);
|
||||
renderer.begin(ShapeRenderer.ShapeType.Line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEntity(Entity entity, float dt) {
|
||||
ModelComponent modelComponent = modelMapper.get(entity);
|
||||
Model model = modelMapper.get(entity).model;
|
||||
|
||||
Polygon model = modelComponent.model;
|
||||
renderer.polygon(model.getTransformedVertices());
|
||||
renderer.setColor(model.getColor());
|
||||
model.render(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.me.asteroids.systems;
|
||||
|
||||
import com.badlogic.gdx.math.Polygon;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.me.asteroids.components.AccelerationComponent;
|
||||
import com.me.asteroids.components.model.Model;
|
||||
import com.me.asteroids.components.ModelComponent;
|
||||
import com.me.asteroids.components.PositionComponent;
|
||||
import com.me.asteroids.components.VelocityComponent;
|
||||
@ -50,10 +50,9 @@ public class MovementSystem extends EntitySystem {
|
||||
|
||||
ModelComponent modelComponent = modelMapper.get(entity);
|
||||
if (modelComponent != null) {
|
||||
Polygon model = modelComponent.model;
|
||||
model.setPosition(position.x, position.y);
|
||||
Model model = modelComponent.model;
|
||||
model.setPosition(position);
|
||||
model.setRotation(positionComponent.rotation - 90);
|
||||
modelComponent.aabb = model.getBoundingRectangle();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,8 @@ public class ScreenWrapSystem extends EntitySystem {
|
||||
|
||||
@Override
|
||||
public void processEntity(Entity entity, float dt) {
|
||||
PositionComponent positionComponent = positionMapper.get(entity);
|
||||
ModelComponent modelComponent = modelMapper.get(entity);
|
||||
|
||||
Vector2 position = positionComponent.position;
|
||||
Rectangle aabb = modelComponent.aabb;
|
||||
Vector2 position = positionMapper.get(entity).position;
|
||||
Rectangle aabb = modelMapper.get(entity).model.getBoundingBox();
|
||||
|
||||
// Check top/bottom edges
|
||||
float minY = aabb.y;
|
||||
@ -57,7 +54,6 @@ public class ScreenWrapSystem extends EntitySystem {
|
||||
updatePosition(entity, position, Constants.WIDTH + (position.x - minX) + maxX, position.y);
|
||||
} else if (minX > Constants.WIDTH) {
|
||||
updatePosition(entity, position, (position.x - maxX) + (minX - Constants.WIDTH), position.y);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user