
How I wrote a physical puzzle in Libgdx
Hello!
A screenshot for the seed:

Somehow aimlessly sitting on the Internet I came across the game "Chains, Balls and Zombies . " I don’t know why, but she strongly hooked me. Simple and at the same time interesting gameplay and some non-linearity - levels can be completed in several ways. In some ways, she reminded me of the notorious Crazy Machines, which I also once suffered from.
Having killed the zombies, I got the idea to write my own game - withpoets and preference balls and zombies, only better (you can rob corovans) . No sooner said than done. As a result of a couple of weeks, the game was made, and posted on Google Play. If you are interested in knowing more in detail - I ask for a cat.
For several years now I have been writing games for mobile devices on Android. I use the libGDX engine. Before that, I tried AndEngine, and even wrote a prototype of a small toy on it - but then I moved to libGDX, about which I do not regret now. The main feature is the ability to write and debug code on the desktop, and then transfer the game to Android with minimal changes. It turns out quickly and pleasantly, no need to wait for the buggy and slow emulator to start. Therefore, it is quite logical that I chose this engine for writing the game.
As you know, it all starts with an idea. In my case, the ideological inspirers were the games “Chains, Balls and Zombies”, “Crazy machines” (very mediocre to this game), “Stupid zombies”. The goal of the game in a nutshell - using all the means at hand, destroy all the zombies on the level. Heavy metal balls suspended on chains, bombs, boxes, boards, mines, car wheels acted as improvised means. Cutting the chain, you drop the ball on the zombies - profit, the green creature is dead. In more complicated versions, you need to detonate bombs and cut chains at the right time - there is an arcade element. To make it more fun, time is ticking in the game - the faster you complete the level, the more stars you get.
I decided to name the game Ugly Zombies - a kind of reference and an attempt to play on Stupid Zombies.

Typical gameplay - re-run chains, roll bombs to boxes, undermine, explosions, boxes kill zombies.
Video games:
Structurally, the game is divided into "Menu" and "Game". From the “Menu” we can get to the “Box Screen”, and from there - to the “Level Screen”. You can also get to the “Shop” from the menu. That is, the structure is traditional - in the game there are 4 boxes, each box has 18 levels (grid 6 * 3). The level becomes available only after passing the previous one. In the store, we can buy additional levels (more will be explained in more detail) and disable ads.

Box selection example. Each box is unique (its own picture and animation)
Actually, all control in the game comes down to cutting chains and clicking on bombs. In the first version, when I debugged the game on the desktop, I removed the chains and detonated the bombs by clicking. Then I launched the game on the phone - and that was bad. Chains were cut through once, and bombs were not detonated. I scratched my head, and changed the behavior from a click to a touch (that is, they touched, had not yet taken their finger off the screen, but the action had happened). It helped, but not much. The desktop was fine, but the phone was still bad. The small screen made the controls uncomfortable. It was necessary to do something.
Then an idea came to my mind - and if you cut, you can cut! I mean, swipe across the screen - this is it, we do, as in Fruit Ninja. I did, tried - yes, that was it! True, the bombs were still blown up the same way. After a while, I did a bombing on a swipe too - it was more convenient. There is some evidence of ease of management and clarity of the game - I gave my ten-year-old nephew to play a draft version of the game, he went through one and a half boxes in an hour. I really have nothing to compare with, but at least an adult should understand the game without any problems.
Art in the game was prefabricated. I took the interface for the menu from the free set that I dig on the Internet. I was still surprised that such a good casual set, and free. As expected free graphics, it was missing. Therefore, using Gimpand strictly censored words , I drew on the basis of the downloaded pack the rest of the graphics for the menu. Here is the main menu of the game:

I did the graphics for the game screen partly by myself, partially took from the Internet. Boards are drawn in Gimp, boxes are taken from OpenGameArt.org, bombs, wheels, zombies are safely downloaded from the Internet. The same applies to the game background. All pictures were post-processed - placed on a transparent background, cropped, resized.
As for the zombies, it was more difficult with him. I downloaded the whole picture, and cut it into pieces - because I still had to make a Ragdoll from this picture. Zombies were the most difficult and painful part, and I think that this is the least developed part of the game. The lack of the artist greatly affected the graphic component of the game. My girlfriend said that the game looks nice - but she could not say otherwise :)
I also drew the graphics for Google Play (the icon and the promo picture) myself, in Gimp. Using torture and trial, this was created:

