Collision Resolution

ultifinitus
  • Collision Resolution ultifinitus

    Hey all, I'm making a simple side-scrolling game, and I would appreciate some input!

    My collision detection system is a simple bounding box detection, so it's really easy to implement. However my collision resolution is ridiculous! Currently I have a little formula like this:

    if (colliding(firstObject,secondObject))  
      firstObject.resolve_collision(yAxisOffset);
    if (colliding(firstObject,secondObject))
      firstObject.resolve_collision(xAxisOffset);
    

    where yAxisOffset is only set if the first object's previous y position was outside the second object's collision frame, respectively xAxisOffset as well.

    Now this is working great, in general. However there is a single problem. When I have a stack of objects and I push the first object against that stack, the first object get's "stuck," on the stack. What's I think is happening is the object's collision system checks and resolves for collisions based on creation time, so If I check one axis, then the other, the object will "sink" object directly along the checking axis.

    This sinking action causes the collision detection routine to think there's a gap between our position and the other object's position, and when I finally check the object that I've already sunk into, my object's position is resolved to it's original position...

    All this is great, and I'm sure if I bang my head against a wall long enough i'll come up with a working algorithm, but I'd rather not =). So what in the heck do you think I should do? How could I change my collision resolution system to fix this?

    Here's the program (temporary link, not sure how long it'll last) (notes: arrow keys to navigate, click to drop block, x to jump)

    I'd appreciate any help you can offer!

  • I'm not sure I understand the problem, but looking at your code above you resolve collision by only moving the first object away. What if in certain conditions, it's the second object that needs to move away and not the first?

    You might want to try resolving the collision by moving both objects away from each other at the same time by half of the offset, or even better by an amount proportional to their weight or size, this way a big box will only move a little bit while a small box will move a lot.

    If you have several objects to resolve (as you mention a stack), you need to find a solution that works for all objects at the same time and not just for 2 at a time.

    If you want a very good/accurate solution I recommend you get a good book on physics/collision for games and try something from there. This will probably take some time to implement and some of those system are quite hard to understand. Maybe also overkill for a simple game.

    One thing you could probably try now is to iterate through your resolution code a few times every frame between all the object. Every iteration will move each object away a little bit and hopefully find a good solution in very few iterations. Of course you might never find a solution this way and it might become too expensive to iterate many times in a single frame. Might be worth a try though.

  • Figured it out!!!!!

    Here's the new method:
    first, I add an object that I wish to check collisions, with my add_message_to_collision_queue(); function. I then invoke my handle_collisions() method:

    bool player::handle_collisions() {
    collisions tcol;
    
    bool did_handle = false;
    for (int temp = 0; temp < collideQueue.size(); temp++) {
    
    tcol = get_collision(prevPos.x,y,get_img()->get_width(),get_img()->get_height(),
                         collideQueue[temp]->get_position().x,collideQueue[temp]->get_position().y,
                         collideQueue[temp]->get_img()->get_width(),collideQueue[temp]->get_img()->get_height());
    
    if (prevPos.y >= collideQueue[temp]->get_prev_pos().y + collideQueue[temp]->get_img()->get_height())
      if (tcol.top > 0) {
        add_pos(0,tcol.top);
        set_vel(get_vel().x,collideQueue[temp]->get_vel().y);
        did_handle = true;
      }
    
    if (prevPos.y + get_img()->get_height() <= collideQueue[temp]->get_prev_pos().y)
      if (tcol.bottom > 0) {
        add_pos(0,-tcol.bottom);
        set_vel(get_vel().x,collideQueue[temp]->get_vel().y);
        ableToJump = true;
        did_handle = true;
      }
    }
    
    for (int temp = 0; temp < collideQueue.size(); temp++) {
    tcol = get_collision(x,y,get_img()->get_width(),get_img()->get_height(),
                         collideQueue[temp]->get_position().x,collideQueue[temp]->get_position().y,
                        collideQueue[temp]->get_img()->get_width(),collideQueue[temp]->get_img()->get_height());
    
    
      if (prevPos.x + get_img()->get_width() <= collideQueue[temp]->get_prev_pos().x)
        if (tcol.left > 0) {
          cout << "\nleft";
          add_pos(-tcol.left,0);
          set_vel(collideQueue[temp]->get_vel().x,get_vel().y);
          did_handle = true;
        }
      if (prevPos.x >= collideQueue[temp]->get_prev_pos().x + collideQueue[temp]->get_img()->get_width())
        if (tcol.right > 0) {
          cout << "\nright";
          add_pos(tcol.right,0);
          set_vel(collideQueue[temp]->get_vel().x,get_vel().y);
          did_handle = true;
        }
    
    }
    
    
    return did_handle;
    }
    

    then I clear the queue. pretty easy, and it works perfectly!!

