Sunday, March 5, 2017

Monkey-X - Collision - Line vs Oriented Rectangle - code example


' From the book '2d game collision detection'
' line vs oriented rectangle collision


Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' Here the line vs oriented rectangle collision 
    Function line_oriented_rectangle_collide:Bool(    l:line,
                                                    r:orientedrectangle)
        Local lr:rectangle
        lr = New rectangle(    New vector2d(0,0),    
                            multiply_vector(r.halfextend,2))
        
        Local l1:line = New line(    New vector2d(0,0),
                                    New vector2d(0,0))
        l1.base = subtract_vector(l.base,r.center)
        l1.base = rotate_vector(l1.base,-r.rotation)
        l1.base = add_vector(l1.base,r.halfextend)
        l1.direction = rotate_vector(l.direction,-r.rotation)
        
        Return line_rectangle_collide(l1,lr)
    End Function
    ' The rectangle vs Line Collision
    ' needed for line vs oriented rectangle collion
    Function line_rectangle_collide:Bool(l:line,r:rectangle)
        Local n:vector2d = rotate_vector_90(l.direction)
        
        Local dp1:Float,dp2:Float
        Local dp3:Float,dp4:Float
        
        Local c1:vector2d = r.origin
        Local c2:vector2d = add_vector(c1,r.size)
        Local c3:vector2d = New vector2d(c2.x,c1.y)
        Local c4:vector2d = New vector2d(c1.x,c2.y)
        
        c1 = subtract_vector(c1,l.base)
        c2 = subtract_vector(c2,l.base)
        c3 = subtract_vector(c3,l.base)
        c4 = subtract_vector(c4,l.base)                        
        
        dp1 = dot_product(n,c1)
        dp2 = dot_product(n,c2)
        dp3 = dot_product(n,c3)
        dp4 = dot_product(n,c4)
        
        Return     (dp1 * dp2 <= 0) Or
                (dp2 * dp3 <= 0) Or
                (dp3 * dp4 <= 0)
    End Function    
    '
    ' helper functions
    '

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function  
        
    Function rotate_vector_90:vector2d(v:vector2d)
        Local r:vector2d = New vector2d()
        r.x = -v.y
        r.y = v.x
        Return r
    End Function
        
    Function multiply_vector:vector2d(v:vector2d,scalar:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * scalar
        r.y = v.y * scalar
        Return r
    End Function

    ' Here is the function that rotates a vector. It returns the
    ' new rotated vector.
    '
    Function rotate_vector:vector2d(v:vector2d,degrees:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * Cos(degrees) - v.y * Sin(degrees)
        r.y = v.x * Sin(degrees) + v.y * Cos(degrees)
        Return r
    End Function  

    Function add_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d(0,0)
        r.x = a.x + b.x
        r.y = a.y + b.y
        Return r
    End Function            

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class

Class line
    ' base is a vector which holds the origin
    ' of the line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
    Method draw()
        DrawLine base.x,base.y,direction.x,direction.y
    End Method    
End Class

Class orientedrectangle
    Field center:vector2d
    Field halfextend:vector2d
    Field rotation:Float
    Method New(center:vector2d,halfextend:vector2d,rotation:Float)
        Self.center = center
        Self.halfextend = halfextend
        Self.rotation = rotation
    End Method
    Method draw()
        Local v1:vector2d,v2:vector2d,v3:vector2d,v4:vector2d
        'topside
        v1 = New vector2d(-halfextend.x,-halfextend.y)
        v2 = New vector2d(halfextend.x,-halfextend.y)
        v1 = rotate_vector(v1,rotation)
        v2 = rotate_vector(v2,rotation)
        v1.x += center.x
        v1.y += center.y
        v2.x += center.x
        v2.y += center.y
        ' rightside
        v3 = New vector2d(halfextend.x,halfextend.y)
        v3 = rotate_vector(v3,rotation)
        v3.x += center.x
        v3.y += center.y
        ' bottom side
        v4 = New vector2d(-halfextend.x,halfextend.y)
        v4 = rotate_vector(v4,rotation)
        v4.x += center.x
        v4.y += center.y
        DrawLine v1.x,v1.y,v2.x,v2.y
        DrawLine v2.x,v2.y,v3.x,v3.y
        DrawLine v3.x,v3.y,v4.x,v4.y
        DrawLine v4.x,v4.y,v1.x,v1.y
    End Method    
    Function rotate_vector:vector2d(v:vector2d,degrees:Float)
        Local r:vector2d = New vector2d()
           r.x = v.x * Cos(degrees) - v.y * Sin(degrees)
            r.y = v.x * Sin(degrees) + v.y * Cos(degrees)
        Return r
    End Function    
End Class



' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Field angle:Float=0
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        angle+=1
        If angle > 360 Then angle=0
    End Method
    Method OnRender()
        Cls 0,0,0
        SetColor 255,255,255

        'set up the line
        Local line1:line = New line(    New vector2d(0,0),
                                        New vector2d(MouseX,MouseY))
        'set up the oriented rectangle (base, halfextend(size),angle)
        Local orect1:orientedrectangle
        orect1 = New orientedrectangle(    New vector2d(320,200),
                                        New vector2d(100,50),
                                        angle)

        ' Here we test for collision
        If col.line_oriented_rectangle_collide(line1,orect1)
            DrawText "Line vs Oriented Rectangle Collision",0,0
        Else
            DrawText "Line vs Oriented Rectangle NO Collision",0,0
        End If

        ' Here we draw the line and oriented
        ' rectangle.
        line1.draw
        orect1.draw
        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Collision - Line vs Line Segment - code example


' From the book '2d game collision detection'
' line vs line segment collision

#rem
If a line collides with a segment you only need to know
if the segments end points lie on the same side 
of the line. If they do then a collision is
impossible.
#end

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    Function line_segment_collide:Bool(l:line,s:segment)
        Return Not on_one_side(l,s)
    End Function    

    '
    ' helper functions
    '
    Function on_one_side:Bool(axis:line,s:segment)
        Local d1:vector2d = subtract_vector(s.point1,axis.base)
        Local d2:vector2d = subtract_vector(s.point2,axis.base)
        Local n:vector2d = rotate_vector_90(axis.direction)
        Return dot_product(n,d1) * dot_product(n,d2) > 0
    End Function

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function

    Function rotate_vector_90:vector2d(v:vector2d)
        Local r:vector2d = New vector2d()
        r.x = -v.y
        r.y = v.x
        Return r
    End Function

End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class line
    ' base is a vector which holds the origin
    ' of the line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
    Method draw()
        DrawLine base.x,base.y,direction.x,direction.y
    End Method    
End Class

Class segment
    ' point1 and point2 are two vectors.
    ' A vector has a x and y coordinate.
    Field point1:vector2d
    Field point2:vector2d
    Method New(point1:vector2d,point2:vector2d)
        Self.point1 = point1
        Self.point2 = point2
    End Method
    Method draw()
        DrawLine point1.x,point1.y,point2.x,point2.y
    End Method
End Class



' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
        Cls 0,0,0
        SetColor 255,255,255

        Local line1:line = New line(    New vector2d(0,0),
                                        New vector2d(MouseX,MouseY))
        Local segline1:segment = New segment(    New vector2d(100,200),
                                                New vector2d(400,100))

        ' Here we test for collision
        If col.line_segment_collide(line1,segline1)
            DrawText "Line vs Line Segment Collision",0,0
        Else
            DrawText "Line vs Line Segment NO Collision",0,0
        End If

        line1.draw
        segline1.draw
        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey -X - Collision - Point vs Oriented Rectangle - code example


' From the book '2d game collision detection'
' point vs oriented rectangle collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' The point vs oriented rectangle collision
    Function oriented_rectangle_point_collide:Bool(    r:orientedrectangle,
                                                    p:vector2d)
        Local lr:rectangle
        lr = New rectangle(    New vector2d(0,0),
                            multiply_vector(r.halfextend,2))        
        Local lp:vector2d = subtract_vector(p,r.center)
        lp = rotate_vector(lp,-r.rotation)
        lp = add_vector(lp,r.halfextend)
        
        Return point_rectangle_collide(lp,lr) 
    End Function                                                    

    ' The point vs rectangle Collision
    ' needed for point in oriented rectangle collision
    Function point_rectangle_collide:Bool(p:vector2d,r:rectangle)
        Local left:Float = r.origin.x
        Local right:Float = left + r.size.x
        Local bottom:Float = r.origin.y
        Local top:Float = bottom + r.size.y        
        Return     left <= p.x And
                bottom <= p.y And
                p.x <= right And
                p.y <= top    
    End Function
    '
    ' helper functions
    '
    Function multiply_vector:vector2d(v:vector2d,scalar:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * scalar
        r.y = v.y * scalar
        Return r
    End Function

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    ' Here is the function that rotates a vector. It returns the
    ' new rotated vector.
    '
    Function rotate_vector:vector2d(v:vector2d,degrees:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * Cos(degrees) - v.y * Sin(degrees)
        r.y = v.x * Sin(degrees) + v.y * Cos(degrees)
        Return r
    End Function

    Function add_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d(0,0)
        r.x = a.x + b.x
        r.y = a.y + b.y
        Return r
    End Function   
        
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class

Class orientedrectangle
    Field center:vector2d
    Field halfextend:vector2d
    Field rotation:Float
    Method New(center:vector2d,halfextend:vector2d,rotation:Float)
        Self.center = center
        Self.halfextend = halfextend
        Self.rotation = rotation
    End Method
    Method draw()
        Local v1:vector2d,v2:vector2d,v3:vector2d,v4:vector2d
        'topside
        v1 = New vector2d(-halfextend.x,-halfextend.y)
        v2 = New vector2d(halfextend.x,-halfextend.y)
        v1 = rotate_vector(v1,rotation)
        v2 = rotate_vector(v2,rotation)
        v1.x += center.x
        v1.y += center.y
        v2.x += center.x
        v2.y += center.y
        ' rightside
        v3 = New vector2d(halfextend.x,halfextend.y)
        v3 = rotate_vector(v3,rotation)
        v3.x += center.x
        v3.y += center.y
        ' bottom side
        v4 = New vector2d(-halfextend.x,halfextend.y)
        v4 = rotate_vector(v4,rotation)
        v4.x += center.x
        v4.y += center.y
        DrawLine v1.x,v1.y,v2.x,v2.y
        DrawLine v2.x,v2.y,v3.x,v3.y
        DrawLine v3.x,v3.y,v4.x,v4.y
        DrawLine v4.x,v4.y,v1.x,v1.y
    End Method    
    Function rotate_vector:vector2d(v:vector2d,degrees:Float)
        Local r:vector2d = New vector2d()
           r.x = v.x * Cos(degrees) - v.y * Sin(degrees)
            r.y = v.x * Sin(degrees) + v.y * Cos(degrees)
        Return r
    End Function    
End Class


' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    ' This variable we use to rotate
    ' the oriented rectangle.
    Field angle:Float=0
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        angle+=1
        If angle>359 Then angle = 0
    End Method
    Method OnRender()
        Cls 0,0,0
        SetColor 255,255,255

        Local center:vector2d = New vector2d(320,200)
        Local halfdivide:vector2d = New vector2d(100,50)
        Local orect1:orientedrectangle = New orientedrectangle(    center,
                                                                halfdivide,
                                                                angle)
    
        ' Here we create a vector with the mouse it's coordinates.
        ' We use this point to test collsion with the orect.
        Local point:vector2d = New vector2d(MouseX,MouseY)        

        ' Here we test for collision
        If col.oriented_rectangle_point_collide(    orect1,
                                                    point)
            DrawText "Point vs Oriented Rect Collision",0,0
        Else
            DrawText "Point vs Oriented Rect NO Collision",0,0
        End If
                    
        orect1.draw
    
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Saturday, March 4, 2017

Monkey-X - Collision - Rectangle vs Line Segment - code example


' From the book '2d game collision detection'
' rectangle vs Line segment collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' Rectangle vs Line Segment Function
    Function rectangle_segment_collide:Bool(r:rectangle,s:segment)
        ' First we test the line vs rectangle collision
        Local sline:line = New line()
        sline.base = s.point1
        sline.direction = subtract_vector(    s.point2,
                                            s.point1)        
        If (Not line_rectangle_collide(sline,r)) Then
            Return False
        End If
        
        ' Here we test the ranges of the line
        ' with the rectangle
        
        Local rrange:range = New range()
        Local srange:range = New range()
        rrange.minimum = r.origin.x
        rrange.maximum = r.origin.x + r.size.x
        srange.minimum = s.point1.x
        srange.maximum = s.point2.x
        srange = sort_range(srange)
        If(Not overlapping_ranges(rrange,srange)) Then
            Return False
        End If

        rrange.minimum = r.origin.y
        rrange.maximum = r.origin.y + r.size.y
        srange.minimum = s.point1.y
        srange.maximum = s.point2.y
        srange = sort_range(srange)
        Return overlapping_ranges(rrange,srange)
                
    End Function
    
    ' The rectangle vs Line Collision
    ' needed for rectangle vs line segment
    Function line_rectangle_collide:Bool(l:line,r:rectangle)
        Local n:vector2d = rotate_vector_90(l.direction)
        
        Local dp1:Float,dp2:Float
        Local dp3:Float,dp4:Float
        
        Local c1:vector2d = r.origin
        Local c2:vector2d = add_vector(c1,r.size)
        Local c3:vector2d = New vector2d(c2.x,c1.y)
        Local c4:vector2d = New vector2d(c1.x,c2.y)
        
        c1 = subtract_vector(c1,l.base)
        c2 = subtract_vector(c2,l.base)
        c3 = subtract_vector(c3,l.base)
        c4 = subtract_vector(c4,l.base)                        
        
        dp1 = dot_product(n,c1)
        dp2 = dot_product(n,c2)
        dp3 = dot_product(n,c3)
        dp4 = dot_product(n,c4)
        
        Return     (dp1 * dp2 <= 0) Or
                (dp2 * dp3 <= 0) Or
                (dp3 * dp4 <= 0)
    End Function

    '
    ' helper functions
    '
    Function sort_range:range(r:range)
        Local sorted:range = r
        If (r.minimum > r.maximum)
            sorted.minimum = r.maximum
            sorted.maximum = r.minimum
        End If
        Return sorted
    End Function    

    Function overlapping_ranges:Bool(a:range,b:range)
        Return overlapping(    a.minimum,
                            a.maximum,
                            b.minimum,
                            b.maximum)
    End Function

    Function overlapping:Bool(mina:Float,maxa:Float,minb:Float,maxb:Float)
        Return minb <= maxa And mina <= maxb
    End Function  
    
    Function rotate_vector_90:vector2d(v:vector2d)
        Local r:vector2d = New vector2d()
        r.x = -v.y
        r.y = v.x
        Return r
    End Function

    Function add_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d(0,0)
        r.x = a.x + b.x
        r.y = a.y + b.y
        Return r
    End Function  

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function    
            
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
    Method draw()
        DrawLine base.x,base.y,direction.x,direction.y
    End Method
End Class

Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class

Class range
    Field minimum:Float
    Field maximum:Float
    Method New(minimum:Float,maximum:Float)
        Self.minimum = minimum
        Self.maximum = maximum
    End Method
End Class

Class segment
    ' point1 and point2 are two vectors.
    ' A vector has a x and y coordinate.
    Field point1:vector2d
    Field point2:vector2d
    Method New(point1:vector2d,point2:vector2d)
        Self.point1 = point1
        Self.point2 = point2
    End Method
    Method draw()
        DrawLine point1.x,point1.y,point2.x,point2.y
    End Method
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Field angle:Float
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()
        angle+=1
        If angle > 360 Then angle = 0  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
        ' this is a line segment setup
        Local point1:vector2d = New vector2d(MouseX,MouseY)
        Local point2:vector2d = New vector2d(MouseX+100,MouseY+100)
        ' ls is short for line segment
        Local ls:segment = New segment(point1,point2)
        '
        ' This is the rectangle
        Local origin:vector2d = New vector2d(320,200)
        Local size:vector2d = New vector2d(100,50)
        Local rect1:rectangle = New rectangle(origin,size)

        ' Here we test for collision
        If col.rectangle_segment_collide(rect1,ls)
            DrawText "Rectangle vs Line Segment Collision",0,0
        Else
            DrawText "Rectangle vs Line Segment NO Collision",0,0
        End If

        ' Here we draw the line and rectangle
        ls.draw
        rect1.draw
                        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Collision - Rectangle vs Line - code example


' From the book '2d game collision detection'
' rectangle vs Line collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' The rectangle vs Line Collision
    Function line_rectangle_collide:Bool(l:line,r:rectangle)
        Local n:vector2d = rotate_vector_90(l.direction)
        
        Local dp1:Float,dp2:Float
        Local dp3:Float,dp4:Float
        
        Local c1:vector2d = r.origin
        Local c2:vector2d = add_vector(c1,r.size)
        Local c3:vector2d = New vector2d(c2.x,c1.y)
        Local c4:vector2d = New vector2d(c1.x,c2.y)
        
        c1 = subtract_vector(c1,l.base)
        c2 = subtract_vector(c2,l.base)
        c3 = subtract_vector(c3,l.base)
        c4 = subtract_vector(c4,l.base)                        
        
        dp1 = dot_product(n,c1)
        dp2 = dot_product(n,c2)
        dp3 = dot_product(n,c3)
        dp4 = dot_product(n,c4)
        
        Return     (dp1 * dp2 <= 0) Or
                (dp2 * dp3 <= 0) Or
                (dp3 * dp4 <= 0)
    End Function

    '
    ' helper functions
    '
    Function rotate_vector_90:vector2d(v:vector2d)
        Local r:vector2d = New vector2d()
        r.x = -v.y
        r.y = v.x
        Return r
    End Function

    Function add_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d(0,0)
        r.x = a.x + b.x
        r.y = a.y + b.y
        Return r
    End Function  

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function    
            
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
    Method draw()
        DrawLine base.x,base.y,direction.x,direction.y
    End Method
End Class

Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class


' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Field angle:Float
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()
        angle+=1
        If angle > 360 Then angle = 0  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
        ' this is a line setup
        Local base:vector2d = New vector2d(0,0)
        Local direction:vector2d = New vector2d(MouseX,MouseY)
        Local line1:line = New line(base,direction)
        '
        ' This is the rectangle
        Local origin:vector2d = New vector2d(320,200)
        Local size:vector2d = New vector2d(100,100)
        Local rect1:rectangle = New rectangle(origin,size)

        ' Here we test for collision
        If col.line_rectangle_collide(line1,rect1)
            DrawText "Line vs Rectangle Collision",0,0
        Else
            DrawText "Line vs Rectangle NO Collision",0,0
        End If
        
        ' Here we draw the line and rectangle
        line1.draw
        rect1.draw
                        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        DrawText "Info : Lines are infinite in length.",DeviceWidth/2,20
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Collision - Point vs Rectangle - code example


' From the book '2d game collision detection'
' point vs rectangle collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' The point vs rectangle Collision
    Function point_rectangle_collide:Bool(p:vector2d,r:rectangle)
        Local left:Float = r.origin.x
        Local right:Float = left + r.size.x
        Local bottom:Float = r.origin.y
        Local top:Float = bottom + r.size.y        
        Return     left <= p.x And
                bottom <= p.y And
                p.x <= right And
                p.y <= top    
    End Function
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class


' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Field angle:Float
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()
        angle+=1
        If angle > 360 Then angle = 0  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
        ' this is a point(vector) with the mouse coordinates
        Local point:vector2d = New vector2d(MouseX,MouseY)
        '
        ' This is the rectangle
        Local origin:vector2d = New vector2d(320,200)
        Local size:vector2d = New vector2d(100,100)
        Local rect1:rectangle = New rectangle(origin,size)

        ' Here we test for collision
        If col.point_rectangle_collide(point,rect1)
            DrawText "Point vs Rectangle Collision",0,0
        Else
            DrawText "Point vs Rectangle NO Collision",0,0
        End If
        
        rect1.draw
                        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Collision - Circle vs Oriented Rectangle - code example


' From the book '2d game collision detection'
' circle vs oriented rectangle collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' the circle vs oriented rectangle collision
    
    Function circle_oriented_rectangle_collide:Bool(c:circle,
                                                    r:orientedrectangle)
        Local origin:vector2d = New vector2d(0,0)
        Local size:vector2d = New vector2d(0,0)
        Local lr:rectangle = New rectangle(origin,size)
        
        lr.size = multiply_vector(r.halfextend,2)
        
        Local center:vector2d = New vector2d(0,0)         
        Local lc:circle = New circle(center,c.radius)
        Local distance:vector2d = subtract_vector(c.center,r.center)
        distance = rotate_vector(distance,-r.rotation)
        lc.center = add_vector(distance,r.halfextend)
        
        Return circle_rectangle_collide(lc,lr)
        
    End Function
    
    ' needed for circle vs oriented rectangle collision
    Function circle_rectangle_collide:Bool(c:circle,r:rectangle)
        Local clamped:vector2d = clamp_on_rectangle(c.center,r)
        Return circle_point_collide(c,clamped)
    End Function

    ' Needed for circle_segment_collide
    Function circle_point_collide:Bool(c:circle,p:vector2d)
        Local distance:vector2d = subtract_vector(c.center,p)
        Return vector_length(distance) <= c.radius
    End Function

    ' Helper Functions ........
    '
    '
    Function multiply_vector:vector2d(v:vector2d,scalar:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * scalar
        r.y = v.y * scalar
        Return r
    End Function

    Function clamp_on_rectangle:vector2d(p:vector2d,r:rectangle)
        Local clamp:vector2d = New vector2d()
        clamp.x = Clamp(p.x,r.origin.x,r.origin.x+r.size.x)
        clamp.y = Clamp(p.y,r.origin.y,r.origin.y+r.size.y)
        Return clamp
    End Function
    
    Function vector_length:Float(v:vector2d)
        Return Sqrt(v.x * v.x + v.y * v.y)
    End Function

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function add_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d(0,0)
        r.x = a.x + b.x
        r.y = a.y + b.y
        Return r
    End Function   

    ' Here is the function that rotates a vector. It returns the
    ' new rotated vector.
    '
    Function rotate_vector:vector2d(v:vector2d,degrees:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * Cos(degrees) - v.y * Sin(degrees)
        r.y = v.x * Sin(degrees) + v.y * Cos(degrees)
        Return r
    End Function

End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class

Class circle
    Field center:vector2d
    Field radius:Float
    Method New(center:vector2d,radius:Float)
        Self.center = center
        Self.radius = radius
    End Method
    Method draw()
        DrawCircle center.x,center.y,radius
    End Method
End Class

Class orientedrectangle
    Field center:vector2d
    Field halfextend:vector2d

    Field rotation:Float
    Method New(center:vector2d,halfextend:vector2d,rotation:Float)
        Self.center = center
        Self.halfextend = halfextend
        Self.rotation = rotation
    End Method
    Method draw()
        Local v1:vector2d,v2:vector2d,v3:vector2d,v4:vector2d
        'topside
        v1 = New vector2d(-halfextend.x,-halfextend.y)
        v2 = New vector2d(halfextend.x,-halfextend.y)
        v1 = rotate_vector(v1,rotation)
        v2 = rotate_vector(v2,rotation)
        v1.x += center.x
        v1.y += center.y
        v2.x += center.x
        v2.y += center.y
        ' rightside
        v3 = New vector2d(halfextend.x,halfextend.y)
        v3 = rotate_vector(v3,rotation)
        v3.x += center.x
        v3.y += center.y
        ' bottom side
        v4 = New vector2d(-halfextend.x,halfextend.y)
        v4 = rotate_vector(v4,rotation)
        v4.x += center.x
        v4.y += center.y
        DrawLine v1.x,v1.y,v2.x,v2.y
        DrawLine v2.x,v2.y,v3.x,v3.y
        DrawLine v3.x,v3.y,v4.x,v4.y
        DrawLine v4.x,v4.y,v1.x,v1.y
    End Method    
    Function rotate_vector:vector2d(v:vector2d,degrees:Float)
        Local r:vector2d = New vector2d()
           r.x = v.x * Cos(degrees) - v.y * Sin(degrees)
            r.y = v.x * Sin(degrees) + v.y * Cos(degrees)
        Return r
    End Function    
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Field angle:Float
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()
        angle+=1
        If angle > 360 Then angle = 0  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
        ' Here we set up the circle where we test
        ' the collision with
        Local cc:vector2d = New vector2d(320,200)
        Local r:Float = 50
        Local circle1:circle = New circle(cc,r)
        ' Here we set up the oriented rectangle
        Local orc:vector2d = New vector2d(MouseX,MouseY)
        Local ors:vector2d = New vector2d(100,50) 'size of the oriented rectangle
        Local orect:orientedrectangle = New orientedrectangle(orc,ors,angle)
        
        ' Collision test
        If col.circle_oriented_rectangle_collide(circle1,orect)
            DrawText "Circle vs Oriented rect Collide",0,0
        Else
            DrawText "Circle vs Oriented rect NO Collision",0,0
        End If
        
        orect.draw
        circle1.draw
        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Circle vs Rectangle - code example


' From the book '2d game collision detection'
' circle vs rectangle collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' the circle vs rectangle segment collision
    Function circle_rectangle_collide:Bool(c:circle,r:rectangle)
        Local clamped:vector2d = clamp_on_rectangle(c.center,r)
        Return circle_point_collide(c,clamped)
    End Function

    ' Needed for circle_segment_collide
    Function circle_point_collide:Bool(c:circle,p:vector2d)
        Local distance:vector2d = subtract_vector(c.center,p)
        Return vector_length(distance) <= c.radius
    End Function

    ' Helper Functions ........
    '
    '
    Function clamp_on_rectangle:vector2d(p:vector2d,r:rectangle)
        Local clamp:vector2d = New vector2d()
        clamp.x = Clamp(p.x,r.origin.x,r.origin.x+r.size.x)
        clamp.y = Clamp(p.y,r.origin.y,r.origin.y+r.size.y)
        Return clamp
    End Function
    
    Function vector_length:Float(v:vector2d)
        Return Sqrt(v.x * v.x + v.y * v.y)
    End Function
    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class circle
    Field center:vector2d
    Field radius:Float
    Method New(center:vector2d,radius:Float)
        Self.center = center
        Self.radius = radius
    End Method
    Method draw()
        DrawCircle center.x,center.y,radius
    End Method
End Class


Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
        ' Here we set up the circle where we test
        ' the collision with
        Local cc:vector2d = New vector2d(320,200)
        Local r:Float = 50
        Local circle1:circle = New circle(cc,r)
        ' Here we set up the rectangle where we test
        ' the collision with
        Local origin:vector2d = New vector2d(MouseX,MouseY)
        Local size:vector2d = New vector2d(100,100)
        Local rect1:rectangle = New rectangle(origin,size)
        
        ' Here we call the collision function
        If col.circle_rectangle_collide(circle1,rect1)
            DrawText "Circle Rectangle Colliding",0,0
        Else
            DrawText "Circle Rectangle NOT Colliding",0,0
        End If
        
        ' Draw the circle and rectangle
        circle1.draw
        rect1.draw
        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Circle vs Line Segment - code example


' From the book '2d game collision detection'
' circle vs line segment collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' the circle vs line segment collision

    Method circle_segment_collide:Bool(c:circle,s:segment)
        If (circle_point_collide(c,s.point1)) Then Return True
        If (circle_point_collide(c,s.point2)) Then Return True
        
        Local d:vector2d = subtract_vector(s.point2,s.point1)
        Local lc:vector2d = subtract_vector(c.center,s.point1)
        Local p:vector2d = project_vector(lc,d)
        Local nearest:vector2d = add_vector(s.point1,p)
        
        Return     circle_point_collide(c,nearest) And
                vector_length(p) <= vector_length(d) And
                0 <= dot_product(p,d)    
    End Method

    ' Needed for circle_segment_collide
    Method circle_point_collide:Bool(c:circle,p:vector2d)
        Local distance:vector2d = subtract_vector(c.center,p)
        Return vector_length(distance) <= c.radius
    End Method

    ' Helper Functions ........
    '
    '
    Function vector_length:Float(v:vector2d)
        Return Sqrt(v.x * v.x + v.y * v.y)
    End Function

    Function project_vector:vector2d(project:vector2d, onto:vector2d)
        ' d is a float variable that holds the dot product
        ' of onto,onto
        Local d:Float = dot_product(onto,onto)
        If (0<d)
            ' dp is a variable that holds the dot product
            ' of project and onto
            Local dp:Float = dot_product(project, onto)
            Return multiply_vector(onto,dp/d)
        End If
        Return onto
    End Function
    
    Function multiply_vector:vector2d(v:vector2d,scalar:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * scalar
        r.y = v.y * scalar
        Return r
    End Function

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function add_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d(0,0)
        r.x = a.x + b.x
        r.y = a.y + b.y
        Return r
    End Function    

End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
    Method draw()
        DrawLine base.x,base.y,direction.x,direction.y
    End Method
End Class

Class circle
    Field center:vector2d
    Field radius:Float
    Method New(center:vector2d,radius:Float)
        Self.center = center
        Self.radius = radius
    End Method
    Method draw()
        DrawCircle center.x,center.y,radius
    End Method
End Class


Class segment
    ' point1 and point2 are two vectors.
    ' A vector has a x and y coordinate.
    Field point1:vector2d
    Field point2:vector2d
    Method New(point1:vector2d,point2:vector2d)
        Self.point1 = point1
        Self.point2 = point2
    End Method
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255

        Local cc:vector2d = New vector2d(320,200)
        Local r:Float = 50
        Local circle1:circle = New circle(cc,r)
        
        Local a:vector2d = New vector2d(MouseX,MouseY)
        Local b:vector2d = New vector2d(MouseX+100,MouseY+100)
        Local s1:segment = New segment(a,b)

        If col.circle_segment_collide(circle1,s1)
            DrawText "Circle Line Collision",0,0
        Else
            DrawText "Circle Line NO Collision",0,0
        End If
    
        
        DrawLine a.x,a.y,b.x,b.y    
        circle1.draw
        
        DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0
        
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Circle vs Line - code example


' From the book '2d game collision detection'
' circle vs line collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' the circle vs line collision

    Method circle_line_collide:Bool(c:circle,l:line)
        Local lc:vector2d = subtract_vector(c.center,l.base)
        Local p:vector2d = project_vector(lc,l.direction)
        Local nearest:vector2d = add_vector(l.base,p)
        Return circle_point_collide(c,nearest)
    End Method

    Method circle_point_collide:Bool(c:circle,p:vector2d)
        Local distance:vector2d = subtract_vector(c.center,p)
        Return vector_length(distance) <= c.radius
    End Method

    ' Helper Functions ........
    '
    '
    Function vector_length:Float(v:vector2d)
        Return Sqrt(v.x * v.x + v.y * v.y)
    End Function

    Function project_vector:vector2d(project:vector2d, onto:vector2d)
        ' d is a float variable that holds the dot product
        ' of onto,onto
        Local d:Float = dot_product(onto,onto)
        If (0<d)
            ' dp is a variable that holds the dot product
            ' of project and onto
            Local dp:Float = dot_product(project, onto)
            Return multiply_vector(onto,dp/d)
        End If
        Return onto
    End Function
    
    Function multiply_vector:vector2d(v:vector2d,scalar:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x * scalar
        r.y = v.y * scalar
        Return r
    End Function

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function add_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d(0,0)
        r.x = a.x + b.x
        r.y = a.y + b.y
        Return r
    End Function    

End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
    Method draw()
        DrawLine base.x,base.y,direction.x,direction.y
    End Method
End Class

Class circle
    Field center:vector2d
    Field radius:Float
    Method New(center:vector2d,radius:Float)
        Self.center = center
        Self.radius = radius
    End Method
    Method draw()
        DrawCircle center.x,center.y,radius
    End Method
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255

        Local cc:vector2d = New vector2d(320,200)
        Local r:Float = 50
        Local circle1:circle = New circle(cc,r)
        Local base:vector2d = New vector2d(0,0)
        Local direction:vector2d = New vector2d(MouseX,MouseY)
        Local l:line = New line(base,direction)
        
        If col.circle_line_collide(circle1,l)
            DrawText "Circle and Line Colliding",0,0
        Else
            DrawText "Circle and Line NOT Colliding",0,0
        End If
        
        circle1.draw
        l.draw
        
        DrawText "Circle vs Line Collision",DeviceWidth/2,0
        DrawText "Info : Lines are infinite in length.",DeviceWidth/2,20
        
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Circle vs Point - code example


' From the book '2d game collision detection'
' circle vs point collision

Import mojo

' This is the collision class.
'
Class collision
    ' Collision function
    ' the circle vs point collision
    Method circle_point_collide:Bool(c:circle,p:vector2d)
        Local distance:vector2d = subtract_vector(c.center,p)
        Return vector_length(distance) <= c.radius
    End Method
    ' Helper Functions ........
    '
    '
    Function vector_length:Float(v:vector2d)
        Return Sqrt(v.x * v.x + v.y * v.y)
    End Function

    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function
    
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class circle
    Field center:vector2d
    Field radius:Float
    Method New(center:vector2d,radius:Float)
        Self.center = center
        Self.radius = radius
    End Method
    Method draw()
        DrawCircle center.x,center.y,radius
    End Method
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()  
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255

        ' c is a vector where we create the circle with
        Local c:vector2d = New vector2d(320,200)
        ' r is a float variable that is the radius of the circle
        Local r:Float = 100
        ' here we create a circle
        Local circle:circle = New circle(c,r)
        
        ' draw the circle
        circle.draw
        
        ' create a vector at the mouse pointer coordinates
        Local mousevector:vector2d = New vector2d(MouseX,MouseY)
        
        ' test collision
        If col.circle_point_collide(circle,mousevector)
            DrawText "Point Collision with circle",0,0
        Else
            DrawText "Point NO Collision with circle",0,0
        End If
        
        DrawText "Move the mouse around to test collision",DeviceWidth/2,0
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Line Segment vs Line Segment - code example


' From the book '2d game collision detection'
' Line Segment vs Line Segment Collision

Import mojo

' This is the collision class. In this example with
' the line segment vs line segment.
'
'
Class collision
    ' Collision function
    ' This is the line segments collision function
    Function segments_collide:Bool(a:segment,b:segment)
        Local axisa:line = New line()
        Local axisb:line = New line()
        axisa.base = a.point1
        axisa.direction = subtract_vector(a.point2,a.point1)
        If (on_one_side(axisa,b)) Then Return False
        axisb.base = b.point1
        axisb.direction = subtract_vector(b.point2,b.point1)
        If (on_one_side(axisb,a)) Then Return False
        If (parallel_vectors(axisa.direction,axisb.direction))
            Local rangea:range = project_segment(a,axisa.direction)
            Local rangeb:range = project_segment(b,axisa.direction)
            Return overlapping_ranges(rangea,rangeb)
        Else
            Return True
        End If
    End Function
    ' Helper Functions ........
    ',
    '
    Function on_one_side:Bool(axis:line,s:segment)
        Local d1:vector2d = subtract_vector(s.point1,axis.base)
        Local d2:vector2d = subtract_vector(s.point2,axis.base)
        Local n:vector2d = rotate_vector_90(axis.direction)
        Return dot_product(n,d1) * dot_product(n,d2) > 0
    End Function

    Function sort_range:range(r:range)
        Local sorted:range = r
        If (r.minimum > r.maximum)
            sorted.minimum = r.maximum
            sorted.maximum = r.minimum
        End If
        Return sorted
    End Function
    
    Function project_segment:range(s:segment,onto:vector2d)
        Local ontounit:vector2d = unit_vector(onto)
        Local r:range = New range()
        r.minimum = dot_product(ontounit,s.point1)
        r.maximum = dot_product(ontounit,s.point2)
        r = sort_range(r)
        Return r        
    End Function

    Function overlapping_ranges:Bool(a:range,b:range)
        Return overlapping(    a.minimum,
                            a.maximum,
                            b.minimum,
                            b.maximum)
    End Function
        
    Function overlapping:Bool(mina:Float,maxa:Float,minb:Float,maxb:Float)
        Return minb <= maxa And mina <= maxb
    End Function    
    
    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function

    Function rotate_vector_90:vector2d(v:vector2d)
        Local r:vector2d = New vector2d()
        r.x = -v.y
        r.y = v.x
        Return r
    End Function

    Function unit_vector:vector2d(v:vector2d)
        Local length:Float = vector_length(v)
        If (0 < length)
            Return divide_vector(v,length) 
        End If    
        Return v
    End Function

    Function vector_length:Float(v:vector2d)
        Return Sqrt(v.x * v.x + v.y * v.y)
    End Function
    
    Function parallel_vectors:Bool(a:vector2d,b:vector2d)
        Local na:vector2d = rotate_vector_90(a)    
        Return (0 = Floor(dot_product(na,b)))
    End Function    

    Function divide_vector:vector2d(v:vector2d,divisor:Float)
        Local r:vector2d = New vector2d()
        r.x = v.x / divisor
        r.y = v.y / divisor
        Return r
End Function
    
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class line
    ' base is a vector which holds the origin
    ' of the line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
End Class

Class range
    Field minimum:Float
    Field maximum:Float
    Method New(minimum:Float,maximum:Float)
        Self.minimum = minimum
        Self.maximum = maximum
    End Method
End Class

Class segment
    ' point1 and point2 are two vectors.
    ' A vector has a x and y coordinate.
    Field point1:vector2d
    Field point2:vector2d
    Method New(point1:vector2d,point2:vector2d)
        Self.point1 = point1
        Self.point2 = point2
    End Method
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        '                    
        Local a:vector2d = New vector2d(10,10)
        Local b:vector2d = New vector2d(320,200)
        Local c:vector2d = New vector2d(MouseX,MouseY)
        Local d:vector2d = New vector2d(MouseX+100,MouseY+100)
        
        ' segments are two vectors. point1 x and y 
        ' and point2 x and y
        '
        Local s1:segment = New segment(a,b)
        Local s2:segment = New segment(c,d)        
        
        If col.segments_collide(s1,s2)
            DrawText "Lines s1 and s2 - Collision",0,0
            Else
            DrawText "Lines s1 and s2 - No Collision",0,0
        End If
        
        DrawLine a.x,a.y,b.x,b.y
        DrawLine c.x,c.y,d.x,d.y
    
        DrawText "Move the Mouse to move the line.",DeviceWidth/2,0
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Line vs Line - code example


' From the book '2d game collision detection'
' Line vs Line Collision

Import mojo

' This is the collision class. In this example with
' the line vs line method.
'
'
Class collision
    ' Collision function
    Method lines_collide:Bool(a:line,b:line)
        If (parallel_vectors(a.direction,b.direction))
            Return equivalent_lines(a,b)
        Else
            Return True
        End If
    End Method
    ' Helper Functions ........
    '
    '
    Function subtract_vector:vector2d(a:vector2d,b:vector2d)
        Local r:vector2d = New vector2d()
        r.x = a.x - b.x
        r.y = a.y - b.y
        Return r
    End Function

    Function equivalent_lines:Bool(a:line,b:line)
        If (Not parallel_vectors(a.direction,b.direction)) Then Return False
        Local d:vector2d = subtract_vector(a.base,b.base)
        Return parallel_vectors(d,a.direction)
    End Function

    Function equal_vectors:Bool(a:vector2d,b:vector2d)
        Return a.x-b.x = 0 And a.y-b.y = 0
    End Function

    Function parallel_vectors:Bool(a:vector2d,b:vector2d)
        Local na:vector2d = rotate_vector_90(a)    
        Return (0 = Floor(dot_product(na,b)))
    End Function

    Function rotate_vector_90:vector2d(v:vector2d)
        Local r:vector2d = New vector2d()
        r.x = -v.y
        r.y = v.x
        Return r
    End Function

    Function dot_product:Float(a:vector2d,b:vector2d)
        Return a.x * b.x + a.y * b.y 
    End Function
    
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class line
    Field base:vector2d
    Field direction:vector2d
    Method New(base:vector2d,direction:vector2d)
        Self.base = base
        Self.direction = direction
    End Method
End Class


' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        ' a,b and c are variables that are turned into vectors
        ' using the vector2d class
        Local a:vector2d = New vector2d(30,50)
        Local b:vector2d = New vector2d(30,20)
        Local c:vector2d = New vector2d(80,40)
        Local down:vector2d = New vector2d(50,-10)
        Local up:vector2d = New vector2d(50,20)
        Local l1:line = New line(a,down)
        Local l2:line = New line(a,up)
        Local l3:line = New line(b,up)
        Local l4:line = New line(c,down)

        If col.lines_collide(l1,l2)
            DrawText "Lines 1 and 2 Collide",0,0
            Else
            DrawText "Lines 1 and 2 do not Collide",0,0    
        End If
        If col.lines_collide(l1,l3)
            DrawText "Lines 1 and 3 Collide",0,20
            Else
            DrawText "Lines 1 and 3 do not Collide",0,20
        End If
        If col.lines_collide(l2,l3)
            DrawText "Lines 2 and 3 Collide",0,40
            Else
            DrawText "Lines 2 and 3 do not Collide",0,40
        End If
        If col.lines_collide(l1,l4)
            DrawText "Lines 1 and 4 Collide",0,60
            Else
            DrawText "Lines 1 and 4 do not Collide",0,60
        End If
        '
        DrawText "Line 1 base = "+l1.base.x+","+l1.base.y,100,100
        DrawText "Line 1 direction = "+l1.direction.x+","+l1.direction.y,320,100
        DrawText "Line 2 base = "+l2.base.x+","+l2.base.y,100,120
        DrawText "Line 2 direction = "+l2.direction.x+","+l2.direction.y,320,120
        DrawText "Line 3 base = "+l3.base.x+","+l3.base.y,100,140
        DrawText "Line 3 direction = "+l3.direction.x+","+l3.direction.y,320,140
        DrawText "Line 4 base = "+l4.base.x+","+l4.base.y,100,160
        DrawText "Line 4 direction = "+l4.direction.x+","+l4.direction.y,320,160
        
        '
        DrawText "Line vs Line Collision",DeviceWidth/2,0
        DrawText "Info : Lines are infinite in length",DeviceWidth/2,20
        DrawText "in every direction...",DeviceWidth/2,40
        '                    
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Point vs Point - code example


'  From the book '2d game collision detection'

Import mojo

' This is the collision class. In this example with
' the point vs point method.
'
'
Class collision
    Method points_collide:Bool(a:vector2d,b:vector2d)
        Return a.x = b.x And a.y = b.y
    End Method
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class


' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        ' a,b and c are variables that are turned into vectors
        ' using the vector2d class
        Local a:vector2d = New vector2d(100,100)
        Local b:vector2d = New vector2d(100,100)
        Local c:vector2d = New vector2d(101,100)
        '
        DrawText "point a : "+a.x+","+a.y,0,100
        DrawText "point b : "+b.x+","+b.y,0,120
        DrawText "point c : "+c.x+","+c.y,0,140
        '
        If col.points_collide(a,b)
            DrawText "Points a vs b - Collision",0,0
            Else
            DrawText "Points a vs b - No Collision",0,0
        End If
        If col.points_collide(a,c)
            DrawText "Points a vs c - Collision",0,20        
            Else
            DrawText "Points a vs c - No Collision",0,20
        End If        
        
    End Method
End Class

Function Main()
    New MyGame()
End Function
    

Monkey-X - Collision - Circle vs Circle - code example.

'  From the book '2d game collision detection'

Import mojo

' This is the collision class. In this example with
' the circles collide method.
'
'
Class collision
    Method circles_collide:Bool(a:circle,b:circle)
        Local radiussum:Float = a.radius+b.radius
        Local distance:vector2d = subtract_vector(a.center,b.center)
        Return vector_length(distance) <= radiussum
    End Method
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class circle
    ' Center is a vector that holds the center of a circle.
    Field center:vector2d
    ' Radius is a float variable that holds the distance from
    ' the center of the circle to the edge.
    Field radius:Float
    Method New(center:vector2d,radius:Float)
        Self.center = center
        Self.radius = radius
    End Method
    Method draw()
        DrawCircle center.x,center.y,radius
    End Method
End Class

' col is the caller of the class collision. 
' we use it to use the collision methods.
Global col:collision = New collision

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        '
        Local center1:vector2d = New vector2d(320,200)
        Local radius1:Float = 50
        Local c1:circle = New circle(center1,radius1)
        '
        Local center2:vector2d = New vector2d(MouseX(),MouseY())
        Local radius2:Float = 50
        Local c2:circle = New circle(center2,radius2)
        
        If col.circles_collide(c1,c2)
            DrawText "Circles Collision - Collision",0,0
        Else
            DrawText "Circles Collision - No Collision",0,0
        End If
        
        DrawText "Move the Mouse to see if collision occurs",DeviceWidth/2,0
        
        DrawText "Two Circles intersect when the distance between",0,DeviceHeight-60
        DrawText "their centers is less then the sum of their radii.",0,DeviceHeight-40
        
        c1.draw
        c2.draw
    End Method
End Class

Function subtract_vector:vector2d(a:vector2d,b:vector2d)
    Local r:vector2d = New vector2d()
    r.x = a.x - b.x
    r.y = a.y - b.y
    Return r
End Function

Function vector_length:Float(v:vector2d)
    Return Sqrt(v.x * v.x + v.y * v.y)
End Function

Function Main()
    New MyGame()
End Function
    

Friday, March 3, 2017

Monkey-X - Collision - Rectangle vs Rectangle - code example


'  From the book '2d game collision detection'

Import mojo

' This is the collision class. In this example with
' the rectangles collide method.
'
'
Class collision
    Method overlapping:Bool(mina:Float,maxa:Float,minb:Float,maxb:Float)
        Return minb <= maxa And mina <= maxb
    End Method
    Method rectangles_collide:Bool(a:rectangle,b:rectangle)
        Local aleft:Float    = a.origin.x
        Local aright:Float    = aleft + a.size.x
        Local bleft:Float    = b.origin.x
        Local bright:Float    = bleft + b.size.x
        
        Local abottom:Float    = a.origin.y
        Local atop:Float    = abottom + a.size.y
        Local bbottom:Float    = b.origin.y
        Local btop:Float    = bbottom + b.size.y
        
        Return overlapping(    aleft,aright,
                            bleft,bright) And overlapping(    abottom,
                                                            atop,
                                                            bbottom,
                                                            btop)
    End Method
End Class

Class vector2d
    ' x and y hold the position of the vector
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class rectangle
    ' origin is a vector that holds the x and y coordinates
    ' of the rectangle
    Field origin:vector2d
    ' size is a vector that holds the x(width) and 
    ' y(height) of the rectangle
    Field size:vector2d
    Method New(origin:vector2d,size:vector2d)
        Self.origin = origin
        Self.size = size
    End Method
    Method draw()
        ' x1,y1,w,h are used to hold the rectangle
        ' location and size.
        Local x1:Int=origin.x
        Local y1:Int=origin.y
        Local w:Int=size.x
        Local h:Int=size.y
        DrawRect x1,y1,w,h
    End Method
End Class

Global col:collision = New collision

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
        ' origin is a vector that we use to create
        ' the rectangle. It holds the x and y position.
        Local origin:vector2d=New vector2d(100,200)
        ' size is a vector that we use to create
        ' the rectangle. It holds the width and height.
        Local size:vector2d=New vector2d(100,100)
        ' r1 is a rectangle created with the origin and size
        ' vector variables
        Local r1:rectangle = New rectangle(origin,size)
        
        ' Here we create another recangle at the 
        ' position of the mouse
        origin = New vector2d(MouseX(),MouseY())
        size = New vector2d(50,50)
        Local r2:rectangle = New rectangle(origin,size)
        
        If col.rectangles_collide(r1,r2) = True Then
            DrawText "Collision",0,0
            Else
            DrawText "No Collision",0,0
        End If
        DrawText "Move the mouse to see if something collides",DeviceWidth/2,0
        r1.draw
        r2.draw
    End Method
End Class



Function Main()
    New MyGame()
End Function
    

Monkey-X - Beginners - Vector Projection Helper - code example


Import mojo

' This is the vector class. It has a 
' x and y float variable.
'
Class vectorf
    Field x:Float,y:Float
    Method New(x:Float = 0,y:Float = 0)
        Self.x = x
        Self.y = y
    End Method
End Class

Class MyGame Extends App
    ' Here we create the 'a,b' variables using the
    ' vectorf class
    Field a:vectorf,b:vectorf
    ' cx and cy contain the center x and center y
    ' coordinates of the screen.
    Field cx:Int
    Field cy:Int
    ' time is a variable used to change(refresh)
    ' the information on the screen.
    Field time:Int
    Method OnCreate()
        SetUpdateRate(1)
        ' randomize using the time function
        Seed = GetDate[4] + GetDate[5]
        cx = DeviceWidth()/2
        cy = DeviceHeight()/2
        ' Here we create new vectors (a,b)
        ' with random values
        a = New vectorf(Rnd(-10,10),Rnd(10,10))
        b = New vectorf(Rnd(-5,5),Rnd(5,5))
    End Method
    Method OnUpdate()
        '                 
        time+=1
        If time>5 Then
            time=0
            a = New vectorf(Rnd(-10,10),Rnd(-10,10))
            b = New vectorf(Rnd(-5,5),Rnd(5,5))
        End If
    End Method
    Method OnRender()
        ' pointx and y hold the coordinates
        ' that are used to draw on the screen.
        Local pointx:Int
        Local pointy:Int
        Cls 0,0,0 
        SetColor 255,255,255
        ' Here we draw the helper screen part.
        DrawLine cx,0,cx,DeviceHeight
        DrawLine 0,cy,DeviceWidth,cy
         DrawText "-X",0,cy
         DrawText "+X",DeviceWidth()-30,cy
         DrawText "-Y",cx,0
         DrawText "+Y",cx,DeviceHeight()-30
         DrawText "0,0",cx,cy,.5,.5
         DrawText "Origin",cx+5,cy-20
        '
        ' Here we draw the vector a.
        SetColor 255,255,255
        pointx = (a.x*13) + cx
        pointy = (a.y*13) + cy
        DrawCircle pointx,pointy,7
        DrawLine cx,cy,pointx,pointy
        DrawText "a",pointx,pointy,.5,.5
        '
        ' Here we draw the vector b.
        SetColor 255,255,255
        pointx = (b.x*13) + cx
        pointy = (b.y*13) + cy
        DrawCircle pointx,pointy,7
        DrawLine cx,cy,pointx,pointy
        DrawText "b",pointx,pointy,.5,.5
        '
        ' Here we create the projected vector
        ' We project vector b onto a.
        Local c:vectorf = project_vector(b,a)
        '
        ' Here we draw the projected vector
        SetColor 255,255,0
        pointx = (c.x*13) + cx
        pointy = (c.y*13) + cy
        DrawCircle pointx,pointy,7
        DrawLine cx,cy,pointx,pointy
        DrawText "c",pointx,pointy,.5,.5        
        
        '        
        ' Here we draw the Screen info
        SetColor 255,255,255
        Scale 1.2,1.2
        SetAlpha 1
        '
        ' String(mystring)[0..4] creates a string with 4 
        ' characters. [ 0,1,2,3 ] Left to right.
        '
        DrawText "Vector Projection b onto a",0,0
        DrawText "A projection is a vector mapped onto another vector.",0,20
        DrawText "",0,40
        SetAlpha 0.6
        DrawText "Vector Projection :",cx-30,DeviceHeight-160
        DrawText "d = dot_product(a,a)",cx-20,DeviceHeight-140
        DrawText "dp = dot_product(b,a)",cx-20,DeviceHeight-120
        SetColor 255,255,0
        DrawText "c = multiply_vector(a,dp/d)",cx-20,DeviceHeight-100

    End Method
End Class

' This function return the dot product of two vectors.
' It returns a value.
'
Function dot_product:Float(a:vectorf,b:vectorf)
    Return a.x * b.x + a.y * b.y 
End Function

' This function multiplies a vector.
' It returns a vector.
'
Function multiply_vector:vectorf(v:vectorf,scalar:Float)
    Local r:vectorf = New vectorf()
    r.x = v.x * scalar
    r.y = v.y * scalar
    Return r
End Function

' This function maps a vector onto the input vector.
' It returns a vector
'
Function project_vector:vectorf(project:vectorf, onto:vectorf)
    ' d is a float variable that holds the dot product
    ' of onto,onto
    Local d:Float = dot_product(onto,onto)
    If (0<d)
        ' dp is a variable that holds the dot product
        ' of project and onto
        Local dp:Float = dot_product(project, onto)
        Return multiply_vector(onto,dp/d)
    End If
    Return onto
End Function

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Vector Rotation Helper - code example


Import mojo

' This is the vector class. It has a 
' x and y float variable.
'
Class vectorf
    Field x:Float,y:Float
    Method New(x:Float = 0,y:Float = 0)
        Self.x = x
        Self.y = y
    End Method
End Class

Class MyGame Extends App
    ' Here we create a 'a' variable using the
    ' vectorf class
    Field a:vectorf
    '
    '
    Field angle:Float
    ' cx and cy contain the center x and center y
    ' coordinates of the screen.
    Field cx:Int
    Field cy:Int
    ' time is a variable used to change(refresh)
    ' the information on the screen.
    Field time:Int
    Method OnCreate()
        SetUpdateRate(60)
        Seed = GetDate[4] + GetDate[5]
        cx = DeviceWidth()/2
        cy = DeviceHeight()/2
        ' Here we create a new vector in
        ' a with a new value(x and y)
        a = New vectorf(Rnd(-10,10),Rnd(10,10))
    End Method
    Method OnUpdate()
        '
        '
        angle+=3
        If angle>359 Then angle=0
        '                 
        time+=1
        If time>300 Then
            time=0
            a = New vectorf(Rnd(-10,10),Rnd(-10,10))
        End If
    End Method
    Method OnRender()
        ' pointx and y hold the coordinates
        ' that are used to draw on the screen.
        Local pointx:Int
        Local pointy:Int
        Cls 0,0,0 
        SetColor 255,255,255
        ' Here we draw the helper screen part.
        DrawLine cx,0,cx,DeviceHeight
        DrawLine 0,cy,DeviceWidth,cy
         DrawText "-X",0,cy
         DrawText "+X",DeviceWidth()-30,cy
         DrawText "-Y",cx,0
         DrawText "+Y",cx,DeviceHeight()-30
         DrawText "0,0",cx,cy,.5,.5
         DrawText "Origin",cx+5,cy-20
        '
        ' Here we draw the vector a.
        SetColor 255,255,255
        pointx = (a.x*13) + cx
        pointy = (a.y*13) + cy
        DrawCircle pointx,pointy,7
        DrawLine cx,cy,pointx,pointy
        DrawText "a",pointx,pointy,.5,.5
        DrawText String(a.x)[0..4]+","+String(a.y)[0..4],pointx+5,pointy+10,.5,.5
        '
        ' Here we draw the rotated vector (b)
        SetColor 255,255,0
        Local b:vectorf = New vectorf()
        b = rotate_vector(a,angle)
        pointx = (b.x*13) + cx
        pointy = (b.y*13) + cy 
        DrawCircle pointx,pointy,7
           DrawLine cx,cy,pointx,pointy
        DrawText "b",pointx,pointy,.5,.5
         
        '        
        ' Here we draw the Screen info
        SetColor 255,255,255
        Scale 1.2,1.2
        SetAlpha 1
        '
        ' String(mystring)[0..4] creates a string with 4 
        ' characters. [ 0,1,2,3 ] Left to right.
        '
        DrawText "Vector Rotation Degrees : "+angle,0,0
        DrawText "Vector rotation changes the direction in which",0,20
        DrawText "a vector points. The vector length stays the same.",0,40
        SetAlpha 0.6
        DrawText "Vector Rotation :",cx-30,DeviceHeight-160
        DrawText "b.x = v.x * Cos(degrees) - v.y * Sin(degrees)",cx-100,DeviceHeight-140
        DrawText "r.y = v.x * Sin(degrees) + v.y * Cos(degrees)",cx-100,DeviceHeight-120

    End Method
End Class

'
' Here is the function that rotates a vector. It returns the
' new rotated vector.
'
Function rotate_vector:vectorf(v:vectorf,degrees:Float)
    Local r:vectorf = New vectorf()
    r.x = v.x * Cos(degrees) - v.y * Sin(degrees)
    r.y = v.x * Sin(degrees) + v.y * Cos(degrees)
    Return r
End Function

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Unit Vector Helper - code example


Import mojo

' This is the vector class. It has a 
' x and y float variable.
'
Class vectorf
    Field x:Float,y:Float
    Method New(x:Float = 0,y:Float = 0)
        Self.x = x
        Self.y = y
    End Method
End Class

Class MyGame Extends App
    ' Here we create a 'a' variable using the
    ' vectorf class
    Field a:vectorf
    ' cx and cy contain the center x and center y
    ' coordinates of the screen.
    Field cx:Int
    Field cy:Int
    ' time is a variable used to change(refresh)
    ' the information on the screen.
    Field time:Int
    Method OnCreate()
        SetUpdateRate(1)
        Seed = GetDate[4] + GetDate[5]
        cx = DeviceWidth()/2
        cy = DeviceHeight()/2
        ' Here we create a new vector in
        ' a with a new value(x and y)
        a = New vectorf(Rnd(-10,10),Rnd(10,10))
    End Method
    Method OnUpdate()        
        time+=1
        If time>5 Then
            time=0
            a = New vectorf(Rnd(-10,10),Rnd(-10,10))
        End If
    End Method
    Method OnRender()
        ' pointx and y hold the coordinates
        ' that are used to draw on the screen.
        Local pointx:Int
        Local pointy:Int
        Cls 0,0,0 
        SetColor 255,255,255
        ' Here we draw the helper screen part.
        DrawLine cx,0,cx,DeviceHeight
        DrawLine 0,cy,DeviceWidth,cy
         DrawText "-X",0,cy
         DrawText "+X",DeviceWidth()-30,cy
         DrawText "-Y",cx,0
         DrawText "+Y",cx,DeviceHeight()-30
         DrawText "0,0",cx,cy,.5,.5
         DrawText "Origin",cx+5,cy-20
        '
        ' Here we draw the vector a.
        SetColor 255,255,0
        pointx = (a.x*13) + cx
        pointy = (a.y*13) + cy
        DrawCircle pointx,pointy,7
        DrawLine cx,cy,pointx,pointy
        DrawText "a",pointx,pointy,.5,.5
        DrawText String(a.x)[0..4]+","+String(a.y)[0..4],pointx+5,pointy+10,.5,.5
        '        
        ' Here we draw the Screen info
        SetColor 255,255,255
        Scale 1.2,1.2
        SetAlpha 1
        '
        ' String(mystring)[0..4] creates a string with 4 
        ' characters. [ 0,1,2,3 ] Left to right.
        '
        Local v:vectorf = unit_vector(a)
        Local x:String=String(v.x)[0..4]
        Local y:String=String(v.y)[0..4]
        DrawText "Unit vector is : "+x+","+y,0,0
        DrawText "The size of unit vector is",0,20
        DrawText "Bigger then -1 and smaller then 1.",0,40
        SetAlpha 0.6
        DrawText "Unit Vector :",cx-30,DeviceHeight-160
        DrawText "vector divided by length",cx-30,DeviceHeight-140
    End Method
End Class

' Here is the function that returns the length of
' the origin(0,0) to it's tip.
'
Function vector_length:Float(v:vectorf)
    Return Sqrt(v.x * v.x + v.y * v.y)
End Function

' This function divides a vector by
' a value. (scaling it)
'  
Function divide_vector:vectorf(v:vectorf,divisor:Float)
    Local r:vectorf = New vectorf()
    r.x = v.x / divisor
    r.y = v.y / divisor
    Return r
End Function

' This function turns a vector in a unit
' vector. Size <1 and >-1.
'
Function unit_vector:vectorf(v:vectorf)
    Local length:Float = vector_length(v)
    If (0 < length)
        Return divide_vector(v,length) 
    End If    
    Return v
End Function

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Vector Length Helper - code example


Import mojo

' This is the vector class. It has a 
' x and y float variable.
'
Class vectorf
    Field x:Float,y:Float
    Method New(x:Float = 0,y:Float = 0)
        Self.x = x
        Self.y = y
    End Method
End Class

Class MyGame Extends App
    ' Here we create a 'a' variable using the
    ' vectorf class
    Field a:vectorf
    ' cx and cy contain the center x and center y
    ' coordinates of the screen.
    Field cx:Int
    Field cy:Int
    ' time is a variable used to change(refresh)
    ' the information on the screen.
    Field time:Int
    Method OnCreate()
        SetUpdateRate(1)
        Seed = GetDate[4] + GetDate[5]
        cx = DeviceWidth()/2
        cy = DeviceHeight()/2
        ' Here we create a new vector in
        ' a with a new value(x and y)
        a = New vectorf(Rnd(-10,10),Rnd(10,10))
    End Method
    Method OnUpdate()        
        time+=1
        If time>5 Then
            time=0
            a = New vectorf(Rnd(-10,10),Rnd(-10,10))
        End If
    End Method
    Method OnRender()
        ' pointx and y hold the coordinates
        ' that are used to draw on the screen.
        Local pointx:Int
        Local pointy:Int
        Cls 0,0,0 
        SetColor 255,255,255
        ' Here we draw the helper screen part.
        DrawLine cx,0,cx,DeviceHeight
        DrawLine 0,cy,DeviceWidth,cy
         DrawText "-X",0,cy
         DrawText "+X",DeviceWidth()-30,cy
         DrawText "-Y",cx,0
         DrawText "+Y",cx,DeviceHeight()-30
         DrawText "0,0",cx,cy,.5,.5
         DrawText "Origin",cx+5,cy-20
        '
        ' Here we draw the vector a.
        SetColor 255,255,0
        pointx = (a.x*13) + cx
        pointy = (a.y*13) + cy
        DrawCircle pointx,pointy,7
        DrawLine cx,cy,pointx,pointy
        DrawText "a",pointx,pointy,.5,.5
        DrawText String(a.x)[0..4]+","+String(a.y)[0..4],pointx+5,pointy+10,.5,.5
        '
        SetColor 155,155,155
        DrawLine pointx,pointy,pointx,cy
        
        ' Here we draw the Screen info
        SetColor 255,255,255
        Scale 1.2,1.2
        SetAlpha 1
        '
        ' String(mystring)[0..4] creates a string with 4 
        ' characters. [ 0,1,2,3 ] Left to right.
        '
        DrawText "Vector Length is : "+String(vector_length(a))[0..4],0,0
        DrawText "The length of a vector is from",0,20
        DrawText "the origin to its tip.",0,40
        SetAlpha 0.6
        DrawText "Vector Length :",cx-30,DeviceHeight-160
        DrawText "d = Sqrt(a.x * a.x + a.y * a.y)",cx-30,DeviceHeight-140
    End Method
End Class

' Here is the function that returns the length of
' the origin(0,0) to it's tip.
'
Function vector_length:Float(v:vectorf)
    Return Sqrt(v.x * v.x + v.y * v.y)
End Function

Function Main()
    New MyGame()
End Function