I recorded the video for Youtube with the vokoscreen program, then edited (cut out the necessary and inserted the music) with the OpenShot Video Editor program. Before that, I tried Avidemux (I used it before), and LiVES - but both crashed when I tried to export the video. But OpenShot managed, despite its crooked control.
Perhaps the issue of graphics on this can be closed. Graphics is a painful process for me, the lack of an artist taught me the basic principles of working in Gimp, and the realization of my own imperfection.
Sounds were partially taken from OpenGameArt.org, partially torn out of the above flash game. To unpack the flash, I used some kind of program written in Java, I don’t remember the name, if someone would be interested, I’ll look. The winning sound (gong) was found on the Internet, cut in Audacity. Sounds of great tension did not cause, especially since there were relatively few of them, a dozen.
I found music on OpenGameArt.org. I found a peppy rock track that, according to me, fit in well with the game (I was lying on the couch playing a toy with this music). In general, there was no big problem with music either. It would have been better to loop it, but my knowledge in Audacity was not enough, and I decided not to bother - especially since this would not greatly affect the gameplay.
Let's move on to the most interesting code for programmers.
The game was written in Eclipse, I used my own add-in engine over libGDX - DDE (Dark Dream Engine). From the capabilities of my engine:
- visual editing of screens (greatly accelerated development);
- convenient access to resources (sounds, graphics) - just put them in the right folders, then they are loaded themselves. Moreover, resource loading is “lazy" - if we access the resource, and it is not loaded yet - it is loaded, cached, and returned;
- support for extensions (in fact, the visual editor of screens - this is the extension)
- a convenient start panel where you can select the resolution of the game to start - conveniently test multi-screen;
- the ability to export apk and application desktop from the start panel - once you have configured all the parameters, then only click "Collect". It works crookedly, so I did not use it.
“... and many more goodies.” I posted the draft version on GitHub, but that was a long time ago and not true. As time appears, I want to finish DDE to a human kind, and write a series of tutorials - I used it in several projects, it's still convenient.
For physics, as expected, I used Box2D - it is very well integrated into libGDX, there were no questions about it. For debugging, I used the Box2dDebugRenderer class - it allows you to visualize physical bodies with lines on the screen.
Structurally, the game is divided into the following parts:
- The main controller class - I called it Zombie. This is a singleton that stores links to all resources. It is accessible from anywhere. You might think this is a God Object - but it is not. This is a simple class of 135 lines, 90% of which are getters and setters. I bring the entire class code so that you understand what I mean:
Further there was a division into resource managers. A resource is almost everything in a game. This is sound, music, textures, screens - everything that can be divided into parts and edited. Thus, there is a sound manager, texture manager, screen manager.
Some details about the screen. One screen is one class.
Screenshot of the store screen:

