How do I make a projected line for pool/billard game?

  • Hey guys.

    I can't get it together.

    This is how my game currently looks

    i.imgur.com/oR2SjIE.png

    What I wanted to do is show a projected line for the red ball (white short line). So If change the angle the line should show the direction the red ball goes to. I thought it would be easy but I just don't know how to do it.

    I think something like calculate the angle the balls are hitting each other to calculate their direction?

    Ignore the green line, its just to check collision with any red ball.

    Would be nice if someone has an idea which I could may understand :D

    Regards,

    Kraudi

  • I think this thread would help me a lot if the image there is still online

    construct.net/en/forum/construct-2/how-do-i-18/detect-collision-point-balls-84860

    I think this is what I need to get the coordinate of the impact between the 2 balls so I can calculate the angle of motion.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I re-shared the images in that link. They are ways to approximate the collision point once the balls are overlapping.

    You still need the point when the balls collide. The two ways are either to use a loop to move the one ball forward by steps till they collide, or you could raycast from the white ball to the red.

    the loop way could be something like this:

    every tick:

    -- testBall: set position to whiteball

    -- testball: set angle to whiteball.angleofmotion

    repeat 1000 times

    testball: isn't overlapping redball

    -- testball: move forward 1 pixel

    The ray cast method it more complex but more percise. Basically a ray from the whiteball against a circle at the redball's position with a radius of whiteball.radius+redball.radius. I couldn't find where I've done that before, but it's a formula you can find online.

    Anyways after that you can calculate the bounce. This is pool so we could do perfectly elastic bounces. You really only need the normal (angle from one ball to another) and the velocity. The formula is pretty standard in physics. Here is a possible example, and a link to an article about it.

    construct.net/en/forum/construct-2/general-discussion-17/approaching-pool-ball-movement-56649

    construct.net/en/forum/construct-2/how-do-i-18/fake-physics-collision-123031

    In the end though it may not precisely match the path the balls will move with the physics behavior due to differences in frame time causing the collision to be at slightly different times.

  • Thank you very much R0J0hound

    I tried doing it with the loop and it works but it's very inacurate. DOn't know If I've made some mistake but you can have a look in the demo here.

    polyth-game.com/builds/snooker

    (You can move red balls with pressed right mouse)

    Also this is the code I've made.

    i.imgur.com/WOWk561.png

    I've also added more collision points to the red balls so it is more accurate but doesn't changed much.

  • Ok I changed some stuff it is definitely more accurate. I did it with 'move 1px forward" you mentioned.

    Heres the v2 demo

    polyth-game.com/builds/snooker2

    Though it's still not good enough because if you play the red ball just thinly the line indicates that you will not hit the ball. Nevertheless the white ball still hits the red ball in the end so that means some calculation is not 'good enough'. Also the shot line sometimes goes the wrong way.

    If you have some minutes would you mind looking into the c3 file itself if I share em?

    Regards and tnx!

  • Kraudi there's a technique called Signed Distance Fields ( SDF ) which you could use here to help you. The basic idea is that you have a function that returns the distance from any position to the closest point on the surface of an object. If the position is inside the object then the distance is negative ( hence "Signed" distance fields ). Circles are probably the easiest SDF, and by the looks of it you only need circles. So that's convenient! Here's the function for a circle written in JS, it's mostly simple maths so should be easy enough to read.

    function circleSDF (point_x, point_y, center_x, center_y, radius) {
    	let dx = point_x - center_x;
    	let dy = point_y - center_y;
    	return Math.sqrt(dx * dx + dy * dy) - radius;
    }
    
    function distance_to_closest_ball (cueball) {
    	let smallest_distance = Infinity;
    
    	for (const ball of balls) {
    		let distance = circleSDF(cueball.x, cueball.y, ball.x, ball.y, cueball.radius + ball.radius);
    
    		if (distance < smallest_distance) {
     			smallest_distance = distance;
     		}
     	}
    
     	return smallest_distance;
    }
    

    The trick here is that you can use your "move along the line" technique with that function. Before moving you can check what the shortest distance to any ball is. You now know that it's safe to move that distance along the line, as there are no objects within that radius of the cue ball. Repeat the check distance, and move along line until the check distance tells you the distance is effectively 0. You will now be at exactly the position the cue ball collides with another ball.

    There's a few minor gotchas. First is that you need to keep count of how far you have moved along the line, as if you don't hit anything the loop will continue forever. Second if you do get a collision the distance is likely to be a very small number ( like 0.0000000007 ) instead of zero because of floating point error, so you should check if the distance is under 0.0001 or something. Lastly the circleSDF function assumes the point is particle ( no size ) so it doesn't take into account the radius of the cue ball. The way I resolved this above is to pass the radius of the cueball and the other ball added together instead.

    There's a fair amount of information about SDF techniques online, but it's mostly about using them for 3D rendering... which is quite complicated. Just so your aware.

  • Thank yo uvery much Nepeo

    I'll look into that because that sounds interesting. Hope to figure something out and hope it isn't too complex.

  • Best of luck, feel free to ask me if you have any questions.

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