Categories

Thursday 19 February 2015

Graphical layer implementation

This blog post is about the graphical layer implementation I did this week.
The implementation was done to gain better control over the order in which the sprites are drawn on the screen (which sprites that will appear on top of the others) and to simplify changing the view (the portion of the game world that is displayed on the screen) of certain sprites in the game but ignore other sprites like GUIs and HUDs.



In SFML there is a data type called RenderTexture, that works very similar to RenderWindow. The major difference between the two is that RenderWindow creates a graphical window presented on the computer screen whereas RenderTexture can not be viewed, only drawn as sprites on other surfaces.

I use RenderTextures as the data type for my layers. The layers are stored in a list, in the order they are supposed to be drawn out. All sprites are now associated with a layer variable, which is just an integer that the drawing function uses to determine which layer it should be drawn on.

When all sprites are drawn the view is changed on the specified layers by using the inbuilt functionality renderTexture.setView();



A thing to remember when using RenderTexture as a layer is that the RenderTexture.clear() function has by default to fill the screen with a non transparent black color. To make the layer transparent in the clear function you need to specify the clear color like this .clear(sf::color(0x00,0x00,0x00,0x00)) So that the alpha channel (the fourth value) is set to be fully transparent.

Since entities in this game can have more than one sprite I also implemented a sprite list in each entity. The sprite list consists of a std::vector containing std::pair where the first value of that pair is a pointer to a sprite and the second value of the pair is the layer specifying int for that sprite. To reach the sprite, for example when changing the position of it one needs to write like this inside the entity class: m_sprites[index].first->SetPosition(x,y);.

Implementing layers was a high risk move, since I did not know if it was going to work as I wanted and it required rewriting a lot of code in many classes before I could see a result. It took more time than I thought it would because of all the code needed to be rewriten to work with the layer code. I could have reached similar results without the layers by adjusting the position of all sprites according to the game view in the window before every time the sprites are drawn to the window. I choose the layer approach over the moving sprites approach because it made more sense for me to think in terms of layers and I thought it would generate code that was easier to understand and read. In terms of performance I have no idea what approach is more suitable. In the end I got the result I wanted.


Thursday 12 February 2015

Tile maps

    Most of this week I have been trying to create a good and working parsing code for tile maps created with the tool tiled. I started trying to copy the code from my last project which was based on tiles. That did not work out that well, since that code was not made to work with the files that the program Tiled outputs and since I hadn't fully understood how file parsing works in C++ so my code just returned errors. I got frustrated and searched the web for an easy solution.
I found this project: https://github.com/bjorn/tiled/wiki/TMX-Map-Format

     It seemed like a good solution, and it probably was if only I could understand it, which I couldn't. So I spent a lot of time trying to figure what was needed to make it work, then I gave up to find something simpler. Then I found this: http://en.sfml-dev.org/forums/index.php?topic=3023.0

    It seemed simple at first glance since it was only two classes of code. I started removing parts that I saw as redundant, like the creation of sprites which I manage elsewhere in my code. I realized that this code was dependent on another libary called tinyxml, so I downloaded that and included it. Then I realized this code was made for an older version of SFML than what I am using for my project. So after combating this code and trying to translate things that I did not understand for hours I gave up, because I saw no end to it and I didn't think the program would run after all the changes that was needed to make it work with my code.

    So finally I got back to trying to do my own parser. I worked until I got an error that I did not manage to get around. Searched for a long time on forums for a solution until finally I gave up and decided to ask about it on a forum myself. I got an answer within half an hour that solved all my problems.

    If I had only asked for help on a forum in the first place I would have saved a tremendous amount of time this week that was spent feeling confused and angered about not finding a solution. At the same time I learned much about how to implement and understand code from others so that was nice.

Here is a picture showing the result off the walls (The black squares surronding the diver.) that was generated from a text file loaded by my parser.