Day 20: Scalable Vector Graphics

Introduction

we created a simple app with an animated sprite. If you tried this app on different screen resolutions, such as Ultra HD tablets or low-resolution phones, you would notice a quality issue. If the device’s smallest native dimension is less than Artenus’ standard 600px, there will be an unclean scale-down, and if it is much larger, you’ll find a blurry image. Why is that? It’s because our sprite uses bitmap graphics with a fixed resolution. Scaling such images always degrades performance to some extent even with the best scaling algorithms.

The solution to this problem is using responsive graphics. Android provides a mechanism called “resource qualifiers” to attack this issue. You can simply provide different resource folders corresponding to different screen resolutions (or other device characteristics), and include screen-specific graphics in them. There is a small problem with this approach. The main implication with this approach is APK size. If you include graphics for a varieties of resolutions, you will have lots of redundancy which adds to the size of your installation file. The other problem is that Android ecosystem accomodates potentially infinite screen sizes and resolutions, and you cannot accommodate all of them in your graphics. Even if you choose a representative set, you will find it hard to provide a consistent UI on all devices. Today we will discuss another approach.

Continue reading

Day 19: Our First Animation

What we have done so far in this tutorial series was to create an essential framework for displaying 2-dimensional texture graphics. Today we are going to see this framework in action.

Introduction

From day 4 we remember that the fundamental parts of our framework are stage, scenes, and sprites. We completed designing the Stage class last day. We saw that the stage can only have one scene at any given time. If our game has four main screens, then one of four scenes will be set as current according to our game’s logic:

Stage and Scenes

Continue reading

Day 18: Bringing It on Stage – Part 2

Today’s post is a short one, but it is one of the key days of this tutorial. After today, we are going to have enough code to build an actual working app. On day 17, we saw how to separate rendering and animation handling. Today we are going to add the rendering code.

Drawing the Scene

If you have followed the series up to here, you have already written all the rendering code in Texture and related classes. The scenes are also self-drawing. All you need to do from stage is to call the rendering method on the appropriate scene.

Yesterday we cleared the content of onDrawFrame in Stage. Now we can add what we just discussed.

public final void onDrawFrame(GL10 gl) {
    gl.glClearColor(0, 0, 0, 1.0f);
    gl.glClear(GLES10.GL_COLOR_BUFFER_BIT);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

    if(currentScene != null) {
        if(!currentScene.isLoaded())
            currentScene.onLoaded();

        currentScene.render(gl);
    }
}

Continue reading

Concurrent Collection

This post is not directly related to GDD, but I thought it could be useful for some. Java’s ArrayList and LinkedList are fail-fast. That means that trying to modify them from one thread while accessing them from another will cause them to throw a ConcurrentModificationException. Java has some concurrent data structures in java.util.concurrent. But most of them are based on creating a second copy of the underlying data on modification. While this is completely thread-safe, it might not be the best option when you have a large amount of data stored.

As part of Artenus, I have developed a concurrent collection that does modify and access the same data without duplication. This of course comes at the cost of occasional errors caused by inconsistency of the list. But most of the time it works correctly. If you need a data structure that you can use to manipulate large number of elements in concurrent threads, this could be an option. But be careful to handle the edge cases gracefully. Full documentation of this class can be found here.

Continue reading

Day 17: Bringing It on Stage – Part 1

Stage is the graphical front-end of our system. It handles OpenGL ES life cycle, and maintains the game flow. Today we start building upon Stage.java of day 6. However, since the implementation is lengthy, we only cover animation handling and how it is incorporated into the stage. Graphical aspects of this class will be discussed next day.

Animation handling

Stage is an interface between our graphical data structures and the OpenGL ES API (which is called EGL). Scenes are added to it, and it has to render and animate them in a fail-safe manner.

In day 16 we added a method called advance to the Scene class, the purpose of which was to advance or increment animations on every sprite. The question we would like to answer today is when and how this method is called.

A naive implementation would call the advance method in onDrawFrame, where the renderer is called to render the scene. To see why this is a bad practice, we should consider some facts:

  1. Rendering is handled by OpenGL ES on a thread dedicated for this purpose. And it is best to keep it this way.
  2. Advancing animations can become a lengthy task as our scenes grow in complexity. When the frame is ready to render, it is already too late to start processing it. It will cause hiccups or stutter in the animation.
  3. OpenGL draws frames at the highest frequency it physically can. By default, rendering is performed whenever the OpenGL is ready to draw, and the rate it is called at it not deterministic (this rate is well known as FPS or frames per second).

Continue reading