And here is the screen code for the class of the store:
As you can see, the code is quite short. I will not explain it in detail, only a couple of points.
1)
2)
That is, the creation of such routine operations was automated with me, which allowed me to concentrate more on the game.
What a game without sweets! By them I mean small decorations that allow you to visually “revive” the game. I made several of these pieces, their description below.
Animated Boxes. Each box should be “live” - this will create a feeling of elaboration of the game. Therefore, each one has a unique drawing with simple animation - the hand increases / decreases, the skull blinks, the bomb rotates, and the star rotates in a top. These are very simple effects, which it is a pleasure to do with libGDX thanks to its developed Actions system. For example, the code for adding a blinking animation to the skull is
Animated dialogs. The game has several dialog boxes - winning, buying levels, etc. Just showing them was ugly - with two lines of code we make an animated appearance / close. The code, again, is as simple as possible (showing \ closing the purchase window) -
To store the settings, I selected a separate class - Settings. Access to this class can be obtained through the Zombie class. Turning on / off music, buying levels, turning off ads - this is what he does.
To interact with Android code from the main project, I created an interface (in Java terms), implemented it in the Android part, and transferred it to the main project. Interface Code -
As you can see, just a set of methods without parameters. All details are implemented in the Android part, in the desktop project only stubs.
The game screen was more complicated for the rest. I divided it into HUD and physical. model. The physical model was called Model.java. An abstraction was introduced - GameObject. This same GameObject contained a physical body, a sprite for rendering, and an update () method for rendering a sprite. The model managed objects - adding, deleting, calling update (), start \ stop nat. the world is all she is. A kind of manager turned out.
To implement various objects - balls, boxes, etc. - subclasses of GameObject were created. An ObjectLoader was created that was able to load GameObjects. Thus, if I wanted to add a new object - I did a subclass from GameObject, and a subclass from ObjectLoader. Perhaps this is a bit of an overhead, but this allowed us to keep the game screen and model relatively clean - only the number of relatively small classes grew.
To create levels, a level editor was created. Written in Java, good old Swing. The levels are stored in JSON, the weight of one level is about 2 kilobytes. Using the built-in JSON-worker in libGDX, I loaded \ saved levels from a file with one line.
If I did all 72 levels manually, I would go crazy, I suspect. Those who make games with levels - it makes sense to think about creating an editor as early as possible, then there will be less hemorrhoids. This is probably a common truth, but still.
There are quite a few left overboard - a description of the handling of physical collisions, the creation of a ragdoll, adaptation to different screen resolutions - but this will draw on an article, and not even one. If someone will be interested - write in the comments, I can paint something. And we move on.
Like any person, I want to eat. Therefore, I thought about at least some income from the game. After reading articles on the Internet, I decided to monetize with advertising and in-game purchases.
Advertising. The banner below (not visible on the game screen), and interstitial announcements on the winning screen (interstitial ad). Advertising can be turned off for one dollar.
Buying levels. Initially, two boxes are available in the game - this is half the levels. The rest costs $ 1.99. I took prices "from the ceiling", I would be glad to hear in the comments reviews on this subject from knowledgeable people.
Basically, that’s all monetization. When you click on a closed box, an offer to purchase boxes appears, and there is also a separate store screen, which is accessible from the main menu. I do not have much experience in this area, again I would be glad to read the comments of people who are doing this professionally.
I did not do any localization. The game has a minimum of text, and I thought that these were unjustified costs. Therefore, as the game was originally in English, it remained.
I did not make much progress. Post here (without a link, who cares - write in a personal email, drop it). Post on w3bsit3-dns.com, on the site libGDX, on the site gcup.ru. I plan to multiply more on the forums. Of course I’ll post it on my blog (I don’t know if it’s possible to specify a link here. My blog is non-commercial, there is no advertisement there. I have a blog on the game building, there are quite a lot on libGDX). I will be glad to advice from knowledgeable people.
I posted the game on Google Play. In principle, there is no great difficulty in assembling the desktop version - just where to put it and why - I do not know. If someone can tell if it makes sense to do this, I will be very grateful
The game took several weeks. The main work was done in a week - from eight in the evening to three in the morning. Motivation is very important. If you are set to work, you do everything very quickly.
It is very good if the team has an artist. Otherwise, sites with free resources for games are your everything. Owning Gimp or Photoshop is a very good help. This also includes ownership of audio and video editors.
This game is my trial project. I wonder if there will be some kind of exhaust from it, some kind of popularity. So to speak, I carefully try the heel of the water - is it cold? I am pleased to listen to your comments, I welcome the discussion on this subject.
It seems like everyone. Waiting for feedback!
UPD: Added a video from the game at the beginning
A screenshot for the seed:

