[SOLVED] How do I make a true circular collision (wall bounce)?

  • I have a ball with 8 collision points with bullet behavior and "Bounce off solids" checked. However, when the ball bounces around, since the collision points don't make a true circle, it's not entirely accurate and will sometimes move up and down as it's bouncing from left to right. I've tried increasing the number of collision points, but it's still not accurate.

    Should I get rid of "Bounce off solids" altogether and just detect the direction/angle it's travelling and calculate the ricochet angle? If so, anyone know how I would go about doing that? Thanks!

  • The bullet behaviour provides a reasonable approximation for bouncing, but it's not perfect.

    If you can get away with simulating the ball as a particle ( no size ) you can do a good job by using Line of Sight to raycast the bullet path. Although I don't think this will work if your using gravity on the ball, as the path changes from a ray to curve in most situations. You can make some tweaks to this to make it behave a little more like a circle, but it's not ideal for most situations.

  • You can try raycasting feature of LoS behavior. Every X seconds cast a ray from the ball in the direction it's moving. For example, to cast a 100px ray:

    Cast ray from Ball.x, Ball.y 
    to Ball.X+100*cos(Ball.Bullet.angleOfMotion), Ball.Y+100*sin(Ball.Bullet.angleOfMotion)
    

    If the ray intersected solid object, save Ball.LineOfSight.ReflectionAngle in a variable.

    On collision with the wall, set angle of motion to that variable.

  • Or switch to the physics behavior instead and set it to circle. May be an overkill for what you try to do though.

  • Nepeo dop2000 Thanks for the LoS and Raycasting tips. However, it doesn't work too well. You can see it in action here: https://www.dropbox.com/s/g6scpyfvllal7hb/ballBounceTest.c3p?dl=0. Seemed promising, but the balls go through the boxes and walls at varying points. The balls are not ricocheting correctly either.

    Similar thread and info on how to achieve, but this is beyond my knowledge. Any help is greatly appreciated:

    Construct thread on using box with radius detection. No idea how to detect collision though.

    https://www.construct.net/en/forum/construct-2/how-do-i-18/circle-collision-radius-49970?kws=circle%2bcollision

    Simulating collisions article:

    https://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769

    https://code.tutsplus.com/tutorials/quick-tip-collision-reaction-between-a-circle-and-a-line-segment--active-10679

    WackyToaster Tried physics as well, but it still uses the collision box heavily and is not very accurate. I'm looking for a non-collision box solution as Construct currently doesn't have a true circle collision detection.

  • Well, first of all, you can't use one global variable if you have multiple balls - they all have different reflection angles.

    Also, with balls moving that fast you have to use stepping. Take a look:

    dropbox.com/s/ei029r65pysf4hj/ballBounceTest.c3p

    It works better, but balls can pass through corners of red squares. It's because the ray is cast from the center and misses the square. You'll probably need to cast two more rays (blue lines):

    I think it will be easier to use Physics here. Set "Bullet=yes" and "Collision mask=Circle" in Physics properties and you should get perfectly bouncing balls.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • dop2000 I can't believe I forgot making the global variable a instance instead! You're right about the raycasting issue. I've added three just to see what happens and it's all kinds of chaos.

    Tried physics again, but now all the balls collide with each other. Wish there was some better way to achieve this as physics may be a bit overkill for what I'm trying to do.

    Physics:

    https://www.dropbox.com/s/jcef2rl365hiahq/ballBounceTest4-physics.c3p?dl=0

  • You can disable Physics collisions between balls. "Physics enable/disable collisions" action.

  • WackyToaster dop2000 Thank you. You were both right and it seems to work pretty well. Thanks!

  • Here's one way to do it. It basically just pushes balls out of each other by using the distance between them. Pushing the balls out of the wall is done by comparing the distances from the corners and edges of the wall's collision polygon and using the smallest distance. It defines the polygon with imagepoints as you can't access the actual collision polygon used by construct.

    Anyways, the value of doing it this way is we can then push the balls out of other balls and walls perfectly, plus we get the collision normal to then do a perfect bounce.

    dropbox.com/s/8t7mugpm6d8u5e9/ballvsConvex.capx

    A few usage notes:

    In the capx I just move the balls with two instance variables for the velocity (vx, xy) and one event to do the motion. It is equivalent to bullet motion.

    The bounce calculation is based on vx and vy, but if you wanted to do the movement with another behavior, you would disable the motion event and set vx and vy before the two events and set the behavior velocities afterwards. Here are some formulas to convert velocities:

    vx = speed*cos(angleOfmotion)
    vy = speed*sin(angleOfmotion)
    
    speed = distance(0,0,vx,vy)
    angleOfMotion = angle(0,0,vx,vy)

    Other thoughts

    It's a similar result to using the physics behavior (you can tell a physics behavior object to use a circle instead of the collision polygon). The bouncing angle has been more consistent from what I've tested. That is probably due to other things the physics behavior does to resolve collisions in a softer way in some cases.

    As with the physics behavior this solves the bounce after the objects are overlapping. Basically on overlap, push out, calculate bounce. Good enough almost always. A more perfect albeit slower solution would be to calculate the exact time of the collisions between each frame and using those points to solve for the bounces.

  • Lumicreative.com ah yeah I was suggesting a slightly more intensive solution, which is to basically replace the bullet behaviour with raycasting. I think in your example is a little broken, with some tweaks it would probably work after a fashion. But under some circumstances it would fail, when passing near to an object the center of the ball may not pass through a box, but the ball would overlap with the box. In that situation the raycast would never report a collision, but the bullet behaviour would.

    This is your project adapted to what I meant. It works well, but it will occasionally not collide when it appears to due to being considered a particle. Using a smaller ball makes it look more convincing. There's some tricks you can do to simulate the ball as a polygon, but you end up back with the problem of flat edges vs curved.

    You can kind of do collision with other ball instances, but it causes some strange collisions because we have a single position buffer which we are read/writing to at the same time.

    I was thinking you could also solve this using signed distance fields and raymarching ( subtly different to what the LOS plugin uses ) but you would basically have to write all this logic from scratch.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)