I have a 2D Side-scroller game written in C using SDL. I chose C because at the time I was most comfortable with it, plus I don't really know C++, so there you have it
This is how my game looks like at the moment.
[attachment=18551:Untitled.jpg]
You can probably immediately notice(or not ) that I was inspired by Mario. I don't plan to make a clone, so I am thinking of stuff as I go. But right now, my physics are not properly or at all implemented. I did make jumping and falling work, but they don't work as you might expect them to.
My jumping for now is basically moving the player a few pixels above, no force, no acceleration or deceleration. My "gravity" is basically checking whether there is a solid tile below the player(and the tile next to it which I will explain why further down) and if not, I fall. But again, no deceleration there.
Here is how my jumping and "gravity" code which I will try to explain why I've done it the way I have.
if(player.key_press[SDLK_SPACE] && !player.is_jumping)
{
player.is_jumping = true;
player.pos.y -= 5000 * delta;
if(player.pos.y < 0.0)
{
player.pos.y = 0.0;
}
}
int tile_below = get_tile_below_player();
int next_tile_below = tile_below + 1;
int player_row = get_player_row();
int player_col = get_player_col();
bool fall = false;
bool can_check_below = true;
int distance;
if((get_tiles_per_row(player_row) - 1) == player_col)
can_check_below = false;
if((Map->tile[tile_below].type != ENUM_TILE_AIR || (can_check_below && Map->tile[next_tile_below].type != ENUM_TILE_AIR)) && (distance = collision_distance_rect(player.pos, Map->tile[next_tile_below])) != 0)
{
player.pos.y -= distance;
}
if(Map->tile[tile_below].type == ENUM_TILE_AIR)
{
fall = true;
if(can_check_below && (Map->tile[next_tile_below].type != ENUM_TILE_AIR) && check_collision_below(player.pos, Map->tile[next_tile_below]))
{
fall = false;
}
}
if((Map->tile[tile_below].type == ENUM_TILE_DIRT || (can_check_below && Map->tile[next_tile_below].type == ENUM_TILE_DIRT)) && player.is_jumping)
{
player.is_jumping = false;
}
if(fall)
{
player.pos.y += 300 * delta; // no collision detection, I clip. Will fix. Fix implemented above.
}
The first bit is my if statement where I check if the space bar was pressed and the player is not in a jumping state, and then "jump" which you see is 5000 * delta, where delta is a constant basically, part of my implementation of a fixed timestep, which I have not yet properly implemented, but I will get around to doing that.
After that is the code where all my magic happens . But first let me explain why I need to check not only the tile below the player, but the tile next to it.
You see I store my map in an array of structures, not a 2D array. The problem with this method is that you can't know immediately which tile you are on, so after many many days of thinking I was finally hinted at how to calculate the index for my map.
So here, I treat my map as rows and columns. To calculate which row a player is on, I do the following arithmetic
player.pos.y / TILE_HEIGHT
I divide the player's position by the tile's height. To get the column I am in, I do
player.pos.x / TILE_WIDTH
And I calculate the index of the of the tile in my struct array like so index = (player_row * tiles_per_row) + player_col. However although it works, it produces some edge-case bugs which I can only describe with pictures