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