Somehow aimlessly sitting on the Internet I came across the game "Chains, Balls and Zombies . " I don’t know why, but she strongly hooked me. Simple and at the same time interesting gameplay and some non-linearity - levels can be completed in several ways. In some ways, she reminded me of the notorious Crazy Machines, which I also once suffered from.
Having killed the zombies, I got the idea to write my own game - with
For several years now I have been writing games for mobile devices on Android. I use the libGDX engine. Before that, I tried AndEngine, and even wrote a prototype of a small toy on it - but then I moved to libGDX, about which I do not regret now. The main feature is the ability to write and debug code on the desktop, and then transfer the game to Android with minimal changes. It turns out quickly and pleasantly, no need to wait for the buggy and slow emulator to start. Therefore, it is quite logical that I chose this engine for writing the game.
Idea
As you know, it all starts with an idea. In my case, the ideological inspirers were the games “Chains, Balls and Zombies”, “Crazy machines” (very mediocre to this game), “Stupid zombies”. The goal of the game in a nutshell - using all the means at hand, destroy all the zombies on the level. Heavy metal balls suspended on chains, bombs, boxes, boards, mines, car wheels acted as improvised means. Cutting the chain, you drop the ball on the zombies - profit, the green creature is dead. In more complicated versions, you need to detonate bombs and cut chains at the right time - there is an arcade element. To make it more fun, time is ticking in the game - the faster you complete the level, the more stars you get.
I decided to name the game Ugly Zombies - a kind of reference and an attempt to play on Stupid Zombies.

Typical gameplay - re-run chains, roll bombs to boxes, undermine, explosions, boxes kill zombies.
Video games:
Game structure
Structurally, the game is divided into "Menu" and "Game". From the “Menu” we can get to the “Box Screen”, and from there - to the “Level Screen”. You can also get to the “Shop” from the menu. That is, the structure is traditional - in the game there are 4 boxes, each box has 18 levels (grid 6 * 3). The level becomes available only after passing the previous one. In the store, we can buy additional levels (more will be explained in more detail) and disable ads.

Box selection example. Each box is unique (its own picture and animation)
Control
Actually, all control in the game comes down to cutting chains and clicking on bombs. In the first version, when I debugged the game on the desktop, I removed the chains and detonated the bombs by clicking. Then I launched the game on the phone - and that was bad. Chains were cut through once, and bombs were not detonated. I scratched my head, and changed the behavior from a click to a touch (that is, they touched, had not yet taken their finger off the screen, but the action had happened). It helped, but not much. The desktop was fine, but the phone was still bad. The small screen made the controls uncomfortable. It was necessary to do something.
Then an idea came to my mind - and if you cut, you can cut! I mean, swipe across the screen - this is it, we do, as in Fruit Ninja. I did, tried - yes, that was it! True, the bombs were still blown up the same way. After a while, I did a bombing on a swipe too - it was more convenient. There is some evidence of ease of management and clarity of the game - I gave my ten-year-old nephew to play a draft version of the game, he went through one and a half boxes in an hour. I really have nothing to compare with, but at least an adult should understand the game without any problems.
Art
Art in the game was prefabricated. I took the interface for the menu from the free set that I dig on the Internet. I was still surprised that such a good casual set, and free. As expected free graphics, it was missing. Therefore, using Gimp

I did the graphics for the game screen partly by myself, partially took from the Internet. Boards are drawn in Gimp, boxes are taken from OpenGameArt.org, bombs, wheels, zombies are safely downloaded from the Internet. The same applies to the game background. All pictures were post-processed - placed on a transparent background, cropped, resized.
As for the zombies, it was more difficult with him. I downloaded the whole picture, and cut it into pieces - because I still had to make a Ragdoll from this picture. Zombies were the most difficult and painful part, and I think that this is the least developed part of the game. The lack of the artist greatly affected the graphic component of the game. My girlfriend said that the game looks nice - but she could not say otherwise :)
I also drew the graphics for Google Play (the icon and the promo picture) myself, in Gimp. Using torture and trial, this was created:

I recorded the video for Youtube with the vokoscreen program, then edited (cut out the necessary and inserted the music) with the OpenShot Video Editor program. Before that, I tried Avidemux (I used it before), and LiVES - but both crashed when I tried to export the video. But OpenShot managed, despite its crooked control.
Perhaps the issue of graphics on this can be closed. Graphics is a painful process for me, the lack of an artist taught me the basic principles of working in Gimp, and the realization of my own imperfection.
Sounds
Sounds were partially taken from OpenGameArt.org, partially torn out of the above flash game. To unpack the flash, I used some kind of program written in Java, I don’t remember the name, if someone would be interested, I’ll look. The winning sound (gong) was found on the Internet, cut in Audacity. Sounds of great tension did not cause, especially since there were relatively few of them, a dozen.
Music
I found music on OpenGameArt.org. I found a peppy rock track that, according to me, fit in well with the game (I was lying on the couch playing a toy with this music). In general, there was no big problem with music either. It would have been better to loop it, but my knowledge in Audacity was not enough, and I decided not to bother - especially since this would not greatly affect the gameplay.
The code
Let's move on to the most interesting code for programmers.
The game was written in Eclipse, I used my own add-in engine over libGDX - DDE (Dark Dream Engine). From the capabilities of my engine:
- visual editing of screens (greatly accelerated development);
- convenient access to resources (sounds, graphics) - just put them in the right folders, then they are loaded themselves. Moreover, resource loading is “lazy" - if we access the resource, and it is not loaded yet - it is loaded, cached, and returned;
- support for extensions (in fact, the visual editor of screens - this is the extension)
- a convenient start panel where you can select the resolution of the game to start - conveniently test multi-screen;
- the ability to export apk and application desktop from the start panel - once you have configured all the parameters, then only click "Collect". It works crookedly, so I did not use it.
“... and many more goodies.” I posted the draft version on GitHub, but that was a long time ago and not true. As time appears, I want to finish DDE to a human kind, and write a series of tutorials - I used it in several projects, it's still convenient.
For physics, as expected, I used Box2D - it is very well integrated into libGDX, there were no questions about it. For debugging, I used the Box2dDebugRenderer class - it allows you to visualize physical bodies with lines on the screen.
Structurally, the game is divided into the following parts:
- The main controller class - I called it Zombie. This is a singleton that stores links to all resources. It is accessible from anywhere. You might think this is a God Object - but it is not. This is a simple class of 135 lines, 90% of which are getters and setters. I bring the entire class code so that you understand what I mean:
Zombie.java
package ua.com.integer.labs.zombie;
import ua.com.integer.dde.kernel.DDKernel;
import ua.com.integer.dde.res.screen.AbstractScreen;
import ua.com.integer.dde.res.sound.SoundManager;
import ua.com.integer.labs.zombie.screen.LoadingScreen;
import ua.com.integer.labs.zombie.screen.game.GameController;
import ua.com.integer.labs.zombie.screen.game.Level;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.Logger;
public class Zombie extends DDKernel {
private static Zombie instance = new Zombie();
private SpriteBatch spriteBatch;
private ShapeRenderer sRenderer;
private Settings sets;
private Level level;
private Sounds sounds;
private GameController gameController;
private PlatformInterface platformInterface;
private Zombie() {
getConfig().relativeDirectory = "../zombie-android/assets/";
}
public static Zombie getInstance() {
return instance;
}
@Override
public void create() {
super.create();
getResourceManager().getManager(SoundManager.class).loadAll();
Gdx.app.setLogLevel(Logger.DEBUG);
gameController = new GameController();
sets = new Settings();
sounds = new Sounds();
spriteBatch = new SpriteBatch();
AbstractScreen.batch = spriteBatch;
sRenderer = new ShapeRenderer();
showScreen(LoadingScreen.class);
}
@Override
public void dispose() {
super.dispose();
getResourceManager().dispose();
sRenderer.dispose();
}
public void setPlayLevel(Level level) {
this.level = level;
}
public Level getLevel() {
return level;
}
public ShapeRenderer getShapeRenderer() {
return sRenderer;
}
public Settings getSettings() {
return sets;
}
public void setPlatformInterface(PlatformInterface platformInterface) {
this.platformInterface = platformInterface;
}
public PlatformInterface getPlatformInterface() {
if (platformInterface == null) {
platformInterface = new PlatformInterface() {
@Override
public void showAds() {
System.out.println("Show ads.");
}
@Override
public void hideAds() {
System.out.println("Hide ads.");
}
@Override
public void buyUnlockAds() {
System.out.println("Buy unlock ads.");
}
@Override
public void buyLevels() {
sets.setBoxesOpened(true);
System.out.println("Buy levels.");
}
@Override
public void showInterstitial() {
System.out.println("Show interstitial!");
}
@Override
public void rateForGame() {
System.out.println("Rate for game");
}
@Override
public void shareViaFacebook() {
System.out.println("Share via facebook");
}
@Override
public void shareViaTwitter() {
System.out.println("Share via twitter");
}
@Override
public void updatePurchases() {
System.out.println("Update purchase state");
}
};
}
return platformInterface;
}
public GameController getGameController() {
return gameController;
}
public Sounds getSounds() {
return sounds;
}
}
Further there was a division into resource managers. A resource is almost everything in a game. This is sound, music, textures, screens - everything that can be divided into parts and edited. Thus, there is a sound manager, texture manager, screen manager.
Some details about the screen. One screen is one class.
Screenshot of the store screen:

