Android Tutorial How to make games

Discussion in 'Tutorials & Examples' started by Informatix, Sep 12, 2013.

  1. Informatix

    Informatix Expert Licensed User

    How to make games

    A great idea, but a disappointing result

    You woke up one morning with a great idea for a game. You rushed to your phone to convince your best friend to do the artwork, your uncle to create sounds and music, and your sister to build a web site to promote your future success. Unfortunately, three weeks later, and after a few sleepless nights, you have to face reality: your game is crap. It has a nice concept, it is pretty, it has cool music and the screenshots are very engaging on the web site, BUT it is slow, it frequently has memory problems, it does not adapt well to different screen resolutions, the animations are choppy, the gameplay is poor, the special effects have been reduced to... none, the AI is dumb as a bag of hammers, the collision detection system is far from perfect (and maybe you do not even know what a collision detection system is), the sounds do not mix with the music and it is necessary to know a whole bunch of rules before playing. In short, it is probably time for you to read this tutorial.

    A few words about me

    I’m a professional developer and I made a few games in the 80’s, but I never worked in the game industry and my experience in creating games for Android is rather limited, so I don’t ask you to blindly trust my words in what follows. But I am passionate since long by games, how they are designed, the algorithms they use, how they solicit your imagination, what skills and tools they require, so I’m not without some knowledge in that domain. And my goal is less to explain you how to make a hit game (that I’ve never created myself) than to help you avoid the most common pitfalls and to give you some directions.

    What’s a game?

    From Wikipedia:
    “A game is structured playing, usually undertaken for enjoyment and sometimes used as an educational tool. Games are distinct from work, which is usually carried out for remuneration, and from art, which is more often an expression of aesthetic or ideological elements.
    […]
    Key components of games are goals, rules, challenge, and interaction. Games generally involve mental or physical stimulation, and often both.”

    As said above, your game must have goals and rules, and your player needs to know them when he/she’s playing. The goals have to be obvious or clearly explained at the beginning of the game: collect all gems, drive fast to be first, eat all food dots, kill all monsters, survive until dawn, etc. The rules can be explained along the way, with tutorials, panels between levels or help balloons, but they have to be explained and easy to remind. If your game has a steep learning curve or too many rules, it has a great chance to end in the depths of the Google Play Store. Having to read a book for playing a game is something to avoid in the Android market.

    Your game must propose progressive challenges, and that’s probably one of the most difficult tasks when you create a game. The game should be easy at the beginning to allow the player to become familiar with the controls, to fully understand the basic rules, to be in the mood... and the difficulty should increase regularly. Make it too difficult at start and you will discourage casual players. Make it too easy and it will look more like a demo than a game. Nowadays, this task is devoted to a specialist (the game designer, or level designer) in gaming companies and is considered as one of the keys to success, so don’t overlook it. Put your game in many different hands and observe how people play it. Make changes and test again. Take note of what people say. Don’t think you know better than everyone what is fun or cool in your game, and what’s challenging or not.

    Your game must be playable: the controls have to be easy to use, the controlled object has to react precisely and without delay, the secondary screens (e.g. the inventory or map screen) have to be accessed quickly, the menus have to be clear... It’s very frustrating when you lose because you were unable to move precisely your character or because you didn’t open the right screen on time to select a spell or a weapon. Any problem with the controls will increase the difficulty of your game. And keep in mind that your players are not as skilled as you are. You played many times to your game, they did not. So don’t expect they will master the controls very quickly, especially in a driving game where a small change of direction can make all the difference between success and failure.

    A game is a complex combination of goals, rules, challenges, graphics, audio, special effects, gameplay, controls, atmosphere, etc. and mixing all this to create something great is very difficult. Whatever your ambition is, you will see that creating a game is not the easiest work and takes a lot of time. You will face many technical and artistic problems, and maybe you’ll abandon more than one project before reaching your objective. So I hope that the following advices will speed up your development and prevent any bad choices.

    Prepare your work

    Coding a game is not really different from coding another type of application. You have to know what’s the result to obtain, what are the tools you need and how you are going to use them. So no surprise here:
    • Limit your dreams to the reality of your skills. Don’t imagine that your first game will compete with Riptide GP, Angry Birds or Ingress. It’s impossible. Start by a simple game, with simple rules, and if you’re successful, you will add complexity, special effects, new levels, etc.
    • Write the rules and the logic of your game, then translate them into pseudocode, and finally use this pseudocode to comment your classes and functions. That will make things clear and ease any future modification. Note that it’s mandatory if you want to work with a teammate.
    • Draw your game screens on paper. Things are usually very different in your mind and on the paper, with the right size. You will realize, for example, that a touchpad takes a lot of place or that it’s not a good idea to put the action button at the top because it is too far to be used quickly.
    • Collect tools, libraries, snippets of code and tutorials. If you don’t know how to do some parts of your game, learn by reading tutorials and books. If you don’t have the right tools, search them or write them. Become familiar with the numerous libraries of Basic4Android. It’s too bad when, in the middle of a development, you realize that you need a library which does not exist yet.

    Tools and libraries

    You could use only the standard libraries of Basic4Android to make a game but this game would be very limited. It is a lot easier and faster to create a game with the right tools. Here’s a selection of libraries at your disposal in February 2014:
    • Game engines: LibGDX, RSAndEngine.
    • Rendering: OpenGL, OpenGL2, jPCT-AE, GameView, Accelerated Surface, Game Sprite.
    • Animation: Animation, AnimationPlus, NineOldAndroids, TweenEngine.
    • Audio: MediaPlayer, SoundPool, AudioTrack, OpenSL.
    • Input: Gesture Detector, PhoneAccelerometer.
    • Artificial intelligence: SteeringBehaviors.
    • Physics: JBox2D, ABPhysics.
    • Files/data: JSON, SQL, XML, RandomAccessFile.
    • Networking/multiplayer: Network, HTTP, GamePlayServices.

    The libraries of the “game engine” category provide a framework to create various kinds of games. They include a rendering engine for 2D, a physics engine (Box2D), an audio engine, a tiled map renderer, a scene graph and a lot of helper classes to ease your burden. They should be your first choice.
    I’d recommend LibGDX because it has plenty of features and a very fast rendering engine, but it is a big fat baby (about 2.8 MB for the full version and 1.7 MB for the lite version), so you could prefer a combination of Accelerated Surface, Game Sprite or OpenGL with MediaPlayer, SoundPool and ABPhysics for a lightweight application.

    For 3D games, I’d recommend a combination of jPCT-AE + MediaPlayer + SoundPool.

    The LibGDX, RSAndEngine and jPCT-AE libraries belong to the OpenGL ES family. Their rendering engine makes an optimized use of the OpenGL ES library and fully benefits from the hardware acceleration.
    The GameView and Accelerated Surface libraries belong to the accelerated Canvas family. They call also the OpenGL ES methods, but without any optimization. They cannot be as fast as the libraries of the OpenGL ES family, and it’s worse with the Android versions prior to Honeycomb because they cannot benefit from the hardware acceleration.
    The Canvas class of Basic4Android belongs to the Skia Canvas family, which has many drawbacks and should not be used in a game.

    For a 2D game with two dozens of graphic objects on screen, it doesn’t matter if you choose a library of the OpenGL ES family or a library of the accelerated Canvas family. A few games have been created with the Accelerated Surface library and they didn’t exhibit a limited performance on most devices. But for games more demanding, for 3D or just for peace of mind, you should prefer a library of the OpenGL ES family.

    Beside the above libraries, you may find useful PreferenceActivity or AHPreferenceActivity to save the game options, ABExtDrawing to create or transform your bitmap images, AHLocale to translate your application to different languages, Threading to run subs on separate threads, and Reflection of course which gives a full access to the Android API.

    You will need also tools to create your images, your sounds, your animations, your 3D models... You have probably your preferences in each category. For Box2D, it exists two scene editors: the C2D scene editor, which is free, and R.U.B.E, which is well worth its price. If you have no artistic skill and no artist in your team, you may find graphic resources on deviantart.org or opengameart.org, and use Bfxr to generate sounds. For music, alas, you have to buy royalty-free songs or take music lessons.

    OpenGL ES

    As I explained, OpenGL ES (Open Graphics Library for Embedded Systems) is at the core of the best rendering engines so I’d like to give you a short introduction to this library.

    This library has been wrapped for Basic4Android and is named OpenGL for the version 1 and OpenGL2 for the version 2. The version 2 eliminates most of the fixed-function rendering pipeline in favor of a programmable one. Almost all rendering features of the transform and lighting stage, such as the specification of materials and light parameters formerly specified by the fixed-function API, are replaced by shaders written in GLSL, the shading language. As a result, OpenGL ES 2.0 is not backward compatible with OpenGL ES 1.1.

    Nowadays, almost all Android devices support OpenGL ES 1.1 and OpenGL ES 2.0, but the version 2 is more complex to learn than the version 1.x and doesn’t offer a significant increase in performance, so if you’re new to OpenGL, you should start with the version 1.1.

    Jelly Bean 4.3 introduced support for OpenGL ES 3 but this version is not yet available to Basic4Android users and needs devices with appropriate drivers.

    If you intend to use directly OpenGL ES, and not a library with higher level functions, be prepared for a serious headache because it’s a somewhat complex library. If you’re scared by geometry or by words like “frustum”, then OpenGL is maybe not for you. ;)

    There are a lot of tutorials on Internet devoted to OpenGL, so I won’t add one. Here’s just a list of the main features and things to know:
    • OpenGL is basically a triangle renderer. Thus, a rectangle drawn by OpenGL is made of two triangles. Each triangle is made of three points called vertices, which have a position in space: x, y, z.
    • Each rendered object has a geometry (a shape made of triangles), a set of colors, a texture (an image applied to its surface) and a material defining how this object interacts with light.
    • Objects are seen by a camera. The camera can move, rotate, and zoom in or out.
    • OpenGL constructs a 2D view of a 3D scene from the camera position. It uses one of the two available projections: parallel (the objects size is always the same regardless of the distance of objects from the camera) or perspective (the objects are smaller when they are far).
    • The size and aspect ratio of the 2D view on screen are defined by the viewport.
    • The Y-axis is pointing upwards.
    • Color values range from 0 to 1.
    • OpenGL stores its data in native heap memory, not in the Java heap memory of your application, and thus is not limited by the VM heap size and is not affected by garbage collection. It’s a big advantage over the Canvas-based solutions.

    Your first steps with OpenGL will probably be disappointing because it needs a lot of code to do simple things, and the result is often not faster than an accelerated Canvas library. In fact, you have to use a batching technique and advanced features such as the Vertex Buffer Objects to make the most of OpenGL. So, is it worth to spend time learning OpenGL since the API provided by LibGDX and jPCT-AE are already optimized and a lot easier to use? IMHO no, except for very particular needs, e.g. if you intend to add a realistic water ripple or wave effect to your game and you didn’t find the appropriate code on Internet.

    Now, you are able to make reasoned choices and select the right tools. It’s time to write your code, but what to do first? And what to do next?

    From the core to the shell

    A game is usually written from the core (the functions that draw, compute or move your objects) to the shell (the artwork, the user interface, the music, the bells & whistles, etc.). In a gaming company, it’s a bit different because people work in parallel, but when you’re alone or a very small team, you should follow this order because:
    1) You will be able to try out the core of the game in the smallest amount of time. You will see quickly what’s really lacking, what does not work, what is technically too difficult, etc.
    2) It is less discouraging to abandon a project at an early stage for a very technical reason, than to abandon it near the end for the same reason.

    So your first task is to produce a playable prototype with the core mechanics of the game. When this prototype will be fully satisfying, and it might not be before long, then it will be time to render your characters with their final texture, add sounds and music, save the game state on disk, make nice menus, etc.

    Use your imagination

    Even experienced game makers face difficulties because each game is unique and challenge your skills. Sometimes there’s no easy solution and internet and books are of no help. You have to invent a new way of doing things or mix existing approaches in an unusual manner. It’s not uncommon with A.I. or special effects. Example: a laser FX. That’s why I’m used to say that your imagination will be as much requested as your skills.

    The main functions of your game

    To build your prototype, you have to create a set of specialized routines. They depend on the type of your game, but usually you have:
    • a loader: it loads the resources and initializes data
    • a screen manager: it selects the appropriate screen (menu, map, options, etc.) according to the game state and player actions;
    • an input handler: it processes the keyboard and touch events
    • a “brain”: it selects the actions of enemies
    • a position calculator: it computes all moves and calls the collision detector
    • a collision detector: it detects collisions between objects
    • an updater: it defines the new state of objects (wounded, dead, paralyzed, hasted, etc.) and computes the score and lives
    • a renderer: it draws the objects on screen
    • a resetter: it resets all data for a new game

    For the clarity of your code and to make changes easier, create a class for each object type (a class for the hero, a class for his horse, a class for his enemies, a class for the map, a class for the furnitures, a class for the weapons, etc.). Then, create a specialized routine (loader, updater, renderer, etc.) in each class. You can choose another model, where the routines are in their own code module. In this case, each class makes a call to the common routine with its custom parameters.

    In the main class, keep track of the game state (“loading”, “ready”, “running”, “paused”, “game over”, etc.).

    If you don’t use a game engine, add the classes that will handle graphics, sounds, animation, files, input, physics, threading and networking at a lower level. These classes will be separated from the logic of the game and can be reused in other games.

    Adapt your game to the screen

    The first stage of your game is the loading of assets, and quickly a problem will arise: your background image has a size of 800x600 which does not fit the current screen resolution in landscape mode (854x480). What can you do?
    • Adjust the image size, but keep the same aspect ratio. Reduce the image dimension which is larger than the screen dimension and compute accordingly the other dimension. In my example, the image height is superior to the screen height so the image height is set to 480. The width becomes 480 * 800 / 600 = 640. The aspect ratio remains the same: 640/480 = 800/600 = 1.3333. By doing this, I get black stripes on the sides, but the image is entirely on screen whatever the resolution may be.
    • Stretch the image. The width and height are set to the screen size. I recommend using a nine-patch (a drawable with stretchable areas) in this case or your image will look distorted.
    • Draw your image as is. The width and height are not changed (or they are just scaled to the device density so that your image gets the same physical size on all devices). It’s too bad for the guys with small screens!
    The same reasoning can be applied to the game area, of course.

    This problem with resolutions brings a new question: what is the ideal size for my images? The answer is simple: there’s none. Create three versions of the same image with different resolutions and use the one that needs the smallest scaling. If you don’t want to bother with that, create large images. The scaling down of a large image will produce a better result than a small image scaled up.

    In one of my applications, I decided to set all background images to 1040x640. The image is large enough to scale up nicely on large screens and small enough for small screens. If I lose a bit of details, it’s not important because it’s just a background. This size is exactly in the middle of 800x480 (WVGA) and 1280x800 (WXGA). For the other graphic objects, I chose to size them properly for a 1280x800 screen. They don’t suffer too much from the scaling down.

    To test different resolutions or densities, you can use the emulator.

    Keep an eye on memory

    Don’t forget that an image takes up space in memory and that some devices allocate a very limited amount of memory to your application. So, if you want to load a bitmap, use the LoadScaledBitmap function of the Accelerated Surface library to resample and resize the image to the right dimensions.
    This problem will be less annoying with libGDX because this library transfers the loaded textures in native heap memory.

    In all cases, Out of Memory is an error to avoid at all costs. This error crashes the game, and even when you trap it, it’s not easy to recover from it. Note that LoadBitmapSample tries to sample down your images when this error occurs, but I cannot recommend relying upon this feature. First because that means that you don’t manage well your resources, and second because nobody likes to play a game with ugly images.

    To track the memory usage of your application, you can use the Monitor tool provided with the Android SDK and/or log the FreeMemory property of the StrictMode library.

    To reduce the memory usage, there’s not a lot of solutions: try to use smaller images, change their color format to RGB565 if you don’t need transparency (see the ReduceColors function of the Accelerated Surface library), set to Null the bitmaps or canvas instances that you no longer use, and/or store your images in native heap memory with either a library of the OpenGL ES family or the Native DirectBuffer library (reserved to experts).

    All that you may read about recycling bitmaps is mostly useless for the new versions of Android. This was only useful in some cases with Gingerbread and older versions. It is now deprecated.

    If you still have problems with memory, you can add this line in the manifest to get more memory with Android versions >= 3:
    Code:
    SetApplicationAttribute(android:largeHeap, "true")
    This line is of no use for the libraries of the OpenGL ES family except, of course, if you store in the Java heap memory a huge volume of data (e.g. an array with millions of float values).

    From the world to the screen

    Using the screen coordinates to position your graphic objects is sometimes a bad idea. Think to a chess board where the pawns can only move from a tile to another. It’s more convenient to position them by indicating a tile than computing their coordinates in pixels. Think also to a big world that cannot fit entirely on your screen. It’s more convenient to position your characters with world coordinates than with the limited screen coordinates. And sometimes you don’t have the choice. The physics engine Box2D, for example, doesn’t use pixels, only meters.

    When you use a library based on OpenGL, you can define with the viewport a different unit scale to position and size your graphic objects. With the other libraries, you have to create functions that make the conversion. Examples:
    Code:
    Public Sub FromTileXToPixelX(TileX As Int) As Int
    Return TileX * TileSize
    End Sub

    Public Sub FromWorldXToScreenX(WorldX As Int) As Int
    If WorldX < ScreenLeft Or WorldX > ScreenRight Then Return –1
    Return WorldX – ScreenLeft
    End Sub
    As you can see, these are very simple math, and very useful. In the second example, the boundaries of the screen in world coordinates are ScreenLeft and ScreenRight. These two X-coordinates limit the current area of the world which is drawn. If the given parameter is outside the boundaries, then –1 is returned; the object is not on screen and shouldn’t be drawn.

    Draw only what’s needed

    Assets are loaded, data are initialized, and all actors of the battle are ready to fight. It’s time to draw the battlefield and the sprites of the warriors at their initial position. Once rendered, the first computations will take place to know who strikes who, who is wounded, who is dead, who moves and where, etc. And the renderer will be called again to show the new situation. How to sequence these different phases properly?

    In libGDX, for example, the Render event is called continuously. You can put all your game logic in this event and sequence the phases as you wish (input handling, computation, rendering, then input handling, computation, rendering, and so on). In the Accelerated Surface library, a Timer raises regularly the Update event, then the Draw event, if you enabled that sequence with StartRegularUpdateAndDraw. It’s advised to put only the rendering functions in Draw, and everything else in Update. If the processing of one of the events takes more time than the Timer interval, the Timer waits before firing the next event so you cannot be in a situation where you start to draw with an incomplete calculation. In the GameView library, you have to set a Timer and use its Tick event. It’s like the Render event of libGDX; you can put everything here and order your phases as you wish.

    Regardless of the number of things to do between two renderings of a scene, everything has to be done in less than 16ms, rendering included. You could set this Timer interval to a longer value with some libraries but I advise against it. A span of 16 ms will display about 60 frames per second, which is an ideal rate for your game. First because the brain won’t have to create intermediate images to give you the feeling of a smooth and continuous motion, and second because your hardware runs at its best with this rate. Some devices are capped to 40fps, but it is still excellent.
    If one of the phases takes too long, but only from time to time, it will introduce an irregularity in the sequence and your animations will be choppy. If a phase takes too long, but always with the same duration, your game will be slowed. Usually the phase involved is the rendering phase. What can you do when that happens?

    There are two main reasons for a slow rendering: your graphic objects are too numerous or too complex. The first thing to do is to avoid rendering objects that are not visible, either because they are hidden by something else or because they are off screen. The second thing to do is to limit the number of textures because OpenGL binds only one texture at a time and doesn’t switch quickly to another. Take the habit to use the texture regions of a texture atlas (see the documentation of your library). A third thing to do is to minimize the complexity of your rendering. Far objects do not need to be rendered with a detailed texture. Fast moving objects do not need to be anti-aliased. Composite backgrounds do not need to be recreated each frame (create a snapshot of the background and draw this snapshot). Disable blending for opaque images (if possible) and minimize the transparent areas. Allow your players to disable some special effects (e.g. fog, water reflection, shadows, etc.). There are other optimizations but, if you apply these first three, you should gain many fps.

    I talked about the common case where the rendering has to be regular, but in a lot of games, like puzzle games, it’s not necessary and you should avoid soliciting constantly the CPU or the GPU for nothing. With libGDX, for example, you can stop the continuous rendering and raises the Render event only when needed. Your device battery will love it!

    Mind the step

    On a device, your application is not alone. There are services running, e.g. to check your mailbox regularly or to scan programs for viruses, and they can alter the flow of your game during short periods of time. You cannot do anything to prevent this, but you can adapt your game to these sudden changes by altering the time step. What’s this?

    We saw in the previous chapter that you have only 16ms to do all your computations and render a scene. This span is not the time step. It’s just a timer interval and it will be impacted by a slowdown of your device. The time step is in fact a float value that defines the speed of your game. An example will be better than a long explanation:
    Each time that you move an object in your game world, you increase or decrease its coordinates. If you do X = X + 2, two units are added whatever the elapsed time between two frames. If you introduce a time step, the formula becomes: X = X + (2 * TimeStep). With this time step, you can accelerate or decelerate your game at will, just by changing this value. Set it to the delta of time between two frames and your objects will move faster when the device is slowed. The player will see a constant move.
    A real example:
    Code:
    Actor.X = Actor.X + Speed * lGdx.Graphics.DeltaTime
    Speed is the speed property of the object to move and DeltaTime the time step. It is expressed in seconds between two frames. If everything goes well, its value should be close to 16/1000.

    Sometimes the interval between two frames is very long (it’s the case when the antivirus of my phone checks the launched application) and the time step causes an issue called the tunnel effect. The step is so great that the move is really big, and your object can cross walls (it is moved directly on the other side). To avoid this, you should limit the value of your time step. Example:
    Code:
    DeltaTime = Min(lGdx.Graphics.DeltaTime, 0.05'max=50ms i.e. 20 fps
    You cannot use a variable time step in all cases. Physics engines require a fixed time step. Box2D, for example, works very well with a value of 1/60. If it’s too slow for you, you can increase it up to 1/30, but don’t go over.

    ....
     
    Last edited: Oct 22, 2014
    fredo, Mashiane, SenZ and 27 others like this.
  2. Informatix

    Informatix Expert Licensed User

    Put a brain in the machine

    Your hero moves now very smoothly, and his infamous enemies are nicely animated, but these enemies won’t be a danger until they get a brain that chooses their actions in an appropriate manner and performs them with a bit of cleverness. If you’re unable to create this artificial brain (or just lazy ;)), you can add multiplayer support and the intelligence will come from the other players. Otherwise, you need to prepare for many readings and much research to develop a decent artificial intelligence. The amount of work will depend on what you want to achieve, the type of your game and the code already available on Internet.

    For some games, like card games, checkers or chess, it exists plenty of optimized algorithms to simulate an opponent. They can be found in various programming languages, so you will just have to convert them to Basic4Android. In the other cases, you should find at least a basic or general algorithm. If you don’t know what to search, what’s best for your game or how to implement it, I suggest reading a book on the subject (Artificial Intelligence for Games, Ian Millington, 2006) because, in what follows, I will only give you general information.

    In computer science, A.I. is one of the most complex fields of study and you will have a hard time to reproduce what you see in the recent and famous first-person shooters or real-time strategy games for your console or PC. People behind these games are specialists and they use very complex algorithms. You can’t achieve the same result without knowledge and experience, and since the players expectations are now high because of these games, you have to judge whether it’s worth the try to create games in a genre where the A.I. is very important. Note that it’s not the only strong reason why there are few first-person shooters or games with an impressive A.I. in the Android market: the limited performance of our devices adds a handicap.

    What is the A.I. supposed to do? It can be used to select where to move a non-player character, decide if a NPC should better find a cover or fire, search the best path around obstacles, suggest a move to the player, gather an army to prepare an attack or organize a defence, analyze how the player plays to find his/her weaknesses and habits, balance the game difficulty depending on the player’s ability, etc.

    An A.I. can think or can cheat. It can select its next action with the same rules and constraints as the player, or it can use cheatings, e.g. by seeing the player positions despite the fog of war, by collecting gold more quickly, by halving its movement cost, by looking at the players cards, by knowing the best attack combinations, by having more units at start, etc. Cheating is the common workaround to the lack of processing power and/or the lack of ability to create an A.I. It’s OK while it is accepted as a game feature or stays unnoticed by the player. On the contrary, you can decide that your A.I. will not be as smart as it could be. It’s common in games where computers are a lot better than most humans, e.g. chess or Scrabble.

    When it comes to find a path or avoid collision, your skills in trigonometry are required and if you forgot the Pythagoras theorem or don’t know what Atan2, Sin or Cos can do for you, you’re in trouble. Fortunately, there are the SteeringBehaviors library and the math classes of libGDX to save your day with ready-made functions.

    I’d like to finish this chapter with a concrete example. In navigation algorithms, it is common to have different movement costs to go from a point to another, since it is faster to travel on roads than through mountains, but it is less common (in amateur games) to have another cost computed on the basis of events or player actions during the game. For example, you can increase slightly the cost of nodes where one of the A.I. units has been killed and, on the contrary, decrease the cost of nodes where the A.I. killed a player unit. This way, you build a cost map that helps to avoid the places where the A.I. units die too often, and indicates where the A.I. takes frequently the advantage. So your units will prefer one path to the other. Of course, it is a bit crude like this and needs to be refined. This cost map can include other factors (e.g. a narrow path is dangerous for a big army) and be computed differently for each unit type (a river between opposed units is an advantage for the artillery and a disadvantage for armoured cars).

    Maybe I gave a somewhat daunting idea of artificial intelligence in this short presentation. Don’t worry; you can make great games without any A.I. (e.g. Angry Birds) or with a very simple A.I. (almost all games from 1980 to 1995, and a large fraction of the games for Android).

    Detect collisions accurately

    When two objects move in the same area, there’s a chance that they collide. It’s what you expect from your bullets when you shoot at a monster. But how to detect whether 2D objects are actually colliding?

    There’s a very simple answer: use the specialized functions of a physics engine. They are very good at anticipating, detecting and handling a collision between two solid bodies. I admit that they are not always easy to use and beginners may want to stay away. So what to do?

    The most used technique is the detection of overlapping AABBs. AABB means “axis-aligned bounding box” and is a rectangle around the visual boundaries of an object. If two AABBs overlap, there’s a collision. That’s fine if the two shapes in the AABBs are more or less rectangular. Let’s see an example. This “angry car” image has a lot of empty space around it:
    car_1.png
    …so you cannot use the image boundaries for the AABB. You have to define a smaller rectangle:
    car_2.png
    As you can see, there’s still some empty space between the wheels and above the car. It’s a problem in the following case:
    car_3.png
    The car AABB and the bomb AABB overlap but you cannot conclude that the two objects are colliding. An easy solution is to define more than one AABB for an object. Example with six AABBs:
    car_4.png
    If the car moves always horizontally, it’s an excellent technique, but if the car goes down a slope, then your bounding boxes are either rotated and no longer axis-aligned, or still aligned but with empty spaces in the corners:
    car_5.png
    In both cases, you have to compute the new position and new size of each bounding box, which is tedious, and only the first option (rotated bounding box) will provide an acceptable solution for collisions, but at the price of a complicated calculation to detect overlapping. Finally, using a physics engine is a much better idea.

    A physics engine does not use directly your images, only convex polygons created from these images. With the Aurélien Ribon’s body editor you can create automatically these polygons for Box2D:
    car_6.png
    As you can see, the collision outlines stick to the shape of the car and there’s no empty space at all. Despite the added complexity, the physics engine will detect any collision very fast because it uses optimized functions.

    Booom!

    Wow! Your game has a brilliant A.I. that moves enemies and when these enemies throw grenades at the hero, you’re able to detect when the hero is hit. The final touch is to make these grenades explode with a bright flash of light and a big booom!

    For your sounds, use the right library: MediaPlayer is not for sounds, only for music or ambient track. You cannot play more than one track at once with MediaPlayer and the track is streamed from the disk. With the SoundPool library, you can play many concurrent sounds, but you will kill your application if you try to play hundreds of sounds at the same time. Limit that to 16 simultaneous sounds and use the priority setting to select what sounds have to be heard above all. All the sounds played by SoundPool are limited in size, therefore in duration, and are fully loaded in memory. Because of the latter reason, limit also their total number.

    Don’t forget to pause music and stop sounds when the application is paused (libGDX does this automatically).

    To reproduce the complex effects of explosions, fire, smoke, etc., you need a particle system like the one included in libGDX. The libraries of the accelerated Canvas family are too slow for a particle system, which implies the rendering of hundreds of small graphic objects, and they cannot set the additive blending mode required commonly by particle effects.

    Creating a particle effect is a subject too broad for this tutorial. It is not as complicated as it sounds, especially when you use a particle editor. So play with the settings.

    Particle effects display a lot of graphic objects. If you abuse of them, you will have a serious performance issue.

    Final words

    A common misconception about games is to think that they are easy to do. A pinch of graphics, a spoon of sounds, a fun idea, and that’s all. Ok, it’s true for some games like the hangman game or the tic-tac-toe, but it’s wrong for a lot of them, and usually the ones that are on top of the charts. Not only for technical reasons. That’s why I didn’t try in this tutorial to write for complete beginners. If you are not yet comfortable with Basic4Android or programming in general, you will have trouble to create the game that you have in mind. And even more if you have no artistic skill or artist in your team.
    I tried to share with you what I find important or useful and, above all, I tried to focus on what’s a game, and how a game is built, not only on the language or the library to use as you can see in most books on the subject. If I taught you at least one thing then I’m glad. And if you feel that I’m wrong, let’s debate.

    -END-
     
    Last edited: Sep 12, 2013
    fredo, Johan Hormaza, ronell and 32 others like this.
  3. ZeroSoft

    ZeroSoft Member Licensed User

    Great tut thx! ;)
     
  4. bluejay

    bluejay Active Member Licensed User

    This is an excellent article - very well done! :)

    Thanks for posting this.
     
  5. RayLee

    RayLee Member Licensed User

    Nice post!!;)
     
  6. padvou

    padvou Active Member Licensed User

    Just read it!
    Although I 'm not into games dev, I enjoyed it very-very much.
    Thank you!
     
  7. Ratters

    Ratters Member Licensed User

    Just come across this, what a great article. Nicely done and really informative
    Thanks for the pointers :)
     
  8. persianpowerman1

    persianpowerman1 Active Member Licensed User

    hi guys,
    brilliant stuff... but im getting this error on the first prog(Animation) in the examples that im running
    Code:
    java.lang.RuntimeException: Libgdx requires OpenGL ES 2.0
    this is even after i had downloaded Agraham's OpenGL ES 2.0 from our site here... but funny thing is that it shows me v1.4 in the IDE's lib column? any ideas... have i missed something??
    thanx guys,
    YO!han
     
  9. Informatix

    Informatix Expert Licensed User

    The OpenGL ES libraries by Agraham are of no use with libGDX, first because libGDX includes already all functions for OpenGL and second it's a lot easier to use libGDX than the OpenGL library. Your error message is due to the fact that your device (probably the emulator) does not support OpenGL ES 2.0. If you're using the emulator, check "Use Host GPU" in the settings of your AVD. But running an OpenGL game on the official emulator is not a good idea. Try Genymotion instead.
     
    Peter Simpson likes this.
  10. persianpowerman1

    persianpowerman1 Active Member Licensed User

    hey buddy... like always.. all your answers and solutions are bang on target...

    greatly appreciated ... thanx again... :)

    YO!han
     
  11. wonder

    wonder Expert Licensed User

    Regarding this subject, I just wanted to share the following youtube channel: Extra Credits

    It has been a great resource for me on how to carefully craft a great user experience.
    They have more than 100 episodes on game development philosophy, check'em out!
    Here's an introductory episode:

     
    Last edited: Nov 27, 2014
  12. Informatix

    Informatix Expert Licensed User

    And the website: http://extra-credits.net/
     
    wonder likes this.
  13. Chris Williams

    Chris Williams Member Licensed User

    So correct! I actually tried to make a video game. I was actually doing okay, but when I saw the learning curves of the software and the game engines, plus the fact that I was not a team, but only a single person, I had no viable choice except to scrap my plans...bummer
     
  14. wonder

    wonder Expert Licensed User

    So in this case, having a fixed steep, how does Box2D deals with a sudden drop in performance?
    For example, like you mentioned, the antivirus running in the background.
     
  15. Informatix

    Informatix Expert Licensed User

    Look at the demo of Box2DLights. I show how to handle this case. I use a fixed step with an accumulator. I repeat the simulation until I reach the time spent in the Render event.
     
    wonder likes this.
  16. wonder

    wonder Expert Licensed User

    I will do so. Thank you! :)
     
  17. sorex

    sorex Expert Licensed User

    how did you test that, by the way?

    the chances that you just hit a wall during testing when a mail was pulled in or a file got scanned are kind of low :)
     
  18. Informatix

    Informatix Expert Licensed User

    Just do something at random in the Render event that takes time.
     
  19. StefanoAccorsi

    StefanoAccorsi Member Licensed User

    Hi all. Thank you @Informatix for this great guide, and for your porting of LibGDX (and even for the answer you write me by mail 10 days ago about ULV: I fixed the problems but there's a possible hint to others that I'll write to you).

    I'm relatively new to B4A (less than a month I found it, so BTW nice to meet you all) but I already wrote 3 apps and I found it great: the best RAD tool for developind Android apps.

    So now I switched to what is my first objective: write a game. As I said, this is a great guide, but I'm still stuck in finding the best tool to use.

    As Informatix wrote, I started with Accelerated Surface. It's a good tool, I wrote the "embryo" of my game in an afternoon. But it's very limited. Even if, for my game, I really don't need advanced features or performance, I couldn't set up a multi-touch handler in my Accelerated Surface.

    So I let it go and tried the "beast": LibGDX. I studied Informatrix tutorial (once again: thank you) then tried the tutorial at www.gamefromscratch.com even if it is Java oriented (I tried to translate it in B4A). My opinion: LibGDX is really a big beast it's really difficult to handle with. Do you know better learning resources to start with?

    So, before continuing my difficult climbing of the learning curve ;) I came back to this guide and explored the other tools.

    RSAndEngine is probably the right tool for me. It's compact but powerful enough, it has a good tutorial, so let's study it! Just a question: why does Informatrix not link it in his guide? Because it's a dead project. Right? Did I understand correcrtly?

    So, by now, I'm trying GameSprite that could work, but will I find it not suitable to me like Accelerated Surface?

    Weel, small talks apart (yeah I'm a bit talkative) I wanted to tell you what was my path in searching the best tool for me (the trip isn't over), thank Informatrix over and over, and then ask to you all two simple questions:

    - what could be the best tool (still supported ...) to develop a 2D game, something like an RTS on a "squared" table (think to the old Civilization): so big scene, few animations, many tiles ...
    - if the answer is LibGDX (I fear it will be) as I asked before: what's the learning path followed by who, among you, now master this library in B4A?

    Thank you so much! Have a great day :)
     
  20. wonder

    wonder Expert Licensed User

    LibGDX.

    Don't be discouraged by its layers of complexity. Once you understand how textures and texture regions work, you'll start to be feel really comfortable with this lib.

    Also, don't load/dispose things manually. Get familiar with the Asset Manager before anything else. So I guess that would be a good place to start.

    My suggestion:
    - Lesson 1: Asset Manager
    - Lesson 2: Textures
    - Lesson 3: TextureRegions
    - Lesson 4: Using "Batch.DrawRegion" in the game's main cycle LG_Render() event.

    - Extra: You must be really comfortable with high-school level mathematics. Without being familiar with vectors and trigonometry, you'll have a really hard time building your own game, no matter which platform.

    Once you understand these concepts, you have everything you need to build your own game, at least graphically.
    From this point on, you may start studying Box2D or if you are a masochist like me, write your own physics engine.

    Good luck.
     
    Last edited: Jan 30, 2016
    fredo, DonManfred and StefanoAccorsi like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice