Simple Bomberman physics... i thought anyway

Hi all.

I am trying to write a litte bomberman clone. (See pic)

The player can move on the x and on the z axis.

And i only need the bounding boxes for "physics", so i wrote this controller.



Player is a simple subclass of Jme Node.

The velocity vector of the player is set at the input controller as (speed*time) in each direction pressed…



The player node has to have the ability to "slide" along the walls.


  • Saving the current position of the player to lastPos
  • Check, if the x part of the velocity is allowed and apply if so
  • Check, if the z part of the velocity is allowed and apply if so
  • Zeroing velocity of player for next update



    The check is done in this way:


  • Multiply the velocity vector with a mask (eg velocity is (.5, 0,1) and we want the x-component multiply with (1,0,0))
  • Add it to localtranslation of playerNode
  • Test with collisiondetecting if player collides
  • If player collides, set back localTranslation



    Now i have the following behavior:

    If i press key up (to the north of the gameboard), the playerbox runs against the wall. It stops at the wall, shivering because of the setbacks of the localTranslation. After releasing the key, sometimes the box’ localTranslation is set into the wall, and the key input is the other way round (up is down, down is up) because the box is inside the wall and is always set back more than velocity…



    I saw the code at http://www.jmonkeyengine.com/jmeforum/index.php?topic=4031.0

    but i dont need triangle collisions. I think the approach with calculating normals could be done with boundingboxes too, but after several hours i didnt get it running…



    Is there an error in reasoning on my side?

    Do i have to update the collisontree after setting the localTranslation of the players node?



    http://snareoj.byteholder.de/Collisiontest.java



Hi, i assembled an test for this behaviour:

http://snareoj.byteholder.de/Collisiontest.java



If you stick into a wall, press two keys (eg down and right) and you will end up in the wall, with controlls reversed.



If you set “doSyslog” true, you’ll see this behaviour:



update 1:

Moving Player - no collisons



update 2:

player has collisions at current position (There is a check at the beginning, if there is a collison atthe current position without moving the player!)



I think this is a very common problem isnt it?

For example, in a “fast” shooter motion and its physics is done with boundingboxes - only for testing if a player hits with his bullet the triangle collision seems a useful approach, and normaly there will be also boundingboxes around the targets zones…



Btw.:

I tried your triangle collisions test from the other thread, and only changed the Sphere of the character to a Box -> not working anymore…



Greetz

snare

Hey snareoj,



About bounding boxes, I'm not aware of a way to calculate any useful information, like normals, from bounding box collisions, other than that it happened.



The shivering (if its a problem) could be cured by not setting the player back farther than it was the previous location, you may have tried this. I beleive you should not need to update the collision tree after every movement.



For what it appears you are trying to do, bounding collisions should be sufficient if handled correctly. I think you took a good stab at it. Because the movement is really only along the x and z axis I think you could get away from needing to do extra math for sliding and such.



Is the problem here the fact that you sometimes end up inside the wall, and then it goes screwey?

Thanks for your answer.



Is the problem here the fact that you sometimes end up inside the wall, and then it goes screwey?


yes.... thats it...

The main reason i am wondering is:

storing old position in a vector (There was no collsion)
updating the players position
handle Collisons
if collision -> set back to stored position

But at the and, there is a collison at the stored position too !

I didnt thought this "easy" way of collision detection is as hard and disappointing as this...
:|

Greetz
Snare


But at the and, there is a collison at the stored position too !

That doesn't seem right. The previous position should be "safe".

Can you give a simple order of operations list?
like:
storeLocation
update along x
checkforcollision
..
...

I don't understand how it thinks a collision is still occuring.

@nymon, i used your code with Triangle Collisions with my setup (A KeyController for Key input, and a Controller for Phyics), and  i got this behaviour:



In my KeyController there is a variable "speed" (should be at physics…), which controlles the amount the sphere goes per update. If the sphere is too fast, it will stuck into

the wall and never come back…



I think this is the main problem: after a certain amount of way passed, the way becomes to "long" - You have to check more positions between last and new Position if there is a collision…



Bye

It does act a little strange with a box. I havn't had a chance to look into why it wants to slide to the side, perhaps its due to inaccuracies from some math.



In my app I simulate gravity and ray cast downward to check if i'm "on the ground", my collision geom is actually hovering above ground a little, this allows me to go up steps and such but not walls. I assume my gravity/ray casting keeps my character (which is a box) from sliding in wierd directions, I just get side to side sliding. But I don't get penetration. I would like to spend more time on it, but can't for a few days.



I'll check out your test

This isn't a general collision type solution, because I don't know how to do one, but since you are doing bomberman, could you not just code a specific collision system for the game? This could work a lot better than using a general collision system (see last point below):


  1. Store the player position in coordinates relative to grid, so 0,0 is where the player is centered in the corner square of the grid.
  2. The player is considered to be "occupying" some squares - if their coordinate in both directions is an integer, then they are occupying one single square at that coordinate. If only one coordinate is an integer, then they are occupying two squares (e.g. at 0, 0.5, the player is occupying squares 0,0 and 0,1). If both coords are non-integers, then the player is occupying 4 squares.
  3. Whenever the player moves in a direction (horizontally or vertically), you just check whether their new coordinates result in them "occupying" the same squares, if so, it is fine. If the set of occupied squares is different after the move, then the move is okay only if all the new squares are clear (not walls). (Side note here - if for some reason you want to have a movement by >= 1 square, then break it down into multiple movements, and run them separately. This should happen unless you have some really terrible frame rates, but it's easy to check for)
  4. If the move is NOT okay, then you need to modify it. The simplest way is just to clip the movement so it stays in the old set of occupied squares. This will result in the player coming to a halt exactly lined up with the blocking wall(s). Clip the horizontal and vertical movements separately to allow for sliding along a wall when pressing diagonally)
  5. To make the movement more responsive (and more like the original bomberman, IIRC) you can actually add a degree of "homing" ability to the movement. The aim here is that if the player is trying to move right into a clear square, with occupied squares above and below it, but they are not EXACTLY aligned with the clear square (vertically) then strictly you need to stop them moving right, and so they will just stick forever. However you CAN help them out without breaking collision, by moving them vertically (even if they are only pressing right on the joystick) so that they move towards lining up with the clear square, and hence they will not get completely stuck. I would do this by using the same concept of occupying squares as above - in this case you will be getting a different set of occupied squares after the movement to the right that the player requests, and you will reject the move because one of the squares (at least) will be blocked. But you notice that the player is moving right, and that only one of the new occupied squares is blocked - so in this case you add some vertical movement to line the player up with the clear square and away from the blocked square. When you do this, make sure you add code that checks for "overshoot" and clips it, so that if you would move the player past an integer coordinate while aligning them, you instead line them up exactly. This code is actually required to make it possible to move around the standard bomberman level design (otherwise it would be very very hard to walk along a corridor horizontally, and then switch to walking down a vertical corridor at a "T" or "+" junction, since you would be unlikely to exactly line yourself up horizontally to allow yourself to move down into a gap instead of slightly clipping the block on the left or right side).



    I hope all that makes sense. I would write some pseudo-code but even as pseudo-code it would be quite complex :slight_smile: I may have missed something, but the basic idea of working with the grid system instead of against it should help.

Yes, i think this would be the best way, implementing a "simple" colliison detection this way.

And probably we'll go this way.



Thanks for this elaborated description, I'll check it out!



Cu

Snare