Tags
c++ collision-detection game-design sdl
Related questions and answers
  • loading, etcetera. I am also using OpenGL via the FreeGLUT library in conjunction with SDL to display graphics. My method of collision detection is AABB (Axis-Aligned Bounding Box), which is really all... have updated my code with a new algorithm that checks where the ball was previously before collision. Corner cases work on that single platform correctly now, but when I have a wall of objects, I keep... to work correctly. Player movement ends up being very glitchy and repositions the player when I don't want it to. Part of the reason is probably because I feel like this is something so simple but I'm

  • Alright so i'm making a vertical side scroller where you are an '8' character traveling downward while avoiding my randomly generated walls (the "generation" function) on the left and right sides... until you pop out into an open space, known as a ' ' (space) character. You lose one life for each INITIAL collision with the X wall, and do not lose another until you have popped out and been freed from it. As an added touch i have made it so after you collide while traveling down the randomly generated map (or rather as the walls move uppward while your character stays put) the X chars you've

  • well... I'm building the animation system of my game engine (the skeletal and skinned animation stuff), and I came to a point where I added so much functionality in the frame and node structures... don't want to find out in the end that I have to rewrite everything again, as a lot of other objects will be working with these data. Sorry if it's a too subjective matter, but I need some insight. I'm... constructing a node object it's done referencing a pool of structure instances to prevent allocation for 2 equal frames. Also the lights are something that I'm not sure on how to handle as I need

  • question about it is, is this a worthwhile approach at all? If it's a bad design I want to know now before I invest too much more time making all the screens I'm going to need. How do you build up... sort of designs other people used to overcome them, or would use. For a little background, I started working on it in my free time last summer. I was initially making the game in C#, but about 3 months... to worry about this since it isn't an issue there. Moving to C++, this has become a fairly major problem and made me think I may have designed things incorrectly. I can't really imagine how to decouple

  • = xyCoords.y; m_font->DrawTextA(NULL, stateStream.str().c_str(), -1, &rct, DT_LEFT|DT_NOCLIP , D3DXCOLOR(1,0,0,1)); This all works perfectly. Where am I going wrong with the first bit of code...I would have thought that if the object is on-screen that this function should return screen coordinates. When used in conjunction with the directX draw text function, it works fine. Textual overlays... (texture coords for the screen go from -1 to 1 in each axis) but headPos has the value of -1.#IND000 in both the x and y. I think this may be because D3DXVec3Project is returning MASSIVE numbers, although I

  • I'm attempting to create a 3d tree procedurally. I'm hoping that someone can check my vector rotation maths, as I'm a bit confused. I'm using an l-system (a recursive algorithm for generating branches). The trunk of the tree is the root node. It's orientation is aligned to the y axis. In the next iteration of the tree (e.g. the first branches), I might create a branch that is oriented say...( 10.0f, 0.0f, 0.0f, 1.0f ); // z rotation Are my maths and approach correct, or am I completely wrong? Finally, I'm using the glm library with OpenGL / C++ for this. Is the order of x rotation

  • ) Where should I place the messaging system for my game engine? Lua? C++? I'm tempted to just have C++ object to behave as servers, offering services to lua business logic. Things like physics system... language, in my case Lua. On the other hand I want to use a component based design for my entities, and here starts my questions: 1) Should I define my componentes in C++? If I do this in C++ won't I... think you were not wrong and you did get the idea exactly as I wanted. Let me explain my ideas right now and key points after some sleep to clarify everything: 1) Components: At first I wanted to write

  • I don't get how coord (a UV vec2 in my mind) is equal to the dot product (a scalar value)? Same problem I had before with "g". What do I set the plane to be? In my opengl c++ 3.0 code, I set... Language 1.0 Several sites have mentioned that this should be "easy" to do in a GLSL vert shader. But I just can not get it to work. My hunch is that I'm not setting the planes up correctly, or I'm missing... in Maya, have 50k polygons and the modeler is using planer mapping, but Maya will not export the UV's. So I'm trying to figure this out. I've looked at the glTexGen manpage information: g = p1xo

  • ) is therefore highly wasteful. Then again, making each entity state a singleton hardly seems appropriate. What do you suggest I do? (The same can be said about game states, so whatever the solution...This is the first time I'm trying to make a 2D game, so I'm having quite a few difficulties in getting things right. Right now I'm trying to figure out exactly how the entity state machine should... changed, then it (the representation) starts having an internal state. I would much rather have it stateless so that I require only one instance of every representation (just as before). Edit

Data information