Sunday, February 20, 2011

Code::Blocks(11) RPG 1 - Tileset and maps(4) Cleaning up

I have been speaking with a good friend about the project , he has told me about many things that should be changed to prevent errors and to improve the code so i have worked on it before going any further in the tutorials so here is a list of things i have changed:

  1. I have removed the reference to the engine destructor, c++ calls it automatically so there is no need to do that, in fact my code made some strange errors when closing the app randomly, now i know why...
  2. I have removed the checking of NULL pointers in the SDL_FreeSurface() the function can handle it, so there is no need of doing that.
  3. In the SDL_SetColorKey i was using the screen format, shouldn't do that, instead i should use tileset format to prevent type mismatch...
  4. LoadTileset() should use const char* instead the char* i was using
  5. I have split UpdateMouse() function, now there is a DrawMouse() function that just draws the mouse, i have taken out the code for handling the mouse and button movement  i have also changed the getmousestate function for the sdl_event handling, now it's smoother.
Thanks to "Jonny D" >  http://code.bluedinosaurs.com/
He owes a good place with interesting tutorials (c++, sdl and many more things)for beginners and for experienced people too!

Bye!

Tuesday, February 15, 2011

Code::Blocks(10) RPG 1 - Tileset and maps(3)

Time to use a multi - layered map:



We want to draw (quite) complex things, starting from simple ones, the easier way to accomplish that is to use tiles (at least one used quite often), so we don't draw the full image, but just small pieces, with many pieces we can draw complex images, I'm going to use three (virtually four)  layers of tiles:

  1. The base ground: Sand, grass, water, etc.
  2. The ground objects: Rocks, trees, a road, a volcano, etc.
  3. Things that can lay on the ground: Treasures , any other inventory-related object, etc.
  4. On a virtual 4rd layer we will draw  additional objects, not map-related such as PCs, NPcs, the mouse cursor, etc.
Before going any further, just download the 2nd project from the Download page (http://jbfproject.blogspot.com/p/downloads.html) and just compile and run it, if everything goes ok, you should have a screen like the one in the top.

Not very impressive right? but it shows the key to build complicated maps using simple tiles, divide an image into small pieces and use layers, we have applied here the latest updates to the simple engine class in the previous posts.

The basic difference between this projects and the life game one is that in the previous one the map was an array with two dimensions: cellmap[x][y], now it is a three dimensions map: map[x][y][layer], so when we draw the map we will have to draw first layer (0) to print the base ground, then layer(1) for the terrain objects and finally layer(2) to draw other objects, after we have drawn the map we will draw the mouse pointer.

Note: there are many , many ways to define and draw a map, here i have just used a simple way.. you can find more ways for example in Amit's game programming information but of course, you can use anything that meets your objectives.

In the next post: Our Hero drawn on screen, cameras , and other things....

Bye

    Tuesday, February 8, 2011

    Code::Blocks(9) RPG 1 - Tileset and maps(2)

    Thinking about the tileset blitting function i have changed my mind, i have realized that it's easier to make just one blitting function that can draw tiles using a grid system and adjust the tiles with an x and y offset.

    Now let's change the function:

    engine.h
     void BlitTileset(int x,int y, int OX, int OY, int tile); // Blit a tile from our tileset to the screen

    Notice: OX and OY >> (Offset X and Y)

    engine.cpp

    void Engine::BlitTileset(int x, int y, int OX, int OY,int tile) //Blits a tile from our tileset to the screen
    {
    SDL_Rect start,end;
    //set the cliping for the source surface (the tileset)
    start.x= (tile%8)*TileSize; //Column = tile % 8 (0-7)
    start.y= (tile/8)*TileSize; //Row = tile / 8 (0-7) >> we could use here a bit shift to divide by 8, but i think it's easier to understand that way...
    start.w=TileSize;
    start.h=TileSize;
    //set the cliping for the destination surface (the screen)
    end.x = (x-1)*TileSize + OX; //Offset X
    end.y = (y-1)*TileSize + OY; //Offset Y
    end.w = TileSize;
    end.h = TileSize;
    SDL_BlitSurface(tileset, &start, screen, &end); //Blits a tile from our tileset to the screen
    }

    That way we can use the same function to draw the map, the pcs , npcs and the mouse cursor, in fact we are going to change the mouse drawing function too so it will be like:

    void Engine::UpdateMouse()
    {
    MouseButtons = SDL_GetMouseState(&MouseX, &MouseY); //Update mouse state
    BlitTileset(0,0,MouseX,MouseY,24); //Blits the mouse pointer into the screen
    }

    Easier that way , right?

    In the next post, i will show how to draw a multi - layer map...

    see you soon

    Saturday, February 5, 2011

    Code::Blocks(8) RPG 1 - Tileset and maps(1)

    In the life game tutorial we have used that tileset:



    Now we are going to use a different tileset:



    We need to draw more things, in the last tutorial we just needed 4 cells states and a mouse cursor, now we are going to use a tileset with 8(width) x 8(height) =64 different tiles, (you can use any size but at the moment it is enough for us), i am going to divide the tiles using a logical way: each row has a particular function, so:
    • Row(0) will be the terrain tiles.
    • Row(1)  terrain object (trees, a volcano, roads...).
    • Row(2) :PCs (NPCs): A person (kinda) , a cat and a dog.
    • Finally in row(3) we have the mouse cursor.
    Notice three things:

    1. My horrid drawing skill with Gimp ;)
    2. There are many empty tiles so if we want to draw more things you can easily do it without making a big effort.
    3. I'm going to use more than one layer to draw the terrain, so we will use a base image for every tile , say grass, water, sand, etc and then we will draw other elements (rocks, threes , a road, etc) on a different layer to add complexity to the image.
     In the engine, we have to change the tileset size from 50 to 100 so it will adjust the tiles properly,

    We need a new function to draw tiles, the one we have just use the tile size to adjust the position of the tiles, but now we need another one so we can adjust the tile to an offset x and y because we want to draw the characters at x=15(pixels), y=27(pixels), not at x=15(tiles), y =27(tiles).

    Finally i'm going to adjust the tileset drawing function so we will pass the tile as a integer (0-63) and the function will automatically search the correct tile.

    In the next post the two new tileset drawing functions.

    bye