I am creating a brick breaker game using libgdx, using the TiledMapEditor to create my levels. i have a layer for my brick graphics and a layer for my brick objects. i have collision working with my brick objects, i have the tile in the brick graphics layer set to null when Collison happens and working. Great, Awesome... except i have created my brinks to be multiple tiles in size. so when i collide with my brick object it turns collision off and removes that specific cell graphic. Leaving me with half the brick still showing on the screen. i have checked the documentation on tiledMaps, the libdx dox and searched slack/goodle/youtube/tiled dox. i thought of creating a method to check if the cells around is not null then to turn them null, but that wont work when i have bricks right beside each other. any ideas or suggestions or even a hint to where to look would be much appreciated. Or to change my sizing of my bricks to fit in one tile. i would rather figure a way out to remove all cells that are over the specified objects
Class for creating my interactive objects
public InteractiveTileObject(World world, TiledMap map, Rectangle rect) {
this.world = world;
this.map = map;
this.rect = rect;
bDef = new BodyDef();
fDef = new FixtureDef();
shape = new PolygonShape();
bDef.type = BodyDef.BodyType.StaticBody;
bDef.position.set((rect.getX() * Arma.VSCALE) + (rect.getWidth() * Arma.VSCALE / 2),
(rect.getY() * Arma.VSCALE) + (rect.getHeight() * Arma.VSCALE / 2));
body = world.createBody(bDef);
shape.setAsBox(rect.getWidth() * Arma.VSCALE / 2, rect.getHeight() * Arma.VSCALE / 2);
fDef.shape = shape;
fixture = body.createFixture(fDef);
}
public abstract void onHit();
public void setCategoryFilter(short filterBit){
Filter filter = new Filter();
filter.categoryBits = filterBit;
fixture.setFilterData(filter);
}
public TiledMapTileLayer.Cell getCell(){
int column = (int)(body.getPosition().x / Arma.VSCALE / 50);
int row = (int)(body.getPosition().y / Arma.VSCALE / 50);
TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(2);
return layer.getCell(column,row);
}
}
Class that pulls objects from TiledMapEditor
public B2WorldCreator(PlayScreen screen) {
World world = screen.getWorld();
TiledMap map = screen.getMap();
BodyDef bDef = new BodyDef();
PolygonShape shape = new PolygonShape();
FixtureDef fDef = new FixtureDef();
Body body;
//create boundy body/fix
for (MapObject object : map.getLayers().get(3).getObjects().getByType(RectangleMapObject.class)) {
Rectangle rect = ((RectangleMapObject) object).getRectangle();
new Boundary(world, map, rect);
}
//create bricks body/fix
for (MapObject object : map.getLayers().get(4).getObjects().getByType(RectangleMapObject.class)) {
Rectangle rect = ((RectangleMapObject) object).getRectangle();
new Brick(world, map, rect);
}
//create wall light body/fix
for (MapObject object : map.getLayers().get(5).getObjects().getByType(RectangleMapObject.class)) {
Rectangle rect = ((RectangleMapObject) object).getRectangle();
new Wall(world, map, rect);
}
}
}
Brick Class
public class Brick extends InteractiveTileObject{
public Brick(World world, TiledMap map, Rectangle bounds) {
super(world, map, bounds);
fixture.setUserData(this);
setCategoryFilter(Arma.BRICK_BIT);
}
@Override
public void onHit() {
Gdx.app.log("Brick", "Collision");
setCategoryFilter(Arma.DEYSTROYED_BIT);
getCell().setTile(null);
}
}
i created this method which works but still need to enter the size of the objects, i would much rather get your method working Tobias.
public void getCells(int width, int height){
int column = (int)((body.getPosition().x / Arma.VSCALE -25) / 50);
int row = (int)((body.getPosition().y / Arma.VSCALE -25) / 50 );
TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get(2);
for (int i = 0; i < width; i++){
for (int k = 0; k < height; k++){
if (layer.getCell(column + i, row + k) != null)
layer.getCell(column + i, row + k).setTile(null);
}
}
You are selecting the cells, that you want to remove by their position on the tiled map. You can do the same for the other cells, that are in the range of the Box2D body, that was hit. The only difference is, that it's a bit more difficult to check whether the tested position is still inside the body (currently you are only checking the body's position).
A solution could look like this:
After you filled in the constants of
MAX_NUMBER_OF_CELLS_PER_BODYandSIZE_OF_A_TILE_CELLyou should be able to find every cell, this body contains. Then you can just remove them like you did before.