mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-01-28 08:30:08 +07:00
Added support for generating box2d bodies for monster and objects and generalized player entities
Added support for generating box2d bodies for monster and objects and generalized player entities Added support for object entities to perform a bitwise or with the map tile flags so pathfinding will avoid them
This commit is contained in:
parent
266eca76ce
commit
d6f8de3b86
@ -20,6 +20,7 @@ import com.riiablo.codec.util.BBox;
|
||||
import com.riiablo.engine.component.AngleComponent;
|
||||
import com.riiablo.engine.component.AnimationComponent;
|
||||
import com.riiablo.engine.component.BBoxComponent;
|
||||
import com.riiablo.engine.component.Box2DComponent;
|
||||
import com.riiablo.engine.component.ClassnameComponent;
|
||||
import com.riiablo.engine.component.CofComponent;
|
||||
import com.riiablo.engine.component.DS1Component;
|
||||
@ -231,6 +232,10 @@ public class Engine extends PooledEngine {
|
||||
interactableComponent.range = base.OperateRange;
|
||||
}
|
||||
|
||||
SizeComponent sizeComponent = createComponent(SizeComponent.class);
|
||||
|
||||
Box2DComponent box2DComponent = createComponent(Box2DComponent.class);
|
||||
|
||||
Entity entity = createEntity(base.Description);
|
||||
entity.add(typeComponent);
|
||||
if (draw) entity.add(cofComponent);
|
||||
@ -242,6 +247,8 @@ public class Engine extends PooledEngine {
|
||||
entity.add(objectComponent);
|
||||
entity.add(labelComponent);
|
||||
if (interactableComponent != null) entity.add(interactableComponent);
|
||||
entity.add(sizeComponent);
|
||||
entity.add(box2DComponent);
|
||||
|
||||
labelComponent.actor.setUserObject(entity);
|
||||
|
||||
@ -298,6 +305,10 @@ public class Engine extends PooledEngine {
|
||||
PositionComponent positionComponent = createComponent(PositionComponent.class);
|
||||
positionComponent.position.set(x, y);
|
||||
|
||||
VelocityComponent velocityComponent = createComponent(VelocityComponent.class);
|
||||
velocityComponent.walkSpeed = monstats.Velocity;
|
||||
velocityComponent.runSpeed = monstats.Run;
|
||||
|
||||
LabelComponent labelComponent = createComponent(LabelComponent.class);
|
||||
labelComponent.offset.y = monstats2.pixHeight;
|
||||
labelComponent.actor = createLabel(name);
|
||||
@ -312,18 +323,22 @@ public class Engine extends PooledEngine {
|
||||
SizeComponent sizeComponent = createComponent(SizeComponent.class);
|
||||
sizeComponent.size = monstats2.SizeX; // FIXME: see above note
|
||||
|
||||
Box2DComponent box2DComponent = createComponent(Box2DComponent.class);
|
||||
|
||||
Entity entity = createEntity(monstats.Id);
|
||||
entity.add(typeComponent);
|
||||
entity.add(cofComponent);
|
||||
entity.add(animationComponent);
|
||||
entity.add(boxComponent);
|
||||
entity.add(positionComponent);
|
||||
entity.add(velocityComponent);
|
||||
entity.add(mapComponent);
|
||||
entity.add(ds1Component);
|
||||
entity.add(monsterComponent);
|
||||
entity.add(labelComponent);
|
||||
if (interactableComponent != null) entity.add(interactableComponent);
|
||||
entity.add(sizeComponent);
|
||||
entity.add(box2DComponent);
|
||||
|
||||
labelComponent.actor.setUserObject(entity);
|
||||
|
||||
@ -453,6 +468,8 @@ public class Engine extends PooledEngine {
|
||||
SizeComponent sizeComponent = createComponent(SizeComponent.class);
|
||||
sizeComponent.size = SizeComponent.MEDIUM;
|
||||
|
||||
Box2DComponent box2DComponent = createComponent(Box2DComponent.class);
|
||||
|
||||
Entity entity = createEntity("player");
|
||||
entity.add(typeComponent);
|
||||
entity.add(cofComponent);
|
||||
@ -466,6 +483,7 @@ public class Engine extends PooledEngine {
|
||||
entity.add(playerComponent);
|
||||
entity.add(zoneAwareComponent);
|
||||
entity.add(sizeComponent);
|
||||
entity.add(box2DComponent);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import com.riiablo.engine.component.Box2DComponent;
|
||||
import com.riiablo.engine.component.VelocityComponent;
|
||||
|
||||
public class Box2DBodySystem extends IteratingSystem {
|
||||
private final ComponentMapper<VelocityComponent> velocitycomponent = ComponentMapper.getFor(VelocityComponent.class);
|
||||
private final ComponentMapper<VelocityComponent> velocityComponent = ComponentMapper.getFor(VelocityComponent.class);
|
||||
private final ComponentMapper<Box2DComponent> box2DComponent = ComponentMapper.getFor(Box2DComponent.class);
|
||||
|
||||
public Box2DBodySystem() {
|
||||
@ -17,7 +17,7 @@ public class Box2DBodySystem extends IteratingSystem {
|
||||
|
||||
@Override
|
||||
protected void processEntity(Entity entity, float delta) {
|
||||
VelocityComponent velocityComponent = this.velocitycomponent.get(entity);
|
||||
VelocityComponent velocityComponent = this.velocityComponent.get(entity);
|
||||
Box2DComponent box2DComponent = this.box2DComponent.get(entity);
|
||||
box2DComponent.body.setLinearVelocity(velocityComponent.velocity);
|
||||
}
|
||||
|
@ -6,11 +6,13 @@ import com.badlogic.ashley.core.Entity;
|
||||
import com.badlogic.ashley.core.EntityListener;
|
||||
import com.badlogic.ashley.core.Family;
|
||||
import com.badlogic.ashley.systems.IntervalIteratingSystem;
|
||||
import com.badlogic.ashley.utils.ImmutableArray;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.physics.box2d.Body;
|
||||
import com.badlogic.gdx.physics.box2d.BodyDef;
|
||||
import com.badlogic.gdx.physics.box2d.Box2D;
|
||||
import com.badlogic.gdx.physics.box2d.CircleShape;
|
||||
import com.badlogic.gdx.physics.box2d.Filter;
|
||||
import com.badlogic.gdx.physics.box2d.Fixture;
|
||||
import com.badlogic.gdx.physics.box2d.PolygonShape;
|
||||
@ -21,7 +23,10 @@ import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.riiablo.camera.IsometricCamera;
|
||||
import com.riiablo.engine.component.Box2DComponent;
|
||||
import com.riiablo.engine.component.ObjectComponent;
|
||||
import com.riiablo.engine.component.PositionComponent;
|
||||
import com.riiablo.engine.component.SizeComponent;
|
||||
import com.riiablo.engine.component.TypeComponent;
|
||||
import com.riiablo.engine.component.VelocityComponent;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -32,9 +37,31 @@ public class Box2DPhysicsSystem extends IntervalIteratingSystem implements Entit
|
||||
|
||||
private final ComponentMapper<PositionComponent> positionComponent = ComponentMapper.getFor(PositionComponent.class);
|
||||
private final ComponentMapper<Box2DComponent> box2dComponent = ComponentMapper.getFor(Box2DComponent.class);
|
||||
private final ComponentMapper<SizeComponent> sizeComponent = ComponentMapper.getFor(SizeComponent.class);
|
||||
private final ComponentMapper<TypeComponent> typeComponent = ComponentMapper.getFor(TypeComponent.class);
|
||||
|
||||
private final ComponentMapper<ObjectComponent> objectComponent = ComponentMapper.getFor(ObjectComponent.class);
|
||||
private final Family objectFamily = Family.all(ObjectComponent.class, SizeComponent.class, PositionComponent.class).get();
|
||||
private ImmutableArray<Entity> objectEntities;
|
||||
|
||||
private final float timeStep;
|
||||
|
||||
private final BodyDef wallBodyDef = new BodyDef() {{
|
||||
type = BodyDef.BodyType.StaticBody;
|
||||
awake = false;
|
||||
allowSleep = true;
|
||||
fixedRotation = true;
|
||||
}};
|
||||
private final BodyDef objectBodyDef = new BodyDef() {{
|
||||
type = BodyDef.BodyType.StaticBody;
|
||||
fixedRotation = true;
|
||||
}};
|
||||
private final BodyDef monsterBodyDef = new BodyDef() {{
|
||||
type = BodyDef.BodyType.DynamicBody;
|
||||
fixedRotation = true;
|
||||
}};
|
||||
private final BodyDef playerBodyDef = monsterBodyDef;
|
||||
|
||||
private Map map;
|
||||
public World world;
|
||||
|
||||
@ -55,25 +82,34 @@ public class Box2DPhysicsSystem extends IntervalIteratingSystem implements Entit
|
||||
@Override
|
||||
public void addedToEngine(Engine engine) {
|
||||
super.addedToEngine(engine);
|
||||
engine.addEntityListener(Family.all(Box2DComponent.class).get(), this);
|
||||
engine.addEntityListener(Family.all(TypeComponent.class, PositionComponent.class, SizeComponent.class, Box2DComponent.class).get(), this);
|
||||
objectEntities = engine.getEntitiesFor(objectFamily);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removedFromEngine(Engine engine) {
|
||||
super.removedFromEngine(engine);
|
||||
engine.removeEntityListener(this);
|
||||
objectEntities = null;
|
||||
dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityAdded(Entity entity) {
|
||||
Box2DComponent box2DComponent = this.box2dComponent.get(entity);
|
||||
Box2DComponent box2DComponent = com.riiablo.engine.Engine
|
||||
.getOrCreateComponent(entity, getEngine(), Box2DComponent.class, box2dComponent);
|
||||
if (box2DComponent.body == null) box2DComponent.body = createBody(entity);
|
||||
if (box2DComponent.body == null) {
|
||||
entity.remove(Box2DComponent.class);
|
||||
return;
|
||||
}
|
||||
bodies.put(entity, box2DComponent.body);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityRemoved(Entity entity) {
|
||||
Body body = bodies.remove(entity);
|
||||
if (body == null) return;
|
||||
world.destroyBody(body);
|
||||
}
|
||||
|
||||
@ -86,14 +122,57 @@ public class Box2DPhysicsSystem extends IntervalIteratingSystem implements Entit
|
||||
}
|
||||
}
|
||||
|
||||
private Body createBody(Entity entity) {
|
||||
SizeComponent sizeComponent = this.sizeComponent.get(entity);
|
||||
TypeComponent typeComponent = this.typeComponent.get(entity);
|
||||
if (sizeComponent.size == SizeComponent.INSIGNIFICANT && typeComponent.type != TypeComponent.Type.OBJ) return null;
|
||||
|
||||
PositionComponent positionComponent = this.positionComponent.get(entity);
|
||||
|
||||
Body body;
|
||||
switch (typeComponent.type) {
|
||||
case OBJ: {
|
||||
ObjectComponent objectComponent = entity.getComponent(ObjectComponent.class);
|
||||
objectBodyDef.position.set(positionComponent.position);
|
||||
body = world.createBody(objectBodyDef);
|
||||
PolygonShape shape = new PolygonShape(); {
|
||||
shape.setAsBox(objectComponent.base.SizeX / 2f, objectComponent.base.SizeY / 2f);
|
||||
body.createFixture(shape, 1f);
|
||||
} shape.dispose();
|
||||
if (map != null) {
|
||||
map.or(positionComponent.position, objectComponent.base.SizeX, objectComponent.base.SizeY, DT1.Tile.FLAG_BLOCK_WALK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MON: {
|
||||
monsterBodyDef.position.set(positionComponent.position);
|
||||
body = world.createBody(monsterBodyDef);
|
||||
CircleShape shape = new CircleShape(); {
|
||||
shape.setRadius(sizeComponent.size / 2f);
|
||||
Fixture fixture = body.createFixture(shape, 1f);
|
||||
//fixture.setSensor(true);
|
||||
} shape.dispose();
|
||||
}
|
||||
break;
|
||||
case PLR: {
|
||||
playerBodyDef.position.set(positionComponent.position);
|
||||
body = world.createBody(playerBodyDef);
|
||||
CircleShape shape = new CircleShape(); {
|
||||
shape.setRadius(sizeComponent.size / 2f);
|
||||
Fixture fixture = body.createFixture(shape, 1f);
|
||||
//fixture.setSensor(true);
|
||||
} shape.dispose();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
body = null;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
private void createBodies(Vector2 offset) {
|
||||
IntMap<Filter> filters = new IntMap<>();
|
||||
|
||||
BodyDef def = new BodyDef();
|
||||
def.type = BodyDef.BodyType.StaticBody;
|
||||
def.awake = false;
|
||||
def.allowSleep = true;
|
||||
def.fixedRotation = true;
|
||||
boolean[][] handled = new boolean[1000][1000];
|
||||
for (Map.Zone zone : new Array.ArrayIterator<>(map.zones)) {
|
||||
for (boolean[] a : handled) Arrays.fill(a, false);
|
||||
@ -118,7 +197,7 @@ public class Box2DPhysicsSystem extends IntervalIteratingSystem implements Entit
|
||||
}
|
||||
|
||||
int lenY = endY - ty;
|
||||
def.position.set((endX + tx) / 2f, (endY + ty) / 2f).add(offset);
|
||||
wallBodyDef.position.set((endX + tx) / 2f, (endY + ty) / 2f).add(offset);
|
||||
|
||||
PolygonShape shape = new PolygonShape();
|
||||
shape.setAsBox(lenX / 2f, lenY / 2f);
|
||||
@ -131,7 +210,7 @@ public class Box2DPhysicsSystem extends IntervalIteratingSystem implements Entit
|
||||
filter.groupIndex = 0;
|
||||
}
|
||||
|
||||
Body body = world.createBody(def);
|
||||
Body body = world.createBody(wallBodyDef);
|
||||
Fixture f = body.createFixture(shape, 0);
|
||||
f.setFilterData(filter);
|
||||
|
||||
@ -143,6 +222,12 @@ public class Box2DPhysicsSystem extends IntervalIteratingSystem implements Entit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Entity entity : objectEntities) {
|
||||
PositionComponent positionComponent = this.positionComponent.get(entity);
|
||||
ObjectComponent objectComponent = this.objectComponent.get(entity);
|
||||
map.or(positionComponent.position, objectComponent.base.SizeX, objectComponent.base.SizeY, DT1.Tile.FLAG_BLOCK_WALK);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean allEqual(Map map, int x, int y, int len, int flags) {
|
||||
|
@ -633,6 +633,18 @@ public class Map implements Disposable {
|
||||
return zone.flags(x, y);
|
||||
}
|
||||
|
||||
void or(Vector2 position, int width, int height, int flags) {
|
||||
if (width == 0 || height == 0) return;
|
||||
int x0 = round(position.x - width / 2f);
|
||||
int y0 = round(position.y - height / 2f);
|
||||
for (int x = 0; x < width; x++, x0++) {
|
||||
for (int y = 0; y < height; y++, y0++) {
|
||||
Zone zone = getZone(x0, y0);
|
||||
if (zone != null) zone.or(x0, y0, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DT1.Tile getTile(int l, int x, int y) {
|
||||
Zone zone = getZone(x, y);
|
||||
if (zone == null) return null;
|
||||
@ -886,6 +898,14 @@ public class Map implements Disposable {
|
||||
return flags[x][y] & 0xFF;
|
||||
}
|
||||
|
||||
int or(int x, int y, int flags) {
|
||||
x -= this.x;
|
||||
if (x < 0 || x > width ) return 0xFF;
|
||||
y -= this.y;
|
||||
if (y < 0 || y > height) return 0xFF;
|
||||
return (this.flags[x][y] |= flags) & 0xFF;
|
||||
}
|
||||
|
||||
void load(DT1s dt1s) {
|
||||
Validate.validState(tiles == null, "tiles have already been loaded");
|
||||
tiles = new Tile[Map.MAX_LAYERS][][];
|
||||
|
Loading…
Reference in New Issue
Block a user