[libGDX] Experience developing a game using Box2D

  • Tutorial
Hello, Habr! Wow For a long time I did not write here. So, perhaps I’ll start with a little background and at the same time I will give a screenshot of the resulting game.

TOTAL100
Gameplay screenshot

Note: the article is for beginners, however, if you are a guru and saw a mistake in the author's judgments / code, then please write about this in the PM or in the comments. And I will add them to the article.


Background


The last year I worked as a web programmer in Python. I can’t say that I didn’t like it, but my soul wanted creativity / independence / change / success (emphasize yours, indie game developers). And there was time to write something of their own in the evenings, but it still did not grow up to anything at least a little meaningful (due to banal fatigue and the desire to spend time separately from the computer).
But suddenly, an opportunity loomed on the horizon. I and a couple of friends decided to make my project. The idea was painted, presentations were made, charts were drawn, the development environment was launched, but only one thing was missing - the investor. There wasn’t very much money (by ordinary standards), but we still couldn’t find an interested person “with the money”. Well, I thought, if so, then it is time to free your imagination and put it into the development of some small , but proud game. About this and the further article.

Idea


I intentionally tried not to take someone’s idea or just copy the finished one. The original idea was simply to drop balls of different colors on walls of the same color and keep score. But having made the first version of the game, I realized that it is boring and has never been addictive. Then I got the idea to make numbers with different signs (plus, minus), instead of balls and add “hateful zero” (c) , resetting all the player’s points.
Then I realized that the player needed to be somehow limited and added a timer. Then, I added levels (although I initially wanted to make just a high score table). The levels had to get complicated somehow, so I added obstacles in the form of walls and platforms. Toward the end of the development, I thought that special rights should be given to zero and made it invulnerable to walls and platforms, which made my “home testers” very angry and extremely amusing to me.

image
Screenshot of the main menu of the game

The timing


Since my free time could "run out" at any moment, I decided to set a goal - to write a game in a week. This goal I have achieved. The game, of course, is still damp, but still in the market and it makes me happy.

Implementation


To implement my ideas, I chose my favorite libGDX framework, which is well integrated with the box2D physics engine. In general, libGDX is great. He has really good documentation, which helped me in 80% of cases, and stackoverflow helped in 20%. Also, it now integrates perfectly with Android Studio (previously could not), which again adds a plus to it. The resulting applications are very, very light (in contrast to the same Unity3D) and quite stable (if the hands are not crooked, like mine :)).

Problems


Problems are of course a big word, but I will write here about several problems that have arisen, which took away a lot of my nerves and time.

  1. The physical world. Honestly, I do not know how I could have missed this point in the documentation (it is described in the code), but for a long time I could not understand why my physical bodies are so slow. The problem was that I indicated camera sizes equal to screen size:
    // Я писал так
    box2DCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    // А надо было например так. 14 -- это число, которое меня устроило. scrWidth и scrHeight -- это размеры экрана. Такая формула позволяет запускать данный код на любом экране и всё растянется пропорционально
    box2dCamera = new OrthographicCamera(14 * (scrWidth / scrHeight), 14);
    

  2. Sprites / Images. If you work with a physical engine, then the image sizes and their positions must be set based on several parameters:
    sprite = new Sprite("your_sprite");
    sprite.setBounds(body.getPosition().x / 2f, body.getPosition().y / 2f, radius, radius); // в моём примере я тело было круглым, поэтому здесь два раза повторяется radius.
    sprite.setOrigin(sprite.getWidth() / 2f, sprite.getHeight() / 2f);
    

  3. Rotation of objects and sprites. If you want to rotate the physical body, then just passing the value of the angle to the sprite you will not get anything good. It is necessary to convert the value from radians to degrees:
    sprite.setRotation(MathUtils.radiansToDegrees * body.getAngle());
    

  4. There were still moments with dispose () for texture objects and other graphics. The fact is that (and this is described in the documentation, but I did not read it well) if you use AssetManager , then in no case do dispose () a separate texture obtained from the manager, as it will delete it and later you will see black a spot instead of a graphic object.
  5. There were also many mats with the removal of an object from the physical world. The solution is googled, but I will give an example here:
    Iterator i = gameObjects.iterator();
    while (i.hasNext()) {
        GameObject object = i.next();
        if (!world.isLocked()) { // ВАЖНО! Если не сделать эту проверку, то получите ошибку. Так мы проверяем, можно ли удалить объект или он как-то используется в мире (коллизии и т.п.)
            object.getBody().setActive(false);
            if (mouseJoint == null) { // Это проверка на касание объекта. mouseJoint -- это захваченное тело при событии TouchDown
                world.destroyBody(object.getBody());
                i.remove();
            }
        }
    }
    


It seems to be all the problems that I encountered during development. Write in the comments about your problems, maybe something will help.

Some tips


  1. Obfuscation and minification. Before that, I had never obfuscated the code, but then I decided to try it. And you know, I liked it! Before the obfuscation, the game weighed 4.8 mb , and after its weight decreased to 3.7 mb. Draw your own conclusions. Moreover, this is done simply, because now ProGuard comes by default with the Android SDK and is included in a couple of lines of code:

    File android / build.gradle
    android {
        ...
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
            }
        }
    }
    

    Android / project.properties file
    // Раскомментируйте эту строчку
    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    

  2. Do not use the Nearest filter (I'm talking about textures). By default, TexturePacker applies the filter Nearest, Nearest . It is better to replace it with Linear, Linear or MipMap, MipMap . So everything will be smoother, even if you can not guess with the size of the pictures.
  3. More about textures. You do not need to make them as large as possible, and then reduce them using setSize () or setScale () . The output may produce a blurry image.


Graphics and Sound


I took the main font in Google Fonts , the rest of the elements I either drew myself in Inkscape , or took free icons and some rules for them.
As for the sounds, I took something from freesound , I did something myself in LMMS . It turned out quite tolerably. By the way, in the next update I want to add background music, which I just intended to do in LMMS. I liked the program. Strongly reminiscent of Fruity Loops Studio.

TOTAL100
Levels screenshot

Monetization


So far, I decided to post one free version with "interstitial" Admob ads . Then, if the audience likes the game, I’ll introduce the opportunity to turn off ads, as well as additional levels for “coins”.

Promotion


This is the most boring and not interesting lesson of all, so I decided that I would publish it on 5-10 resources and that's enough. Maybe if the product is interesting, he will find his own audience? (dreams ...) . I would like to read in the comments how best (and preferably inexpensively) to promote my product. And then most of the articles on this topic are either custom-made or simply outdated.

Total


I laid out the game recently, so it's too early to talk about anything. However, I learned a lot during the development of the game and the experience gained can be applied to future projects.

In a week or two I’ll update the article and attach the graphics of downloads / profit from advertising. Thanks for reading!

Also popular now: