I am extending my previous study on SDL library for my final. From the tutorial page I blogged before, they are just separate utilities like input event handler, collision detection, sprite animation etc. Each of them consist of multiple functions and classes. My job is reading all the lines, extracting the essentials and stitching them into a piece. In order to clear out my mind, I started with a diagram that tells me what are the components in a class, so that I will not miss anything when I brought them in.
I also made use of a game idea I created last quarter as the content. It is a game that the player hit and replace obstacles on the map with good road, so that a truck can pass through to send resource to poor villages. I simplified it to a demo within a given time frame.
If a frame is already working, it requires courage to start changing the code. It is sad to see errors come out again. The worst case is I added many lines of codes but the program is not running in any ways and I cannot change it back. For this biggest program I have ever made in this quarter, I back up a version each time I successfully implemented a features. The process is as follow:
1. Tile map (last time) + Keyboard control character
2. Character with animation
3. Collision and logic <- change a tile to something else when touching it
4. Create the sprite sheet for the tiles and walkcycle of the character
5. Add another class for the truck and load an image into it
6. Make the truck move.
This is how the game looks like at the moment:
However I did not reached step 6 before the deadline. But that should not be hard. I can reuse the code for collision detection from the character.
Knowing what is going on with the code is actually very enjoyable.
Clipping a sprite:
No wonder why each time I was looking for animation for sprite, it always comes in a sprite sheet. I needed to crop each of them out with photoshop in order to import into Scratch. That is because the image can only be loaded once, and reused many times in the program. If any animation is involved, only the clipping plane is being moved (or the image behind the clipping mask is being moved), instead of swapping the whole image into something else. The following code is the animation for the dot (character). It has multiple frames when it is facing left and multiple frames when it is facing right respectively. Same method is repeated for the truck and the tiles. But the tile is a bit different. It is clipped according to its type. Changing the type of the tile is actually changing the position of the image.
clipsRight[ 0 ].x = 0;
clipsRight[ 0 ].y = 0;
clipsRight[ 0 ].w = DOT_WIDTH;
clipsRight[ 0 ].h = DOT_HEIGHT;
clipsRight[ 1 ].x = DOT_WIDTH;
clipsRight[ 1 ].y = 0;
clipsRight[ 1 ].w = DOT_WIDTH;
clipsRight[ 1 ].h = DOT_HEIGHT;
clipsRight[ 2 ].x = DOT_WIDTH * 2;
clipsRight[ 2 ].y = 0;
clipsRight[ 2 ].w = DOT_WIDTH;
clipsRight[ 2 ].h = DOT_HEIGHT;
clipsLeft[ 0 ].x = 0;
clipsLeft[ 0 ].y = DOT_HEIGHT;
clipsLeft[ 0 ].w = DOT_WIDTH;
clipsLeft[ 0 ].h = DOT_HEIGHT;
clipsLeft[ 1 ].x = DOT_WIDTH;
clipsLeft[ 1 ].y = DOT_HEIGHT;
clipsLeft[ 1 ].w = DOT_WIDTH;
clipsLeft[ 1 ].h = DOT_HEIGHT;
In each fps of the running program, the sprites are re-evaluate according to its number of frame, then move the frame by 1. In the following code, a function apply_surface is called in each frame in order to render the image with its clipping box and mask. A simple logic is applied to determine it is left or right and pass it to the function. When right or left key is pressed, the x position is added by a positive or negative velocity. Facing left or right can be determined by the direction of the velocity. And the frame of the sprite is looped. It is following the same logic as in Scratch.
if( status == DOT_RIGHT )
apply_surface( box.x – camera.x, box.y – camera.y, dot, screen, &clipsRight[ frame ] );
else if( status == DOT_LEFT )
apply_surface( box.x – camera.x, box.y – camera.y, dot, screen, &clipsLeft[ frame ] );
The collision checking function is surprisingly similar to the one I made for Bomberman I made for previous assignment with Scratch, like comparing the x and y of object a and b to see whether they are overlapping and at which side. But this time the logic blocks are code in the form of function. Another function touches_wall is calling the check collision function and determine what the character is actually touching and return true or false. The original calling is to stop the character by adding and deducting the speed at once when it hit a wall-type tile. I change it to changing the tile type of the tile it hit. I was trying to create a new tile to replace the old tile. But that did not work. And changing the tile type is the right way to achieve the effect I want.
bool touches_wall( SDL_Rect box, Tile *tiles )
//Go through the tiles
for( int t = 0; t < TOTAL_TILES; t++ )
//If the tile is a wall type tile
if( ( tiles[ t ]->get_type() >= TILE_CENTER ) && ( tiles[ t ]->get_type() <= TILE_TOPLEFT ) )
//If the collision box touches the wall tile
if( check_collision( box, tiles[ t ]->get_box() ) == true )
tiles[ t ]->type = 0;
//If no wall tiles were touched
loading an image is more complicated than I think. At first I simply copy all the codes for the character and replace all the variables with the truck’s one — without test running it. After I completed, it somehow did not work well. The truck image clashes the memory of the tile and everything messed up. I went back to a back up file and started up from the beginning step by step. But it already took me several hours. T_T
At the beginning of the quarter I started from Scratch, using ready made logic block without knowing what is within. After a quarter of learning, I can finally repeat the process with codes and library. Of course if I can do the same with a easier way, why do I need a more complicated way? But it is a learning process. I feel like I can program whatever game I need to make now!