Building Colliders - UQdeco2800/2022-studio-3 GitHub Wiki
The Colliders were changed from rectangles to various shaped polygons to fit with the isometric view.
Entity Collision with buildings
As you can see with the old collider, it contatins a lot of empty space that entities would get caught up on which is big problem. At first the colliders were rotated 60 degrees to fit with the isometric view. This worked for the walls but the other buildings have a more complex structure. It was more accurate to find the points on the texture, convert it to a shape and set it as the new collider. This decision was made because when navigating around the world, you would expect to only get caught up on things you see (since you will not actually be able to see the colliders without the debug mode on) so the colliders need to be exactly representative of the sprite.
The colliders can be seen as the fine green bounding boxes around the buildings.
Old collider | New colliders |
---|---|
Wall coliders
The wall coliders were rotated 60 degrees (isometric view):
This can be seen in BuildingFactory.java:createWall()
Entity wall = new Entity();
// other irrelevant create wall stuff ommited
PolygonShape boundingBox = new PolygonShape();
Vector2 center = wall.getCenterPositon(); // Collider to be set around center of entity
boundingBox.setAsBox(center.x * 0.25f, center.y * 0.25f, center, (float) (60 * Math.PI / 180));
wall.getComponent(ColliderComponent.class).setShape(boundingBox);
Entities also don't get stuck when moving along the walls and the colliders are connected smoothly. (better explained in the video linked below)
Video demo: Collision with wall demonstration.mp4 - Demonstrates how the player collider can now slide up down against the walls without a lot of impedance.
\
TownHall and Barracks Collider
As explained above, a different method was used for more complex buildings.
How pixel coordinates were found from the textures
By using an image paint program, it was easy to pinpoint the exact pixel locations to set the points on the collider. And as you can see the drafted points below directly line up with the colliders seen at the top of this page.
TownHall | Barracks |
---|---|
For TownHall: BuildingFactory.java:createTownHall()
final float TH_SCALE = 7f;
Entity townHall = new Entity();
/*
... other irrelevant townhall creation stuff
*/
// Setting Isometric Collider
// Points (in pixels) on the texture to set the collider to
float[] points = new float[] { // Four vertices
31f, 607f, // Vertex 0 3--2
499f, 835f, // Vertex 1 / /
958f, 515f, // Vertex 2 / /
486f, 289f // Vertex 3 0--1
};
// Defines a polygon shape on top of a texture region
PolygonRegion region = new PolygonRegion(new TextureRegion(ServiceLocator.getResourceService()
.getAsset("images/base.png", Texture.class)), points, null);
float[] cords = region.getTextureCoords();
Vector2[] vertices = new Vector2[region.getTextureCoords().length / 2];
for (int i = 0; i < cords.length / 2; i++) {
vertices[i] = new Vector2(cords[2*i], cords[2*i+1]).scl(TH_SCALE);
}
PolygonShape boundingBox = new PolygonShape(); // Collider shape
boundingBox.set(vertices);
townHall.getComponent(ColliderComponent.class).setShape(boundingBox); // Setting Isometric Collider
For Barracks: BuildingFactory.java:createBarracks()
final float BARRACKS_SCALE = 5f;
Entity barracks = new Entity();
/*
... other irrelevant townhall creation stuff
*/
// Setting Isometric Collider
// Points (in pixels) on the texture to set the collider to
float[] points = new float[]{
895f, 1649f, // Vertex 0 3
1568f, 1312f, // Vertex 1 4 / \ 2
1568f, 1088f, // Vertex 2 | |
893f, 749f, // Vertex 3 5 \ / 1
228f, 1078f, // Vertex 4 0
228f, 1311f // Vertex 5
};
// Defines a polygon shape on top of a texture region
PolygonRegion region = new PolygonRegion(new TextureRegion(ServiceLocator.getResourceService()
.getAsset("images/isometric barracks current.png", Texture.class)), points, null);
float[] cords = region.getTextureCoords();
Vector2[] vertices = new Vector2[region.getTextureCoords().length / 2];
for (int i = 0; i < cords.length / 2; i++) {
vertices[i] = new Vector2(cords[2*i], cords[2*i+1]).scl(BARRACKS_SCALE);
}
PolygonShape boundingBox = new PolygonShape(); // Collider shape
boundingBox.set(vertices);
barracks.getComponent(ColliderComponent.class).setShape(boundingBox); // Setting Isometric Collider
return barracks;
Mouse Click Collision with buildings
Another problem was when trying to select an entity and a building in close proximity was also selected when it shouldn't have been selected. Also when trying to select a single wall, a lot of walls around it would also be selected at the same time.
This was fixed by using these new colliders to test collision instead using a square around the entity
This can be seen in the SelectableComponent.java:isIn(xCoordinate, yCoordinate)
Vector2 pointInWorld = screenToWorldPosition(xCoordinate, yCoordinate);
// If entity is a building, test if the clicked point is in building collider
if (entity.getComponent(BuildingActions.class) != null) {
selected = entity.getComponent(ColliderComponent.class).getFixture().testPoint(pointInWorld);
return;
}