Thread: Asteroids-like collision detection/physics & rounding speed

  1. #1
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476

    Asteroids-like collision detection/physics & rounding speed

    Basically there are two problems. The first one is easy (in a 2D world):

    The entities in the project have positions stored as float points. But a screen has only ints as pixels. So, is rounding floats to ints appropriate? Since if I just take the floor, the objects move sloppy (stays the same, then jumps, stays the same etc). What would you do?

    The second one not so easy:

    So, let's say the players (spaceships) have position, rotation, scale and a center. If a player touches the screen borders, it should bounce realistically. For example:

    assume the player looks like a giant 'U'.

    Code:
    |   |
    |   |
    |___|
    if it's rotated 45 degrees to the right and collides with the top, like

    Code:
    __________
        X
       /
      /
     / C /
     \  /
      \/
    (Where X is the point of collision and C the mass center of the object)

    In this case, the point X is a bit to the right of C, so the object should rotate a bit to the right and be pushed down.

    There is a force acting directly down from point X (ignore friction for now). How should I implement this?


    So, the basic idea is implementing forces with a position and direction. But how to calculate the resulting rotation/translation of the object? I think this needs some trig. Don't matter.

    My ideas are:
    If the force's direction vector points to the center of an object (beginning at the force point), the translation is equal to the direction and the rotation is none. But if the vector points 90 degrees to the left/right, the translation is none and there is only rotation.
    Last edited by Brafil; 07-28-2009 at 10:30 AM.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Brafil View Post
    Basically there are two problems. The first one is easy (in a 2D world):

    The entities in the project have positions stored as float points. But a screen has only ints as pixels. So, is rounding floats to ints appropriate? Since if I just take the floor, the objects move sloppy (stays the same, then jumps, stays the same etc). What would you do?
    Apparently, openGL uses floats internally (for everything) and your variable will be converted if you use ints, which is inefficient -- so in other words, always use floats and use >=, <= never == with collision stuff.

    Which I have only done a bit of 2D collision so I can't add much more. Although I am sure there must be 90000 pages online to do with your second question(s). I guess it depends on how "realistic" you want the physics; I always like collision stuff that involves the appearance of a little bit too much reciprocating energy, eg. so head-on they actually bounce away faster than the speed they started at, which looks neat and adds to the viewing excitement, but probably is not very realistic, physics wise. My other fav technique there is incorporating a significant random potential, eg, so they may speed up, or slow down, or the trajectory may be too oblique. That ain't real at all, it's almost better than real! Unless your goal is emulating something specific these are subjective questions of style.
    Last edited by MK27; 07-28-2009 at 06:58 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Asteroids is simple and you don't need tons of physics in it if you don't have to have it.

  4. #4
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    I didn't mean asteroids. I only thought of the game containing asteroids-style elements.

    And I don't want tons of physics, but still a bit better collision response. The game shall be fun, not realistic, and I think just a floating spaceship which can't go out of bounds is not enough.

    But it shouldn't be like a physics simulation. I'm just adding some toys (like friction in empty space. It is not fun to play if you gotta stop it manually).

    EDIT @MK27: Nice idea. I'll add some randomness, too. Like the engines breaking if you try to go too fast (maybe they won't) ;-p
    Last edited by Brafil; 07-29-2009 at 08:52 AM.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    The entities in the project have positions stored as float points. But a screen has only ints as pixels. So, is rounding floats to ints appropriate? Since if I just take the floor, the objects move sloppy (stays the same, then jumps, stays the same etc). What would you do?
    I'd definitely store positions as floating-point numbers (probably doubles, but floats work as well), and then round to ints for display purposes. One nice thing about this is that if you want to support different screen resolutions, or in-game zooming, then you just use a different factor for the conversion to integers. The internal floating-point representation can remain the same. If you decide to do this you could say, for example, that the screen is 1.0 by 1.0 (or 100.0 or 100.0, but I'd recommend 1.0 by 1.0) units in size, and then keep track of everything (position, velocity, acceleration, etc) in this coordinate system. Then you can map the coordinate system to any view you like (a different size window, a mini-map in the corner, whatever).

    (like friction in empty space. It is not fun to play if you gotta stop it manually.
    You can also map a key like down or backspace to "brake"; it accelerates you in the opposite direction that you're moving, so that if you hold it down long enough you'll come to a complete stop.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    I have this brake key, but the game is kinda difficult only with it.

    BTW: I have managed to rotate the sprite if it touches the upper screen. But how can I make it rotate smoothly? Not just like flipping?

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Code:
    ...
    ...
    void Object::Update(float timeDelta)
    {
       m_vecVel += m_vecAcceleration * timeDelta;
       m_vecPos += m_vecVel * timeDelta;
    
       //Bounce off sides of screen
       if (m_vecPos.x <= Screen.left || m_vecPos.x >= Screen.right)
       {
           m_vecVel.x = -m_vecVel.x;
       }
       if (m_vecPos.y <= Screen.top || m_vecPos.y >= Screen.bottom)
       {
          m_vecVel.y = -m_vecVel.y;
       }
    
    }
    
    
    void Object::Thrust(float units)
    {
        m_vecAcceleration.x += cosf(m_vecRotation.z) * units; 
        m_vecAcceleration.y += sinf(m_vecRotation.z) * units;
    }
    
    void Object::RotateLeft(float units,float timeDelta)
    {
        m_vecRotation.z += units * timeDelta;
    }
    
    void Object::RotateRight(float units,float timeDelta)
    {
        m_vecRotation.z -= units * timeDelta;
    }
    ...
    ...
    This should do what you want. Note that mass is not taken into effect nor have I computed any mass moment of inertia's, etc.

  8. #8
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    Nice. Only that the acceleration is zero if the user doesn't press up or down (in my case).

    When bouncing off, should I apply a torque and force to the object? They will be a bit random.

    And how can I decrease the x and y-velocity at the same amount? For simulating friction?

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Do you want me to write the game for you? I gave you a place to start and you come back and ask other questions that are obviously only pertinent to your system. I don't know how your system works but surely you can integrate my suggestions into your code.

  10. #10
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    No. I've been implementing nearly exactly what you said. The only thing was if I should round or not, performance-wise. I know that I can profile, but I wanted to know what others do (learn by example, :-), not how they do it.

    Basically I know what to do know. I'll apply a small force in the right direction (I can calculate that) and a torque. I'll look at some other games for seeing how they do it.

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by dwks View Post
    I'd definitely store positions as floating-point numbers (probably doubles, but floats work as well), and then round to ints for display purposes.
    I know dwks does this way more than I, but I still believe that in the end openGL converts all non-floats to floats, so that is sort of silly. Maybe you should round to an integer value instead (or is that what was meant)?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Brafil View Post
    And how can I decrease the x and y-velocity at the same amount? For simulating friction?
    Normal sliding friction is a force directed opposite to the direction of travel and proportional to the velocity. Therefore, to apply friction:

    Code:
    velocity = sqrt( vx * vx + vy * vy );
    frictionForce = k * velocity;
    vx -= sign(vx) * frictionForce * timeStep;
    vy -= sign(vy) * frictionForce * timeStep;
    Where sign(foo) gives -1 if foo is negative, and 1 if foo is positive.

    This is the PHYSICALLY CORRECT way to apply friction. However, for game purposes, you can simulate friction without performing that expensive sqrt() operation by simply decreasing the velocity proportionally:

    Code:
    vx *= drag;
    vy *= drag;
    Where drag is some number between 0 and 1.

    There is also a fast, approximate method for computing sqrt( vx * vx + vy * vy ) without actually taking a square root, and this might be accurate enough for your purposes. But I'd start with the "drag" method and see how good it feels.

    There are other things to consider. Friction force can never REVERSE the direction of the velocity, but this finite timestep approximation can cause that to occur. So you would need some more complicated checks -- if the velocity changes sign, set it to zero instead. Again, the drag method does not have this problem.
    Last edited by brewbuck; 07-31-2009 at 11:59 AM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by brewbuck View Post
    Friction force can never REVERSE the direction of the velocity
    If the ship were covered in chewing gum it could
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Round to ints is pointless. Most graphics hardware works natively with floats anyways. The days of ints being faster and floats being slower have long since passed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Some collision handling fun
    By DavidP in forum Game Programming
    Replies: 9
    Last Post: 04-13-2008, 08:45 AM
  2. Collision Detection Problems
    By Dark_Phoenix in forum Game Programming
    Replies: 1
    Last Post: 12-17-2006, 03:25 PM
  3. Collision Detection
    By Grantyt3 in forum C++ Programming
    Replies: 3
    Last Post: 09-30-2005, 03:21 PM
  4. collision detection
    By DavidP in forum Game Programming
    Replies: 2
    Last Post: 05-11-2002, 01:31 PM
  5. Replies: 4
    Last Post: 05-03-2002, 09:40 PM