Jump to content

  • Log In with Google      Sign In   
  • Create Account


farmdve

Member Since 01 Apr 2012
Offline Last Active Nov 07 2013 06:20 PM

Topics I've Started

How do I implement some physics in my 2D game?

26 October 2013 - 01:52 PM

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 smile.png

 

This is how my game looks like at the moment.

 

 

Attached File  Untitled.jpg   39.45KB   5 downloads

 

You can probably immediately notice(or not tongue.png ) 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 tongue.png. 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

 

Attached File  pic1.jpg   4.09KB   4 downloads
 
Now, in that picture I've numbered the columns, where do you think my player is(the red square)? The correct answer is, column 2, if you look closely one pixel is still in column 2. Why is it in column 2? Let's do some math. If we assume that my tiles are 32x32, and that my player's position on the X coordinate is 95, then using the formula player.pos.x / TILE_WIDTH would translate to 95 / 32 which produces 2,96875, but since we are dealing with integers, it's simply 2 regardless of how small the difference is. So that is why my player is in column 2 instead of 3 and why I check the two tiles below the player. I fix this in the if statement where I set the fall variable.
 
There are one or two more bugs, but I have "fixed them".
 
Anyway, sorry for wasting your time, but I had to explain why I did what I did. Now I would like to ask how to implement proper physics, not realistic, something like Mario physics but without an engine? My knowledge of physics in real life are lacking, I slept or skipped physics classes in school, so it's as if I know nothing. 
 
I've been looking at some articles online, but I didn't understand how to implement things like deceleration, jumping force based on how long the space bar was pressed. Or to do gravity properly.

I am trying to fix how weapons look.

04 October 2013 - 04:28 PM

For a while now, when playing first person shooters, one thing has always bugged me, the weapon that blocks the view, and the metal ring or square around the crosshair.
 
Here is a random image I found on google showing an ACOG scope http://images.wikia.com/callofduty/images/9/99/Aiming_down_the_ACOG_Scope_CODG.png, what do you notice? I for instance am bugged by it, simply because the metal ring blocks a few percent of the view. Another image here showing the main body of the PP-2000 from BF3 and how it blocks a lot from the view http://www.imfdb.org/images/thumb/e/ec/Bf3_pp-2000_aim.jpg/600px-Bf3_pp-2000_aim.jpg
 
Now what else do you see? Yes, the body of the weapon with the hand holding it, that blocks a significant amount of view in front of you, so much that it will hide an enemy if he is slightly farther away and below you. Has happened to me.
 
This is pretty much an issue with every shooter out there that has an aim down feature of the weapon(s). How do you propose this gets fixed, but maintains a feel of realism?

Should you work with limitations or overcome them?

22 September 2013 - 08:18 AM

Hi folks,

 

Right now I have a tile-based map file that has the following content

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXBXXXXXXXXXXXXXXXXXXXXXX
AXXXXXXXXBXXXXXXXXXXXXXXXXXXXXXXXXXX
BBBBBBXXXBBBBBBBBBBBBBBBBBBBBBBBBBBB

X represents "Air", A represents the player's spawn position and B is a solid tile.

 

All that gets rendered to this

 

Yu2VgNv.png

 

But you can see that my map is pretty much aligned, i.e the number of columns(i.e tiles) per row is the same for each row which works fine with the way I implemented my simple physics, but what happens if I change it around like so

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXX
XXXXX
XXXXXXXXXXXXXBXXXXXXXXXXXXXXXXXXXXXX
AXXXXXXXXBXXXXXXXXXXXXXXXXXXXXXXXXXX
BBBBBBXXXBBBBBBBBBBBBBBBBBBBBBBBBBBB

Which renders to this

 

d829g04.png

 

The red square is my player, he spawned to the position like in the previous image, but when I jumped he landed on the air, unable to jump anymore(because my code that sets a boolean flag if the player can jump never gets executed) and when I move, there is no collision detection. The black part in there means nothing is being rendered on those positions, no tiles there.

 

So here is my question. Do I treat this as a bug, or just accept that this is a limitation I have to work with? Because perhaps fixing this will require me to refactor most of how I handle physics in the game, or how I calculate the index for the array of structures where my map is stored, which I believe is impossible since I think the way I am doing it now is the only way to calculate the array index.

 

How do I handle physics? Well, falling off a tile on my map required me to detect two things, whether the tile below me was air, in which I case I set the flag to fall BUT I also do a second-stage IF where I check if the the tile next to the tile below me was solid and there was collision, in which case I didn't fall. Why did I do this? Because my code determines the column the player is with a simple division like playerX / TILE_WIDTH which works fine, but has some quirks in that I need to be perfectly in the next column for it to properly work. For instance 15/32 = 0, and that resulted in my falling off code needing to do the second-stage IF check. 

 

Perhaps it's bad design, I am not sure but with the way I store my map, this was the only way I think.


How and what do I do now?

17 September 2013 - 03:49 PM

So my 2D platformer inspired by Mario, but not a clone has some basic stuff more or less complete, which is a subjective term in my case cause my code is probably not bug free and probably doesn't have a very good design, but learning as much as I can smile.png

 

I have more or less completed the following:

  • Arbitrary map parsed from file.
  • Moving the character left and right.
  • Jumping.
  • Collision detection.
  • Falling off a tile due to "gravity".

The last three actually are not implemented 100% right, so they need a lot of work too, for instance I need fixed timestep instead of variable timestep as it could and usually does cause my collision detection to fail as the player could move waaay past a tile if the frame took longer than 0.001 seconds. I need to make it so the camera(i.e screen) follows the player in the center as he moves on the map.

 

Also, a next logical step in my opinion would be items or entities, but neither of those do I know how to implement(not even a clue!) and not sure if they will fit into my design.

 

Thank you in advance!

 

P.S

Yes, no mistake. I am doing my game in pure C using SDL 2.0. I plan to do the switch to C++ for my next game.


My opinion on game development after a few weeks.

14 September 2013 - 02:59 PM

...it's very hard. I started with 2D and the most easiest part is drawing on the screen and making something move. However, as soon as you try to add basic physics(they don't have to be realistic) or other stuff like collision detection or collision resolution, it becomes difficult, you begin to see errors in your design that you chose in the beginning, but it's too late to fix it, so you try to get around it with some fix, but turns out the fix has a bug that isn't really a bug but it can crash your program, you can mostly handle it, but you really don't know if there are any edge-cases which aren't handled or if your fix even works as intended.

 

And it's also important to carefully consider if your map will be uniform or not as it directly affects performance and difficulty of your code and various other aspects that I didn't.

 

So yeah, game programming is hard, takes one to do it to know it even if someone else told you it's hard. Makes me wonder if I will ever be able to work with 3D game programming if I am already at my limits so far.


PARTNERS