Good idea
I have hit a snag with Line intersect <> ball code from the archives though. When a new line is added for the collision test, the ball will deflect regardless of where the line ends
It's as if an imaginary line goes all the way across the screen
The RED line has been added in this screenshot. The ball bounces as shown and cannot 'pass by' where the line ends:

The line only works one way too. Depending which way the line is draw it is possible for the ball to pass straight through. After which it rebounds back as expected
Any other ways to resolve this? Help appreciated
What I have so far ..
MAIN SOURCE
####################################
IMPORT code "BallLineColl.bmx"
I have hit a snag with Line intersect <> ball code from the archives though. When a new line is added for the collision test, the ball will deflect regardless of where the line ends
It's as if an imaginary line goes all the way across the screen
The RED line has been added in this screenshot. The ball bounces as shown and cannot 'pass by' where the line ends:

The line only works one way too. Depending which way the line is draw it is possible for the ball to pass straight through. After which it rebounds back as expected
Any other ways to resolve this? Help appreciated
What I have so far ..
MAIN SOURCE
SuperStrict Framework BRL.GLMax2D Import BRL.Blitz Import "LineBallColl.bmx" ' Create gameMyObject ' CreateMyObject ' point p0 is its starting point in the coordinates x/y game.Create(640,480,80,0.0) game.myOb.airf = 0.982 game.myOb.b = 0.5 game.myOb.f = 0.995 game.myOb.r = 10 game.MyOb.lastTime = MilliSecs() game.myOb.p0 = New point game.myOb.p0.x = 350 game.myOb.p0.y = 120 ' vectors x/y components game.myOb.vx = 0.0; game.myOb.vy = 0.0; Local v:vector2d = New vector2d game.createWall(600,30,50,50,1,1) game.createWall(250,450,600,30,1,1) game.createWall(50,380,250,450,1,1) game.createWall(50,50,50,380,1,1) Global starttime% , timeout% Global mx# , my# Type edit Global mode%,line%,x%,y% End Type Graphics game.stageW,game.stageH ' ======================================================= Repeat Cls If MouseHit(2) edit.mode=~edit.mode ; FlushMouse If edit.mode=False edit.line=0 ; game.myob.vx=0 ; game.myob.vy=0 EndIf EndIf If edit.mode Editor Else GameUpdate EndIf Flip Until KeyDown(key_escape) ' ======================================================= Function GameUpdate() game.animate(game.myob) game.drawall(game.myob) If game.myob.moving=0 mx=MouseX() ; my=MouseY() SetColor $77,$77,$77 DrawLine game.myob.p0.x,game.myob.p0.y , mx,my If MouseHit(1) Local d#=Dist(mx,my,game.myob.p0.x,game.myob.p0.y) Local a#=Ang(mx,my,game.myob.p0.x,game.myob.p0.y) game.myob.vx=Sin(a)*(d/3.5) game.myob.vy=-Cos(a)*(d/3.5) EndIf EndIf Msg "LMB = Shoot RMB for editor" End Function Function Editor() Cls Msg "LMB = add line RMB= return to game" SetColor $aa,$44,$16 For Local v:vector2d = EachIn game.Walllist DrawLine v.p0.x,v.p0.y,v.p1.x,v.p1.y Next If edit.line=1 DrawLine edit.x,edit.y,MouseX(),MouseY() If MouseHit(1) Select edit.line Case 0 edit.x=MouseX() ; edit.y=MouseY() edit.line=1 Case 1 game.createWall(edit.x,edit.y,MouseX(),MouseY(),1,1) edit.line=0 End Select EndIf End Function Function Msg(t$) SetColor $ff,$ff,$ff DrawText t$,10,5 End Function Function Dist#(x1#,y1#,x2#,y2#) Local dx#=Abs(x1-x2) Local dy#=Abs(y1-y2) Return Sqr(dx*dx + dy*dy) End Function Function Ang#(x1#,y1#,x2#,y2#) Local dx#=x1-x2 Local dy#=y1-y2 Return 180.0-ATan2(dx,dy) End Function
####################################
IMPORT code "BallLineColl.bmx"
' Line/Ball collision and deflection - Jesse SuperStrict Import BRL.LinkedList Type point Field x# , y# End Type Type tgame Field stageW% , stageH% Field maxV# , gravity# Field bounce:vector2d Field MyOb:vector2d Global walllist:TList ' Method Create(W%,H%,V#,G#) walllist = CreateList() stageW = W ; stageH = H maxV = V ; gravity = G myOb = New vector2d End Method ' Method CreateWall(x1#,y1#,x2#,y2#,b#,f#) ' Create vector ' point p0 is its starting point in the coordinates x/y ' point p1 is its ending point in the coordinates x/y Local v:vector2d = New vector2d walllist.addlast(v) v.p0 = New point v.p0.x = x1 ; v.p0.y = y1 v.p1 =New point v.p1.x = x2 ; v.p1.y = y2 v.b = b ; v.f = f v.updateVector() End Method ' Method Animate(MyOb:vector2d) Local i%,w:vector2d,vb:vector2d,pen# ' add air resistance MyOb.vx :* MyOb.airf; MyOb.vy :* MyOb.airf; ' dont let it go over Max speed If (Myob.vx>game.maxV) MyOb.vx = game.maxV; Else If (MyOb.vx<-game.maxV) MyOb.vx = -game.maxV; EndIf If (MyOb.vy>game.maxV) MyOb.vy = game.maxV; Else If (MyOb.vy<-game.maxV) MyOb.vy = -game.maxV; EndIf ' update the vector parameters myob.updateObject(); ' check the walls For collisions For w = EachIn game.Walllist ' If we have hit the wall pen# = MyOb.r-myOb.findIntersection(w); If pen>=0 ' move MyObject away from the wall MyOb.p1.x :+ w.lx*pen MyOb.p1.y :+ w.ly*pen ' change movement vb = myob.bounce(w) MyOb.vx = vb.vx MyOb.vy = vb.vy EndIf Next ' reset MyObject To other side If gone out of stage If (MyOb.p1.x>game.stageW+MyOb.r) MyOb.p1.x = -Myob.r; ElseIf (Myob.p1.x<-Myob.r) MyOb.p1.x = game.stageW+Myob.r; EndIf If (Myob.p1.y>game.stageH+Myob.r) MyOb.p1.y = -Myob.r; ElseIf (Myob.p1.y<-Myob.r) MyOb.p1.y = game.stageH+Myob.r; EndIf ' draw it drawAll(Myob); ' make End point equal To starting point For Next cycle MyOb.p0 = MyOb.p1; ' save the movement without time MyOb.vx :/ MyOb.timeFrame MyOb.vy :/ MyOb.timeFrame End Method ' Method DrawAll(v1:vector2d) SetColor $77,$ff,$66 For Local v:vector2d = EachIn game.Walllist DrawLine v.p0.x,v.p0.y,v.p1.x,v.p1.y Next SetColor $ff,$ff,$40 DrawOval v1.p0.x-v1.r,v1.p0.y-v1.r,.. v1.r*2,v1.r*2 End Method ' End Type Type vector2d Field p0:point Field p1:point Field vx#,vy# , dx#,dy# , rx#,ry# , lx#,ly# Field Length# , timeFrame# , lastTime# Field r# , airf# , b# , f# , moving% ' Method updateObject() Local ThisTime#,time# ' find time passed from last update thisTime = MilliSecs(); time = (thisTime - lastTime) /100 ' we use time, Not frames To move so multiply movement vector with time passed vx :* time ; vy :* time; moving=True If (vx>-0.04 And vx<0.04) Then vx=0 If (vy>-0.04 And vy<0.04) Then vy=0 If (vx=0 And vy=0) Then moving=False ' add gravity, also based on time vy = vy+time*game.gravity; p1 = New point; ' find End point coordinates p1.x = p0.x+vx ; p1.y = p0.y+vy; ' length of vector Length = Sqr(vx*vx+vy*vy); ' normalized unti-sized components dx = vx/Length ; dy = vy/Length ' Right hand normal rx = -vy ; ry = vx; ' Left hand normal lx = vy ; ly = -vx; ' save the current time lastTime = thisTime; ' save time passed timeFrame = time; End Method ' Method updateVector:vector2d() ' x And y components ' End point coordinate - start point coordinate vx = p1.x-p0.x ; vy = p1.y-p0.y ' length of vector Length = Sqr(vx*vx+vy*vy); ' normalized unti-sized components If (Length>0) dx = vx/Length ; dy = vy/Length; Else dx = 0 ; dy = 0; EndIf ' Right hand normal rx = -dy ; ry = dx; ' Left hand normal lx = dy ; ly = -dx; Return Self End Method ' ' find New vector bouncing from v2 Method bounce:vector2d(v2:vector2d) ' projection of v1 on v2 Local proj1:vector2d = projectVector(Self, v2.dx, v2.dy); ' projection of v1 on v2 normal Local proj2:vector2d = projectVector(Self, v2.lx, v2.ly); Local proj:vector2d = New vector2d ' reverse projection on v2 normal proj2.Length = Sqr(proj2.vx*proj2.vx+proj2.vy*proj2.vy); proj2.vx = v2.lx*proj2.Length proj2.vy = v2.ly*proj2.Length ' add the projections proj.vx = f*v2.f*proj1.vx+b*v2.b*proj2.vx proj.vy = f*v2.f*proj1.vy+b*v2.b*proj2.vy Return proj End Method ' ' project vector v1 on unit-sized vector dx/dy Method projectVector:vector2d (v1:vector2d, dx#, dy#) ' find dot product Local dp# = v1.vx*dx+v1.vy*dy; Local proj:vector2d = New vector2d ' projection components proj.vx = dp*dx ; proj.vy = dp*dy; Return proj; End Method ' ' find intersection point of 2 vectors Method findIntersection# (v2:vector2d) ' vector between center of ball And starting point of wall Local v3:vector2d = New vector2d v3.vx = p1.x-v2.p0.x; v3.vy = p1.y-v2.p0.y; ' project this vector on the normal of the wall Local v:vector2d = projectVector(v3, v2.lx, v2.ly) ' find length of projection v.Length = Sqr(v.vx*v.vx+v.vy*v.vy) Return v.Length End Method ' End Type Global game:tgame = New tgame