'Snooker balls bouncing like they should be. ;*) 'Relsoft 2003 'http://rel.betterwebber.com 'thanks to: Hugo Elias for writting that lil tute. Very *vague* I mght add. ;*) ' 'Notes: No friction is implemented as my daughter is... well, I have to cook ' her breakfast. ;*) 'Ported to FB June 20, 2006 'Keys: 'LEFT and RIGHT arrows = change direction 'SPACE = shoot 'ESC = QUIT DEFINT A-Z TYPE ballType x AS SINGLE 'the x coord y AS SINGLE xv AS SINGLE yv AS SINGLE speed AS SINGLE '??? mass AS SINGLE 'the mass angle AS INTEGER 'angle of direction END TYPE DECLARE SUB Normalize (nx!, ny!, X1!, Y1!, X2!, Y2!) DECLARE FUNCTION Collide% (Ball() AS balltype) DECLARE FUNCTION Dot! (ax!, ay!, bx!, by!) CONST FALSE = 0, TRUE = NOT FALSE CONST PI = 3.141593 'wanna eat pie? CONST FRICTION = .001 DIM balls(1) AS ballType 'Initialise balls balls(0).x = 200 balls(0).y = 170 balls(0).xv = 0 balls(0).yv = 0 balls(0).speed = 2.6 balls(0).mass = 1.5 balls(0).angle = 218 balls(1).x = 100 balls(1).y = 80 balls(1).xv = 0 balls(1).yv = 0 balls(1).speed = 0 balls(1).mass = 2.5 balls(1).angle = 30 CLS SCREEN 13,8,2 screenset 1,0 'Target the ball DO LINE (0, 0)-(319, 199), 0, BF 'cls FOR i% = 0 TO 1 'draw em ballz x = balls(i%).x y = balls(i%).y CIRCLE (x, y), 10, i% + 5 PAINT (x, y), i% + 5 NEXT i% tx% = COS(balls(0).angle * PI / 180) * 50 'Line of target ty% = SIN(balls(0).angle * PI / 180) * 50 LINE (balls(0).x, balls(0).y)-(balls(0).x + tx%, balls(0).y + ty%), 15, , &HFAFA screensync screencopy IF MULTIKEY(&h4B) then balls(0).angle = (balls(0).angle - 1) MOD 360 IF MULTIKEY(&h4D) then balls(0).angle = balls(0).angle + 1 MOD 360 LOOP WHILE NOT MULTIKEY(&h39) 'Set initial ball vectors balls(0).xv = COS(balls(0).angle * PI / 180) * balls(0).speed balls(0).yv = SIN(balls(0).angle * PI / 180) * balls(0).speed 'Bouncy!!!! dim xva!,xvb!,yva!,yvb!,impulsex!,impulsey! DO LINE (0, 0)-(319, 199), 0, BF 'cls FOR i% = 0 TO 1 'move the balls balls(i%).x = balls(i%).x + balls(i%).xv 'x move balls(i%).y = balls(i%).y + balls(i%).yv 'y move 'the next if then else clause checks to see if the balls are 'inside the screen of out of bounds, they bounce IF balls(i%).x < 10 THEN balls(i%).xv = -balls(i%).xv ELSEIF balls(i%).x > 310 THEN balls(i%).xv = -balls(i%).xv ELSE END IF IF balls(i%).y < 10 THEN balls(i%).yv = -balls(i%).yv ELSEIF balls(i%).y > 190 THEN balls(i%).yv = -balls(i%).yv ELSE END IF balls(i%).xv = balls(i%).xv - balls(i%).xv * FRICTION balls(i%).yv = balls(i%).yv - balls(i%).yv * FRICTION x = balls(i%).x y = balls(i%).y CIRCLE (x, y), 10, i% + 5 'Draw the balls PAINT (x, y), i% + 5 NEXT i% IF Collide(balls()) = -1 THEN GOSUB calcVectors 'The ball to ball algo balls(0).xv = xva! 'set new velocities/vectors balls(0).yv = yva! balls(1).xv = xvb! balls(1).yv = yvb! END IF screensync screencopy LOOP WHILE NOT MULTIKEY(&h1) END calcVectors: 'Notes: 'vectors: Impact,Impulse, ' balla,ballb,newa,newb 'Points: p1,p2 'Real Floats: Mass1,Mass2,Impactspeed 'Formula: '1. Impact= balla-ballb 'vector subtaction '2. impulse = Normalize(p1,p2) 'see normalize sub '3. impactspeed = Dot!(impact,impulse) '4. newimpulse=impulse*impactspeed*mass1*mass2 '5. newa=balla+newimpulse/mass1 '6. newb=ballb-newimpulse/mass2 'PS the divide by 2 is for the frictionless model. ;*) impactx! = balls(1).xv - balls(0).xv impacty! = balls(1).yv - balls(0).yv Normalize impulsex!, impulsey!, balls(0).x, balls(0).y, balls(1).x, balls(1).y impactSpeed! = Dot!(impactx!, impacty!, impulsex!, impulsey!) impulsex! = impulsex! * impactSpeed! * balls(0).mass * balls(1).mass / 2 impulsey! = impulsey! * impactSpeed! * balls(0).mass * balls(1).mass / 2 xva! = balls(0).xv + impulsex! / balls(0).mass yva! = balls(0).yv + impulsey! / balls(0).mass xvb! = balls(1).xv - impulsex! / balls(1).mass yvb! = balls(1).yv - impulsey! / balls(1).mass RETURN FUNCTION Collide (Ball() AS ballType) 'returns id the ball collided using the distance formula. 'can be optimized a lot!!! Collide = 0 dx! = Ball(1).x - Ball(0).x dy! = Ball(1).y - Ball(0).y dist! = SQR(dx! ^ 2 + dy! ^ 2) IF dist! <= 20 THEN Collide = -1 END IF END FUNCTION FUNCTION Dot! (ax!, ay!, bx!, by!) 'returns the dot product between 2 vectors a and b. Dot! = (ax! * bx!) + (ay! * by!) END FUNCTION SUB Normalize (nx!, ny!, X1!, Y1!, X2!, Y2!) 'normalizes the components of a vector derived from 2 points (x1,y1) and '(x2,y2) dx! = X2! - X1! dy! = Y2! - Y1! dist! = SQR(dx! ^ 2 + dy! ^ 2) nx! = dx! / dist! ny! = dy! / dist! END SUB