And here is the screen code for the class of the store:
StoreScreen.java
package ua.com.integer.labs.zombie.screen.menu;
public class StoreScreen extends AbstractScreen {
public StoreScreen() {
addScreenEventListener(new ScreenListener() {
@Override
public void eventHappened(AbstractScreen screen, ScreenEvent event) {
switch(event) {
case SHOW:
findByName("all-boxes").setVisible(!Zombie.getInstance().getSettings().isBoxesOpened());
findByName("no-ads").setVisible(!Zombie.getInstance().getSettings().isAdwareDisabled());
break;
case BACK_OR_ESCAPE_PRESSED:
getKernel().showScreen(MenuScreen.class);
break;
default:
break;
}
}
});
ActorUtils.deployConfigToScreen(this, Actors.getInstance().getConfig("store-screen"));
findByName("back-button").addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Zombie.getInstance().getSounds().playClick();
getKernel().showScreen(MenuScreen.class);
}
});
findByName("all-boxes").addListener(new ScaleActorListener(0.05f).setTime(0.1f));
findByName("all-boxes").addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Zombie.getInstance().getSounds().playClick();
Zombie.getInstance().getPlatformInterface().buyLevels();
}
});
findByName("no-ads").addListener(new ScaleActorListener(0.05f).setTime(0.1f));
findByName("no-ads").addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Zombie.getInstance().getSounds().playClick();
Zombie.getInstance().getPlatformInterface().buyUnlockAds();
}
});
}
}
As you can see, the code is quite short. I will not explain it in detail, only a couple of points.
1)
ActorUtils.deployConfigToScreen(this, Actors.getInstance().getConfig("store-screen"));
- expand the screen config (I have my own screen editor, remember?). Background, buttons - it all hangs visually, this line does the rest. 2)
findByName("all-boxes").addListener(new ClickListener()...
- find the object with the specified name and assign a handler to it. The name of the object (actor, in libGDX terminology) we specify in the interface editor. That is, the creation of such routine operations was automated with me, which allowed me to concentrate more on the game.
Snacks
What a game without sweets! By them I mean small decorations that allow you to visually “revive” the game. I made several of these pieces, their description below.
Animated Boxes. Each box should be “live” - this will create a feeling of elaboration of the game. Therefore, each one has a unique drawing with simple animation - the hand increases / decreases, the skull blinks, the bomb rotates, and the star rotates in a top. These are very simple effects, which it is a pleasure to do with libGDX thanks to its developed Actions system. For example, the code for adding a blinking animation to the skull is
findByName("head-item").addAction(Actions.forever(Actions.sequence(Actions.color(Color.WHITE, 0.4f), Actions.color(Color.BLACK, 0.4f))));
Animated dialogs. The game has several dialog boxes - winning, buying levels, etc. Just showing them was ugly - with two lines of code we make an animated appearance / close. The code, again, is as simple as possible (showing \ closing the purchase window) -
private void hideBuyDialog() {
Actor dialogContent = findByName("dialog-content");
if (dialogContent != null) {
findByName("dialog-content").addAction(Actions.scaleTo(0f, 0f, 0.1f));
}
}
private void showBuyDialog() {
Actor dialogContent = findByName("dialog-content");
if (dialogContent != null) {
dialogContent.addAction(Actions.scaleTo(1f, 1f, 0.1f));
}
}
To store the settings, I selected a separate class - Settings. Access to this class can be obtained through the Zombie class. Turning on / off music, buying levels, turning off ads - this is what he does.
To interact with Android code from the main project, I created an interface (in Java terms), implemented it in the Android part, and transferred it to the main project. Interface Code -
package ua.com.integer.labs.zombie;
public interface PlatformInterface {
public void buyLevels();
public void buyUnlockAds();
public void showAds();
public void hideAds();
public void showInterstitial();
public void rateForGame();
public void shareViaFacebook();
public void shareViaTwitter();
public void updatePurchases();
}
As you can see, just a set of methods without parameters. All details are implemented in the Android part, in the desktop project only stubs.
Game screen
The game screen was more complicated for the rest. I divided it into HUD and physical. model. The physical model was called Model.java. An abstraction was introduced - GameObject. This same GameObject contained a physical body, a sprite for rendering, and an update () method for rendering a sprite. The model managed objects - adding, deleting, calling update (), start \ stop nat. the world is all she is. A kind of manager turned out.
To implement various objects - balls, boxes, etc. - subclasses of GameObject were created. An ObjectLoader was created that was able to load GameObjects. Thus, if I wanted to add a new object - I did a subclass from GameObject, and a subclass from ObjectLoader. Perhaps this is a bit of an overhead, but this allowed us to keep the game screen and model relatively clean - only the number of relatively small classes grew.
To create levels, a level editor was created. Written in Java, good old Swing. The levels are stored in JSON, the weight of one level is about 2 kilobytes. Using the built-in JSON-worker in libGDX, I loaded \ saved levels from a file with one line.
If I did all 72 levels manually, I would go crazy, I suspect. Those who make games with levels - it makes sense to think about creating an editor as early as possible, then there will be less hemorrhoids. This is probably a common truth, but still.
There are quite a few left overboard - a description of the handling of physical collisions, the creation of a ragdoll, adaptation to different screen resolutions - but this will draw on an article, and not even one. If someone will be interested - write in the comments, I can paint something. And we move on.
Monetization
Like any person, I want to eat. Therefore, I thought about at least some income from the game. After reading articles on the Internet, I decided to monetize with advertising and in-game purchases.
Advertising. The banner below (not visible on the game screen), and interstitial announcements on the winning screen (interstitial ad). Advertising can be turned off for one dollar.
Buying levels. Initially, two boxes are available in the game - this is half the levels. The rest costs $ 1.99. I took prices "from the ceiling", I would be glad to hear in the comments reviews on this subject from knowledgeable people.
Basically, that’s all monetization. When you click on a closed box, an offer to purchase boxes appears, and there is also a separate store screen, which is accessible from the main menu. I do not have much experience in this area, again I would be glad to read the comments of people who are doing this professionally.
Localization
I did not do any localization. The game has a minimum of text, and I thought that these were unjustified costs. Therefore, as the game was originally in English, it remained.
Promotion
I did not make much progress. Post here (without a link, who cares - write in a personal email, drop it). Post on w3bsit3-dns.com, on the site libGDX, on the site gcup.ru. I plan to multiply more on the forums. Of course I’ll post it on my blog (I don’t know if it’s possible to specify a link here. My blog is non-commercial, there is no advertisement there. I have a blog on the game building, there are quite a lot on libGDX). I will be glad to advice from knowledgeable people.
I posted the game on Google Play. In principle, there is no great difficulty in assembling the desktop version - just where to put it and why - I do not know. If someone can tell if it makes sense to do this, I will be very grateful
conclusions
The game took several weeks. The main work was done in a week - from eight in the evening to three in the morning. Motivation is very important. If you are set to work, you do everything very quickly.
It is very good if the team has an artist. Otherwise, sites with free resources for games are your everything. Owning Gimp or Photoshop is a very good help. This also includes ownership of audio and video editors.
This game is my trial project. I wonder if there will be some kind of exhaust from it, some kind of popularity. So to speak, I carefully try the heel of the water - is it cold? I am pleased to listen to your comments, I welcome the discussion on this subject.
It seems like everyone. Waiting for feedback!
UPD: Added a video from the game at the beginning