Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Graphic update : Walls and Obstacles

To draw everything that is not drawn by the TiledMapRenderer, I need to implement a draw() method in the entities I want to draw.

Basically, the way I built my code, I have the Obstacle entities, that represents almost everything the hero will interact or collide with (walls and various moving objects). Thus I need to create draw methods for every type of Obstacle. And that's where my code starts to be REALLY messy and dirty. No time for code optimization and code cleaning at this point of the jam, remember ?

So, there are some Obstacle entities that will require a NinePatch (Walls and Pistons), and some Obstacle entities that will require a Texture (all the other Obstacles I think). Texture and NinePatch don't use the same draw method. Then, I have to take this point into account.

Before seeing the code for the draw methods, let's see the simple part :

Organizing the Entities

Before calling the different draw methods in the render of the GameScreen, I organize the different entities to be drawn in Arrays :

In the TiledMapReader.java, I store the Obstacles that need a Texture in an array called "obstacles" and I store the Obstacles that need a NinePatch in an array called obstaclesWithNinePatch .

For that, I only need to do

obstacles.add(obstacle);

or

obstaclesWithNinePatch.add(obstacle);

Drawing the entities

Once the various Obstacles stored in the right Array, I can draw them in the GameScreen.java, by calling the right draw method, whether the Obstacle uses a Texture or a NinePatch.

For that, I need to add this code in the render() of the GameScreen.java :

game.batch.begin();
for(Obstacle obstacle : mapReader.obstaclesWithNinePatch)
    obstacle.draw(game.batch);
for(Obstacle obstacle : mapReader.obstacles)
    obstacle.draw(game.batch, textureAtlas);
game.batch.end();

Then let's go the really messy part


Reorganization of the Obstacle.java

The Obstacle.java was reorganize to have a constructor that need a TextureAtlas as argument, which is needed for the use of NinePatch.

Now Obstacle.java have these constructors :

public Obstacle(World world, OrthographicCamera camera, MapObject rectangleObject){        
}
    
public Obstacle(World world, OrthographicCamera camera, MapObject rectangleObject, TextureAtlas textureAtlas){        
}
    
public Obstacle(World world, OrthographicCamera camera, PolylineMapObject polylineObject){
        setInitialState(polylineObject);
}
  1. Constructor for Obstacle requiring a Texture
  2. Constructor for Obstacle requiring a NinePatch
  3. Constructor only used by ObstacleMoving.java
You can see that these constructors are empty. All the code of the Body creation has been moved in a create() method.

And there are also two draw() methods.

1. Draw method that uses a Texture :

public void draw(SpriteBatch batch, TextureAtlas textureAtlas){        
        batch.setColor(0, 0, 0.1f, 1);
        batch.draw(textureAtlas.findRegion("WhiteSquare"), 
                this.body.getPosition().x - width, 
                this.body.getPosition().y - height,
                width,
                height,
                2 * width,
                2 * height,
                1,
                1,
                body.getAngle()*MathUtils.radiansToDegrees);
}

2. Draw method that uses a NinePatch :

public void draw(SpriteBatch batch){
        batch.setColor(1, 1, 1, 1);
        ninePatch.draw(batch, 
                        this.body.getPosition().x - width,
                        this.body.getPosition().y - height, 
                        2 * width, 
                        2 * height);
}

Creation of a Wall class

In the past, in the TiledMapReader, I had a for loop that checked what type of Obstacle need to be created, and by default, it created an Obstacle. I did a little change, and created a Wall class, and now, the for loop creates a Wall by default.

Here is the code of Wall.java :

public class Wall extends Obstacle{

    public Wall(World world, OrthographicCamera camera, MapObject rectangleObject, TextureAtlas textureAtlas) {
        super(world, camera, rectangleObject, textureAtlas);    
        create(world, camera, rectangleObject);

        ninePatch = new NinePatch(textureAtlas.findRegion("Wall"), 49, 49, 49, 49);
        ninePatch.scale(0.5f*GameConstants.MPP, 0.5f*GameConstants.MPP);
    }
}

Drawing a NinePatch

As you can see the Wall.java, we create a NinePatch with this line

ninePatch = new NinePatch(textureAtlas.findRegion("Wall"), 49, 49, 49, 49);

In Photoshop I drew an image of 100px by 100px dimension, and I packed it in the TextureAtlas with all the other images.Then, when I create the NinePatch with the above code line, I tell which texture will be the NinePatch, and I define which regions will stretch with the "49, 49, 49, 49" of the code which correspond to the coordinates of 4 lines that will split the chosen texture in 9 parts.

Then I resize the NinePatch so it's not HUGE, and it can incorporate well in my game with this line

 ninePatch.scale(0.5f*GameConstants.MPP, 0.5f*GameConstants.MPP);

The case of the ObstaclePiston

Drawing the ObstaclePiston was a bit tricky, as it needs two NinePatch : one for the head and one for the axis that need to be positionned precisely.

I rewrote most of the ObstaclePiston.java, and I could spend a whole post on it. Just click the link to see the code in the repository.