📜 ⬆️ ⬇️

[libGDX] Experience developing a game using Box2D

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 bring a screenshot of the resulting game.

TOTAL100
Screenshot gameplay

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


Prehistory


All last year I have been working as a web programmer in Python. I will not say that I did not like it, but my soul wanted creativity / independence / change / success (underline your indie game developers). And there was a time to write something different in the evenings, but it didn’t grow up to something even slightly meaningful (due to the banal fatigue and the desire to spend time separately from the computer).
But suddenly, on the horizon, an opportunity loomed. I and a couple of friends decided to make their project. The idea was painted, presentations were made, graphics were drawn, the development environment was launched, but only one was missing - an investor. We didn’t need a lot of money (by usual measures), but we still couldn’t find an interested person "at the money." Well, I thought, if so, then it would be time to free your imagination and put it into the development of some small , but proud game. About this and further article.
')

Idea


I deliberately tried not to take someone’s idea, or simply to copy what was already ready. The original idea was to simply throw balls of different colors onto the walls of the same color and score. But having made the first version of the game, I realized that it is boring and never delays. It was then that I got the idea to make the numbers with different signs (plus, minus), instead of the balls, and add “hateful zero” (c) , zeroing all player points.
Then I realized that the player needed to be limited in some way and added a timer. Then, added levels (although, initially I wanted to make just a table of records). The levels had to be somehow complicated, so I added obstacles in the form of walls and platforms. Already towards the end of the development, I thought that zero should be given special rights and made it invulnerable to walls and platforms, which greatly angered my “home testers” and extremely amused me.

image
Screenshot of the main menu of the game

Timing


Since, at any time, my free time could “run out”, I decided to set myself a goal - to write a game in a week. I have achieved this goal. The game, of course, 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 beautiful. He has really good documentation that helped me out 80% of the time, and in 20% he helped stackoverflow. Also, it is now perfectly integrated with Android Studio (previously could not), which again adds a plus to it. The resulting applications are very, very light (as opposed to the same Unity3D) and fairly stable (if your hands are not crooked like mine :)).

Problems


Problems are certainly a rant, but I will write here about several problems that have arisen, which have taken away a lot of nerves and time from me.

  1. The physical world. Honestly, I don’t know how I could miss this moment in the documentation (it is described in the code), but for a long time I couldn’t understand why my physical bodies are so slow. The problem was that I indicated the camera dimensions equal to the 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 physics engine, then the sizes of images and their positions need to be set on the basis of 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 simply 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 also moments with dispose () on texture objects and other graphics. The fact is that (and this is described in the documentation, but I didn’t read it well) if you use AssetManager , then in no case do not dispose () a separate texture obtained from the manager, as it will delete it and later you will see black spot instead of a graphic object.
  5. There were also a lot of mats with the removal of the object from the physical world. The decision is googling, but I still give an example here:
     Iterator<GameObject> 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 while developing. Write in the comments about your problems, maybe something I will help.

Some tips


  1. Obfuscation and minification. Before that, I never obfuscated the code, but then I decided to try. And you know, I liked it! Before obfuscation, the game weighed 4.8 mb , and after that 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' } } } 

    File android / project.properties
     //    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 

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


Graphics and sound


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

TOTAL100
Level Screenshot Screenshot

Monetization


So far I have decided to post one free version with “interstitial” Admob ads. Then, if the game is popular with the public, I’ll introduce an opportunity to turn off advertising, as well as additional levels for the Coin.

Promotion


This is the most boring and not interesting occupation 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 audience? (dreams ...) . I would like to read in the comments how best (and preferably inexpensive) to promote your product. And most of the articles on this topic are either custom or simply outdated.

Total


I laid out the game quite 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.

After a week or two I will update the article and attach graphics downloads / profits from advertising. Thanks for reading!

Source: https://habr.com/ru/post/265815/


All Articles