Announcement

Collapse
No announcement yet.

My experience with SDL2 and game development by Acid_Snake

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • My experience with SDL2 and game development by Acid_Snake

    By Acid_Snake

    In my last post I mentioned that I have been working around with SDL2 and a game for PC and Android. Here I will talk about my experiences with this library and show you what the game looks like.

    Simple DirectMedia Layer, or SDL for short, is a low-level audio, keyboard, mouse, touchscreen and graphics library aimed at creating low-level (mostly 2D) games on various platforms.

    When we do something related to homebrews, be it games, menus or other types, on the PSP, we usually first choose a graphics library, or for those writing it in LUA, we choose a LUA interpreter with our preferred library.

    The most common PSP graphics library out there is simply called graphics.c (or graphics.h). It was one of the first and oldest libraries out there and still used by some homebrews and menus (like the famous 138Menu by my friend GBOT).

    Another famous homebrew, Wagic, and famous menu, yMenu, use the JGE++ library, who was coded by, I don’t know, and is available on the PSP, PC and smartphones (iOS, Android, others?).

    The last homebrew I coded for the PSP was arkMenu, which uses a new graphics library created by xerpi called ya2dlib. The reason I used ya2d was because it was fast, powerful and I am a friend of xerpi (we are both Spaniards) so I was in constant contact with him asking him to improve it or writing new features to it to fit arkMenu.

    All this made me get interested in writing a completely new game from scratch for PC and Android, and just like I would do on the PSP, I first had to choose the development environment and graphics library.

    When it comes to gaming today most people will tell you to write your game using Unity or other fancy IDE's like Visual Studio. But there’s a problem: these IDE;s make small games consume a shitload of resources, as well as requiring modern graphics cards and requiring a powerful PC to work with, which I do not have at hand (I do all my coding on an intel atom netbook from 2010 with very basic intel integrated graphics card that barely does 3D).

    All this said: I needed to do all the coding by hand, like a damn pro, and use a low-level library, like I would do on the PSP. After researching for 5 minutes (most of which was spent on loading Firefox itself) I came across SDL2 and a bunch of tutorials about it.

    SDL2 provides a BIG improvement from the first SDL: it now has hardware acceleration for 2D rendering, amongst other things, but this is the most important. SDL2 has everything that I needed to make a simple game: graphics, TrueType Fonts, sound, controller (keyboard, mouse, touchscreen, etc) so it was the perfect choice. That said, I started by doing what I always do when I migrate to a new graphics library: write wrappers for the screen, images, sound and other library-specific code so I don’t have to worry about remembering a new API. This is pretty straightforward and requires very little effort and has very little impact on performance.

    Once that was done, I proceeded to writing a sample. I created a small background with a static character moving around depending on which keyboard arrow you pressed, and it teleported to the coordinates of the mouse if you clicked on screen. Believe it or not, this small and useless “code” gets you familiar with the library and in my case, it served as inspiration for the game I ended up writing.

    After this, I worked on this “test” by adding a few more things like character animation, a local greedy best first algorithm for path finding (this is actually a bad choice, a global best A* algorithm would be ideal but I’m too lazy to change it now).

    Alas I knew the “test” was starting to look more like a game and less like a test, but what kind of game? That’s where inspiration took over: I had the idea to write a game where you have to cross over a minefield (where the mines are not visible of course) using a wide variety of weapons and items that you can randomly find. The areas of the game are randomly generated, with the amount of hidden mines increasing depending on the difficulty level. This is actually the easiest way to code how a game difficulty works: using probability. In other words, the highest the difficulty, the more probability of there being mines and less probability of there being items or “safe spots”.

    In statistics, probability goes from 0 (which means “impossible occurrence”, it can never happen) to 1 (which means “needed occurrence”, it will always happen), but floating point data takes up between 32 and 64 bits, if we interpolate it to percentage (between 0 and 100) we can achieve the same thing and only require an unsigned char (which takes up just 8 bits).

    In game programming, we want to be as efficient as possible. Once you have a percentage, you can just use the rand() function from the standard C library, like this:

    Code:
    srand(time(NULL)); // initialize the random number generator
     int r=rand()%100; //we obtain a random number from 0 to 99
     if (r<probability)
     // add something to the map, or whatever
    Other things like the game's map are represented by a two-dimensional array (aka a matrix) of cells that each hold a background floor (which can have an invisible mine, a visible mine, a rock/lake/blockade, a safe spot, etc) and a doubly linked list that contains references to Objects, these Objects can be characters the player controls, items the player can pick up, or a cow, which works like both of them.

    Due to the game being written in an OOP manner (with only a few aspects of it using simple namespaces) all items and weapons inherit from the character class and share many of the same functionality, using inheritance and all that OOP *** that I will not talk much about in here. Did I mention I do all of this using a preprocessor I myself wrote that converts classes to plain C structs? Yeah I think I did, but whatever I just like to brag about some of the stuff I make when I'm inspired.

    The game generates maps randomly depending on the difficulty, so now all I had to do was code a simple menu to change difficulties, nothing really big, and of course a high-level scoring system. Having high scores means also having savedatas, and having savedatas also means encrypting them, at least a bit, to just prevent casual script kiddies from modifying the saves and giving themselves a big *** score. The simplest and easiest form of encryption anyone can think of is by xoring the data with a key.

    When we xor value A with value B we get a resulting value C, if we xor this value C with value B we get value A, when xoring value C with value A we get value B. In a more “mathematical” way:

    A XOR B=C
    C XOR B=A
    C XOR A=B

    We can use this to create a key (value B), xor the savedata (value A) with it and obtain an encrypted savedata (value C). Then to load we just xor the encrypted savedata (value C) with the key (value B) and we obtain the original savedata (value A).

    This is of course the oldest and simplest form of encryption and is EXTREMELY easy to bypass, but we are not talking about a critical application here, we’re talking about yet-another mobile game, and giving yourself a super-high score is only lying to yourself, so I really don’t give a ***. BTW the key I use for my game is an Easter egg.

    Well that’s enough for now, on part 2 I will talk about my experience porting the game to Android and I will (finally) show some screenshots of the game.
    By Acid_Snake

    I like beer.
    The Hackmaster

  • #2
    Part 2

    By Acid_Snake

    In this final part, I will talk about my struggle and non-struggle porting the game to Android. What is initially a straightforward thing, and for the most part it is, ended up having a few problems that I needed to address manually. I will also finally reveal the game with some screenshots.

    Once the bare basics of the game were made, I realized that the game only really used one click of the mouse to work, so it would be pretty straightforward to port it to Android by replacing the click with a tap and SDL2 is after all available for Android.

    Android applications are however written in Java, that crappy programming language I would never use unless I get paid for it, so to port C programs to Android we have to use the Java Native Interface (JNI), and to do that you have to compile your application as a library along with SDL2 (you can have SDL2 be a shared library – .so – or statically linked into your main application library, which is what I did) and then write a main Java class that loads this library and calls the main library function.

    Thankfully the folks working on SDL2 already did all this *** for those of us who hate Java to the bone, but there was still a few things I had to change. On my device, when I paused the game by going back to the launcher and resumed it, one assumes that the game will go back to normal, just like when you sleep your PSP or go back to the live area of the vita and returned to the game, however in my case the screen went black but the game did resume, there was background music and the game responded to my taps it was just the screen that messed up.

    I Googled around and found that you had to reload ALL your *** textures due to them being invalid as you loose the OpenGL context when you go back to the launcher or changed application (on Android, SDL2 is an OpenGL wrapper).

    I tried to override the onPause and onResume functions of SDL2’s main class to have it call some function that reloaded all textures, this meant that I had to keep track of all the loaded textures and add a new method call “reload” to the image wrapper class. However, this didn’t do anything, I still had a black screen when resuming the game.

    So how did I fix it? By overriding the onPause method of the main Java class to have it call a C function I created that saved the state of the game (how the map was laid out, the current score, what characters and items there were and where they were) to a file, then the game exited completely rather than pausing and when launching the game again it recreated the game’s state with that file, it is of course needless to say that if you were not playing (the game was in the main menu for instance) then there was no need to save the current game state.

    Damn, that was a lot of talk so I had to split what was initially only one post into two. Anyway, the screenshots of the game:









    The game has a lot of weapons and items that are randomly placed on the map, and you always have the same start-up weapons and items. There’s also cows that you can control, they eat grass and either reveal mines or safe spots, cows never die or are harmed, they are invincible and only get bored after eating 5 times or so and go away somewhere else.

    Although the code itself is pretty much done, some of the graphics still need to be finished. And it should be possible and easy to port to something like the PSP, but for now there’s no incentive to do this. I already have a friend with an Android developer account that agreed to upload the game to the store once it’s finished.

    The game will be free, but I want to work on the sequel (which will be bigger, I already have some ideas that will be fun) and all this requires some funding so it will most likely have ads at least at start up (I want to stress out that I don’t like day-one DLC or micro-transactions so that’s out of the question) and I will be accepting donations for those who want to help with this project but don’t have technical or artistic knowledge.

    BTW, if anyone has (good) knowledge in making sound effects and music and would like to contribute to the project, send me a PM in /talk.
    The Hackmaster

    Comment

    Working...
    X