`Collision Demo
sync on
sync rate 60
TYPE lin
    x1 AS FLOAT
    y1 AS FLOAT
    x2 AS FLOAT
    y2 AS FLOAT
    c AS BOOLEAN
    used AS BOOLEAN
ENDTYPE
TYPE ball
    x AS FLOAT
    y AS FLOAT
    oldx AS FLOAT
    oldy AS FLOAT
    xv AS FLOAT
    yv AS FLOAT
    xi AS FLOAT
    vi AS FLOAT
    radius AS INTEGER
ENDTYPE
 
GLOBAL dl_timer
GLOBAL l_marker
GLOBAL mx1#
GLOBAL my1#
GLOBAL mx2#
GLOBAL my2#
GLOBAL grav AS FLOAT
    grav = 1.0
GLOBAL b AS ball
GLOBAL internal = 1
DIM lhist(100) as lin
 
dl_timer = timer() + 50 
l_marker = 1
b.radius = 5
 
do
cls
    set cursor 0,0
    ink rgb(255,255,255),0
    print "Hold right mouse button to drag the ball. Release to drop."
    print "Hold left mouse button to draw lines. Press space to clear."
    print b.xv
    print b.yv;" (";b.oldy - b.y;")"
    print BallLineCollision()
    print grav
 
    DrawLine()
    UpdateLines()
    ControlBall()
    UpdateBall()
 
    if spacekey() = 1 then ClearAllLines()
sync
loop
`----------------------------------------------------------
function DrawLine()
 
    if mouseclick() <> 1
        dl_timer = timer() + 50
        mx1# = mousex()
        my1# = mousey()
    endif
 
    if timer() > dl_timer
        mx2# = mousex()
        my2# = mousey()
        dl_timer = timer() + 50
        lhist(l_marker).x1 = mx1#-1
        lhist(l_marker).y1 = my1#+1
        lhist(l_marker).x2 = mx2#
        lhist(l_marker).y2 = my2#
        lhist(l_marker).used = 1
 
        if l_marker < 100
            inc l_marker
        else
            l_marker = 1
        endif
        mx1# = mousex()
        my1# = mousey()
    endif
endfunction
 
function UpdateLines()
    for i = 1 to 100
        if lhist(i).used = 1
            ink rgb(255,0,0),rgb(255,0,0)
            for j = 0 to 5 
                if internal = 1
                    if lhist(i).c = 1
                        ink rgb(255,255,0),0
                    endif
                    if lhist(i).c = 2
                        ink rgb(0,0,255),0
                    endif
                endif
                if j > 3
                    ink rgb(255,255,255),0
                endif
                line lhist(i).x1,lhist(i).y1+j,lhist(i).x2,lhist(i).y2+j
            next j
        endif
    next i
endfunction
 
function ControlBall()
    remstart
    Remember, from left to right, positive slopes go uphill, negative slopes down
    0 is a flat plain
    [infinite] is a vertical line
 
    Also, physics must be done as so: 
    velocity = pixels per loop, increases with slope
    inertia = easy, just use curvevalue
    remend
    b.oldx = b.x
    b.oldy = b.y
 
    b.x = b.x + b.xv
    b.yv = (b.oldy - b.y)/10
    col = BallLineCollision()
 
    if col = 0
        if (b.y+6) > screen height() or (b.x + 6) > screen width() or (b.x - 6) < 0
            col = 1
        endif
    endif
 
    `Velocity Deterioration / Friction
    if b.xv > 0
        b.xv = b.xv - 0.00001
    endif  
 
    if col = 0
        `Gravity
        if grav = 0 then grav = 1
        if grav < 5
            grav = grav * 1.04
        endif
        b.yv = b.yv + grav
 
        `Y-Velocity
        b.y = b.y + b.yv  
    else 
        grav = 1       
        b.xv = b.xv + (BallLineSlope()/5)
        if BallLineCollisionY() <> -1
            b.y = BallLineCollisionY() - 5
        endif
    endif    
 
    if mouseclick() = 2
        b.x = mousex()
        b.y = mousey()
        b.xv = 0
    endif
endfunction
 
function UpdateBall()
    ink rgb(0,255,0),0
    circle b.x,b.y,b.radius
endfunction
 
function BallLineCollision()
    remstart
    to find a given line's height at any point we
    use the equation of a line. Since both the line's starting point
    and the ball's landing points SHOULD be points on the line, we use
    y = mx+b, solving for y.
    remend
    LOCAL hit
    hit = 0
 
    `Find the missing y coord
    for i = 1 to 100
        lhist(i).c = 0
        if lhist(i).x1 < b.x and lhist(i).x2 > b.x : `If the ball is over that line
 
            ycol = (lhist(i).y1-lhist(i).y2)/(lhist(i).x1-lhist(i).x2)*b.x + yint((lhist(i).y1-lhist(i).y2)/(lhist(i).x1-lhist(i).x2),lhist(i).x1,lhist(i).y1)            
            `ycol = slope*ballX + y-intercept(slope,xpoint,ypoint)
            if ycol > (b.y+5) : `If that line is below the ball
                hit = 0
            else
                if ycol < (b.y-5) : `If that line is above the ball
                    hit = 0
                else
                    if abs(ycol-b.y) =< 6 : `The ball is right there
                        hit = i
                        lhist(i).c = 1
                        grav = 0
                    endif
                endif
            endif
        endif
    next i
 
endfunction hit
 
function BallLineCollisionY()
    LOCAL hit AS FLOAT
    hit = 0
    lhist(i).c = 0
 
    `Find the missing y coord
    for i = 1 to 100
        if lhist(i).x1 < b.x and lhist(i).x2 > b.x : `If the ball is over that line
 
            ycol = (lhist(i).y1-lhist(i).y2)/(lhist(i).x1-lhist(i).x2)*b.x + yint((lhist(i).y1-lhist(i).y2)/(lhist(i).x1-lhist(i).x2),lhist(i).x1,lhist(i).y1)            
            `ycol = slope*ballX + y-intercept(slope,xpoint,ypoint)
 
            if ycol > (b.y+5)
                hit = -1
            else
                if ycol < (b.y-5) : `The ball cannot fly. Return nothing if the line is above
                    hit = -1
                else
                    if abs(ycol-b.y) =< 6 : `The ball is right there
                        hit = ycol
                    endif
                endif
            endif
        endif
    next i
endfunction hit
 
function BallLineSlope()
    `Finds the slope of the line the ball is over
    LOCAL hit AS FLOAT
    hit = 0
 
    `Find the missing y coord
    for i = 1 to 100
        if lhist(i).x1 < b.x and lhist(i).x2 > b.x : `If the ball is over that line         
            hit = (lhist(i).y1-lhist(i).y2)/(lhist(i).x1-lhist(i).x2)
        endif
    next i
 
endfunction hit
 
function yint( slope AS FLOAT, x AS FLOAT, y AS FLOAT )
    LOCAL r AS FLOAT
    r = y - slope*x
endfunction r
 
function ClearAllLines()
    for i = 1 to 100
        lhist(i).used = 0
        lhist(i).x1 = 0
        lhist(i).y1 = 0
        lhist(i).x2 = 0
        lhist(i).y2 = 0
    next i
endfunction