Monday, February 20, 2017

Monkey-X - Wall Tracing on Random Maps - code example


' Wall Tracing from the book Ai For Game Developers.
' Random Maps based on code from Rogue Basin.
'

Import mojo

'
'this is the wall tracing entity
Class entity
    Field tilex:Int,tiley:Int
    Field direction:Int=8
    Field speed:Int
    Method New()
        findstartposition
    End Method
    Method update()
        walltrace
    End Method
    Method walltrace()
        If direction = 4
            If mymap.map[tilex-1][tiley] = 1
                tilex -= 1
                direction = 2
            Elseif mymap.map[tilex][tiley+1] = 1
                tiley += 1
                direction = 4
            Elseif mymap.map[tilex+1][tiley] = 1
                tilex += 1
                direction = 6
            Elseif mymap.map[tilex][tiley-1] = 1
                tiley -= 1
                direction = 8
            End If
        Elseif direction = 6
            If mymap.map[tilex][tiley+1] = 1
                tiley += 1
                direction = 4
            Elseif mymap.map[tilex+1][tiley] = 1
                tilex += 1
                direction = 6
            Elseif mymap.map[tilex][tiley-1] = 1
                tiley -= 1
                direction = 8
            Elseif mymap.map[tilex-1][tiley] = 1
                tilex -= 1
                direction = 2
            End If
        Elseif direction = 8
            If mymap.map[tilex+1][tiley] = 1
                tilex += 1
                direction = 6
            Elseif mymap.map[tilex][tiley-1] = 1
                tiley -= 1
                direction = 8
            Elseif mymap.map[tilex-1][tiley] = 1
                tilex -= 1
                direction = 2
            Elseif mymap.map[tilex][tiley+1] = 1
                tiley += 1
                direction = 4
            End If
        Elseif direction = 2
            If mymap.map[tilex][tiley-1] = 1
                tiley -= 1
                direction = 8
            Elseif mymap.map[tilex-1][tiley] = 1
                tilex -= 1
                direction = 2
            Elseif mymap.map[tilex][tiley+1] = 1
                tiley += 1
                direction = 4
            Elseif mymap.map[tilex+1][tiley] = 1
                tilex += 1
                direction = 6
            End If
        End If


    End Method
    Method findstartposition()
        ' for tracing the wall we need to be sure
        ' that the entity is spawned against a wall
        ' here we check for a random pos on the map
        ' on the floor(1) with a wall(2) at y+1
        Local exitloop:Bool=False
        While exitloop = False
            Local x:Int=Rnd(3,mymap.mapwidth-3)
            Local y:Int=Rnd(3,mymap.mapheight-3)
            If mymap.map[x][y] = 1
            If mymap.map[x][y+1] = 2 
                exitloop = True
                tilex = x
                tiley = y
            End If
            End If
        Wend
    End Method    
    Method draw()
        SetColor 255,0,0
        DrawOval     tilex*mymap.tilewidth,
                    tiley*mymap.tileheight,
                    mymap.tilewidth+1,
                    mymap.tileheight+1
    End Method
End Class

Class map
    Field tilewidth:Float
    Field tileheight:Float
    Field mapwidth:Int
    Field mapheight:Int
    Field screenwidth:Int
    Field screenheight:Int
    Field map:Int[][]
    Method New(    screenwidth:Int,
                screenheight:Int,
                mapwidth:Int,
                mapheight:Int)
        Self.screenwidth = screenwidth
        Self.screenheight = screenheight
        Self.mapwidth = mapwidth
        Self.mapheight = mapheight
        Self.tilewidth = Float(screenwidth)/Float(mapwidth)
        Self.tileheight = Float(screenheight)/Float(mapheight)
        map = New Int[mapwidth][]
        For Local i=0 Until mapwidth
            map[i] = New Int[mapheight]
        Next
        map[mapwidth/2][mapheight/2] = 3 ' 3 is a door
        makemap
    End Method
    Method makemap()
        Local timeout:Int
        While timeout<(mapwidth*mapheight)*20
            timeout+=1
            Local x:Int=Rnd(11,mapwidth-11)
            Local y:Int=Rnd(11,mapheight-11)
            If map[x][y] = 3
                makeroom(x,y)
            End If
        Wend    
        'here we turn doors into walls
        'if they should be walls
        For Local y1=1 Until mapheight-1
        For Local x1=1 Until mapwidth-1
            If map[x1][y1] = 3
            Local cnt:Int=0
            For Local y2=y1-1 To y1+1
            For Local x2=x1-1 To x1+1
                If map[x2][y2] = 2 Then cnt+=1
            Next
            Next
            If cnt>3 Then map[x1][y1] = 2
            End If
        Next
        Next
        'here we turn doors into walls if they
        ' touch tiles that are nothing (0)
        For Local y1=1 Until mapheight-1
        For Local x1=1 Until mapwidth-1
            If map[x1][y1] = 3
            Local cnt:Int=0
            For Local y2=y1-1 To y1+1
            For Local x2=x1-1 To x1+1
                If map[x2][y2] = 0 Then cnt+=1
            Next
            Next
            If cnt>0 Then map[x1][y1] = 2
            End If
        Next
        Next        
        'here we turn the doors into floors
        For Local y1=0 Until mapheight
        For Local x1=0 Until mapwidth
            If map[x1][y1] = 3 Then map[x1][y1] = 1
        Next
        Next
    End Method
    Method makeroom(x:Int,y:Int)
        Local side:String
        If map[x][y-1] = 0
            side="up"
        Elseif map[x+1][y] = 0
            side="right"
        Elseif map[x][y+1] = 0
            side="down"
        Elseif map[x-1][y] = 0
            side="left"
        End If        
        Local w:Int=Rnd(5,10)
        Local h:Int=Rnd(5,10)
        If side="up"
            Local x1:Int=x-w/2
            Local y1:Int=y-h
            If roomfits(x1,y1,w,h)
                insertroom(x1,y1,w,h+1)
                'door up
                map[x1+Rnd(2,w-2)][y1] = 3
                ' door right
                map[x1+w-1][y1+Rnd(2,h-2)] = 3
                'door left
                map[x1][y1+Rnd(2,h-2)] = 3
            End If                        
            
        End If
        If side="right"
            Local x1:Int=x+1
            Local y1:Int=y-h/2
            If roomfits(x1,y1,w,h)
                insertroom(x1-1,y1,w,h)
                'door up
                map[x1+Rnd(2,w-2)][y1] = 3
                'door down
                map[x1+Rnd(2,w-2)][y1+h-1] = 3
                ' door right
                map[x1+w-2][y1+Rnd(2,h-2)] = 3                
            End If
        End If
        If side="left"
            Local x1:Int=x-w
            Local y1:Int=y-h/2
            If roomfits(x1,y1,w,h)
                insertroom(x1,y1,w+1,h)
                'door up
                map[x1+Rnd(2,w-2)][y1] = 3
                'door down
                map[x1+Rnd(2,w-2)][y1+h-1] = 3                
                'door left
                map[x1][y1+Rnd(2,h-2)] = 3

            End If            
        End If
        If side="down"
            Local x1:Int=x-w/2
            Local y1:Int=y+1
            If roomfits(x1,y1,w,h)
                insertroom(x1,y1-1,w,h)
                'door down
                map[x1+Rnd(2,w-2)][y1+h-2] = 3                
                'door left
                map[x1][y1+Rnd(2,h-2)] = 3                
                ' door right
                map[x1+w-1][y1+Rnd(2,h-2)] = 3                

            End If                        
        End If
    End Method
    Method insertroom(x,y,w,h)
        For Local y2=y Until y+h
        For Local x2=x Until x+w
            If map[x2][y2] <> 3 Then map[x2][y2] = 2
        Next
        Next

        For Local y2=y+1 Until y+h-1
        For Local x2=x+1 Until x+w-1
            map[x2][y2] = 1
        Next
        Next
    End Method
    Method roomfits(x:Int,y:Int,w:Int,h:Int)
        For Local y1=y Until y+h
        For Local x1=x Until x+w
            If map[x1][y1] = 1 Then Return False
        Next
        Next
        Return True
    End Method
    Method draw()
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            Select map[x][y]
                Case 0
                Case 1'floor
                SetColor 100,100,100
                DrawRect     x*tilewidth,
                            y*tileheight,
                            tilewidth+1,
                            tileheight+1
                Case 2'wall
                SetColor 200,200,200
                DrawRect     x*tilewidth,
                            y*tileheight,
                            tilewidth+1,
                            tileheight+1
                Case 3'wall
                SetColor 244,244,0
                DrawRect     x*tilewidth,
                            y*tileheight,
                            tilewidth+1,
                            tileheight+1

            End Select
        Next
        Next
    End Method
End Class

Global mymap:map
Global myentity:List<entity> = New List<entity>

Class MyGame Extends App
    Field cnt:Int
    Method OnCreate()
        SetUpdateRate(5)
        Seed = GetDate[4]+GetDate[5]
        newmap
    End Method
    Method OnUpdate()    
        cnt+=1
        For Local i:=Eachin myentity
            i.update
        Next
        If KeyHit(KEY_SPACE) Or cnt>200
            cnt=0
            newmap
        End If    
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymap.draw
        For Local i:=Eachin myentity
            i.draw
        Next
        SetColor 255,255,255
        DrawText "Monkey-X - Wall Tracing on Random Maps",10,10
    End Method
End Class


Function Main()
    New MyGame()
End Function


Function newmap()
    Local s:Int=Rnd(40,100)
    mymap = New map(DeviceWidth,DeviceHeight,s,s)
    myentity = New List<entity>
    For Local i=0 Until Rnd(1,s/3)
        myentity.AddLast(New entity())
    Next
End Function

Monkey-X - Path Following - code example


' Path following - from the book - ai for game developers
Import mojo

Class entity
    Field tilex:Int
    Field tiley:Int
    Field entwidth:Int
    Field entheight:Int
    Field tilewidth:Float
    Field tileheight:Float
    Field mapwidth:Int
    Field mapheight:Int    
    Field direction:Int=1 ' 1 is up, 2 is upright ect clockwise
    Method New()
        mapwidth = mypathfollowing.mapwidth
        mapheight = mypathfollowing.mapheight
        entwidth = mypathfollowing.tilewidth
        entheight = mypathfollowing.tileheight
        tilewidth = mypathfollowing.tilewidth
        tileheight = mypathfollowing.tileheight
        findstartpos        
    End Method
    Method update()
        ' terrain analysis
        ' here we check clockwise around the entity its position
        ' and fill the ta(terrainanalysis) array with 0 if there is no read there
        ' and 10 if there is a road
        Local ta:Int[] = New Int[9]
        ta[1] = mypathfollowing.map[tiley-1][tilex]
        ta[2] = mypathfollowing.map[tiley-1][tilex+1]
        ta[3] = mypathfollowing.map[tiley][tilex+1]
        ta[4] = mypathfollowing.map[tiley+1][tilex+1]
        ta[5] = mypathfollowing.map[tiley+1][tilex]
        ta[6] = mypathfollowing.map[tiley+1][tilex-1]
        ta[7] = mypathfollowing.map[tiley][tilex-1]
        ta[8] = mypathfollowing.map[tiley-1][tilex-1]
        For Local i = 1 To 8
            If ta[i] = 0 
                ta[i] = 0
            Else
                ta[i] = 10
            End If
        Next
        ' weighted direction analysis
        ' here we use the current direction and add
        ' up the current direction with 2 and left and
        ' right from there with +1 and the opposite
        ' direction of the entity direction -1        
        If direction = 1
            ta[1] += 2
            ta[2] += 1
            ta[8] += 1
            ta[5] -= 1
        End If
        If direction = 2
            ta[2] += 2
            ta[3] += 1
            ta[1] += 1
            ta[6] -= 1
        End If
        If direction = 3
            ta[3] += 2
            ta[4] += 1
            ta[2] += 1
            ta[7] -= 1
        End If
        If direction = 4
            ta[4] += 2
            ta[5] += 1
            ta[3] += 1
            ta[8] -= 1
        End If
        If direction = 5
            ta[5] += 2
            ta[6] += 1
            ta[4] += 1
            ta[1] -= 1
        End If
        If direction = 6
            ta[6] += 2
            ta[7] += 1
            ta[5] += 1
            ta[2] -= 1
        End If
        If direction = 7
            ta[7] += 2
            ta[8] += 1
            ta[6] += 1
            ta[3] -= 1
        End If
        If direction = 8
            ta[8] += 2
            ta[1] += 1
            ta[7] += 1
            ta[4] -= 1
        End If
        ' choosing direction
        ' here we get the highest weight to get the next direction
        Local maxterrain:Int
        Local maxindex:Int
        For Local i=1 To 8
            If ta[i] > maxterrain
                maxterrain = ta[i]
                maxindex = i
            End If
        Next
        ' update position
        ' here we use the new direction and move the entity and set
        ' the new or last direction
        If maxindex = 1
            direction = 1
            tiley -= 1
        End If
        If maxindex = 2
            direction = 2
            tilex += 1
            tiley -= 1
        End If
        If maxindex = 3
            direction = 3
            tilex += 1
        End If
        If maxindex = 4
            direction = 4
            tilex += 1
            tiley += 1
        End If
        If maxindex = 5
            direction = 5
            tiley += 1
        End If
        If maxindex = 6
            direction = 6
            tilex -= 1
            tiley += 1
        End If
        If maxindex = 7
            direction = 7
            tilex -= 1
        End If
        If maxindex = 8
            direction = 8
            tilex -= 1
            tiley -= 1
        End If
    End Method
    Method findstartpos()
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            If mypathfollowing.map[y][x] = 1
                tilex = x
                tiley = y
                Return
            End If
        Next
        Next
    End Method
    Method draw()
        SetColor 255,255,0
        DrawRect tilex*tilewidth,tiley*tileheight,entwidth,entheight
    End Method
End Class

Class pathfollowing
Global map:Int[][] = [
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
[0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]    
Field screenwidth:Int
    Field screenheight:Int
    Field mapwidth:Int
    Field mapheight:Int
    Field tilewidth:Float
    Field tileheight:Float
    Method New(width:Int,height:Int)
        mapwidth = map.Length
        mapheight = map[0].Length
        screenwidth = width
        screenheight = height
        tilewidth = Float(screenwidth)/Float(mapwidth)
        tileheight = Float(screenheight)/Float(mapheight)
    End Method
    Method draw()
        SetColor 200,100,0
        For Local y = 0 Until mapheight
        For Local x = 0 Until mapwidth
            If map[y][x] = 1
                DrawRect     x*tilewidth,y*tileheight,
                            tilewidth+1,tileheight+1
            End If
        Next
        Next
    End Method
End Class

Global mypathfollowing:pathfollowing
Global myentity:entity

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(5)
        mypathfollowing = New pathfollowing(DeviceWidth,DeviceHeight)
        myentity = New entity()
    End Method
    Method OnUpdate()        
        myentity.update
    End Method
    Method OnRender()
        Cls 0,0,0 
        mypathfollowing.draw
        myentity.draw
        SetColor 255,255,255
        DrawText "Monkey-X - Path Following Example",10,10
    End Method
End Class


Function Main()
    New MyGame()
End Function

Friday, February 10, 2017

Monkey-X - Particle Attraction - code example


Import mojo
Class gravitypoint
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
    Method draw()
        SetColor 255,255,0
        DrawOval x,y,6,6
    End Method
End Class

Class particle
    Field x:Float,y:Float
    Field incx:Float
    Field incy:Float
    Method New(x:Float,y:Float)
        Self.x = x
        Self.y = y 
        incx = Rnd(-1,1)
        incy = Rnd(-1,1)
    End Method
    Method update()
        For Local i:=Eachin mygravitypoint
            Local a:Int=getangle(x,y,i.x,i.y)
            incx+=Cos(a)/2
            incy+=Sin(a)/2
        Next
        x+=incx
        y+=incy
    End Method
    Method draw()
        SetColor 255,255,255
        DrawOval x,y,6,6
    End Method
    Function getangle:Int(x1:Int,y1:Int,x2:Int,y2:Int)
         Local dx = x2 - x1
         Local dy = y2 - y1
         Return ATan2(dy,dx)+360 Mod 360
    End Function      
End Class

Global myparticle:List<particle> = New List<particle>
Global mygravitypoint:List<gravitypoint> = New List<gravitypoint>

Class MyGame Extends App
    Field counter:Int=0
    Method OnCreate()    
        Seed = GetDate[5]+GetDate[4]
        SetUpdateRate(60)
        createscene
    End Method
    Method OnUpdate()  
        counter+=1
        If counter > 300
            counter = 0
            createscene
        End If      
        For Local i:=Eachin myparticle
            i.update
        Next
    End Method
    Method OnRender()
        Cls 0,0,0 
        For Local i:=Eachin myparticle
            i.draw
        Next
        If MouseDown(MOUSE_LEFT)
            For Local i:=Eachin mygravitypoint
                  i.draw
            Next
        End If
        SetAlpha 1
        SetColor 255,255,255
        DrawText "Monkey-X - Particles with 'Attraction' Effect - Thnx to The Coding Train",0,0
        DrawText "Particles get attracted to <Left Mouse Button> points on the map",0,DeviceHeight-20
    End Method
End Class

Function createscene()
    myparticle = New List<particle>
    mygravitypoint = New List<gravitypoint>

    For Local i=0 Until Rnd(10,200)
        myparticle.AddLast(New particle(Rnd(DeviceWidth),Rnd(DeviceHeight)))
    Next
    For Local i=0 Until Rnd(1,20)
        mygravitypoint.AddLast(New gravitypoint(Rnd(DeviceWidth),Rnd(DeviceHeight)))
    Next
End Function

Function Main()
    New MyGame()
End Function

Tuesday, February 7, 2017

Monkey-X - Hill Algorithm - code example

Import mojo

Global screenwidth:Int=640
Global screenheight:Int=480

Class hill
    Field map:Int[][]
    Field mapwidth:Int
    Field mapheight:Int
    Field tilewidth:Float
    Field tileheight:Float
    Method New(width:Int=20,height:Int=20)
        mapwidth = width
        mapheight = height
        tilewidth=Float(screenwidth)/Float(mapwidth)
        tileheight=Float(screenheight)/Float(mapheight)
        map = New Int[mapwidth][]
        For Local i=0 Until mapwidth
            map[i] = New Int[mapheight]
        Next        
        makehill
    End Method
    Method makehill()
        ' Here we draw rectangles on the map adding by +1
        ' with the underlaying value.
        '
        Local exitloop:Bool=False
        While exitloop = False
            Local x:Int=Rnd(-mapwidth/7,mapwidth)
            Local y:Int=Rnd(-mapheight/7,mapheight)
            Local w:Int=Rnd(1,mapwidth/5)
            Local h:Int=Rnd(1,mapheight/5)
            If Rnd(2)<1.8
                w=1
                h=1
            End If
            ' if highest map value > 20 then stop drawing
            ' rectangles
            If addrect(x,y,w,h) > 24 Then exitloop = True
        Wend
    End Method
    Method addrect:Int(x:Int,y:Int,w:Int,h:Int)
        ' This function draws the rectangle and
        ' returns the highest value it makes in the map
        '
        Local highestvalue:Int
        For Local y1=y To y+h
        For Local x1=x To x+w
            If x1>=0 And x1<mapwidth And y1>=0 And y1<mapheight
                Local a:Int = map[x1][y1]
                a+=1
                If a>highestvalue Then highestvalue = a
                map[x1][y1] = a 
            End If
        Next
        Next
        Return highestvalue
    End Method
    Method draw()
        ' world map
        ' This function draws the map
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            Local c:Int=map[x][y]*10
            'water (low)
            If map[x][y] > 0 Then SetColor 0,0,100
            If map[x][y] > 5 Then SetColor 0,0,200
            If map[x][y] > 8 Then SetColor 0,0,250
            'grass (higher)
            If map[x][y] >=10 Then SetColor 0,c,0            
            'hills (higher)
            If map[x][y] >=15 Then SetColor c,c/2,0            
            'mountains (highest)
            If map[x][y] >=20 Then SetColor c,c,c                        
            DrawRect Float(x)*tilewidth,Float(y)*tileheight,tilewidth+1,tileheight+1
        Next
        Next
        'heightmap
        SetScissor 320,0,320,480
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            Local c:Int=map[x][y]*10
            SetColor c,c,c
            DrawRect Float(x)*tilewidth,Float(y)*tileheight,tilewidth+1,tileheight+1        
        Next
        Next
        SetScissor 0,0,640,480
    End Method
End Class

Global mymap:hill

Class MyGame Extends App
    Field count:Int
    Method OnCreate()
        Seed = GetDate[5]
        SetUpdateRate(1)
        mymap = New hill(50,50)
    End Method
    Method OnUpdate()        
        count+=1
        If count>2 Then
            count=0
            Local s:Int=Rnd(32,320)
            mymap = New hill(s,s)
        End If
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymap.draw
        SetColor 255,255,255
        DrawText "Hill Algorithm",0,0
        DrawText "World Map",0,20
        DrawText "Height map",320,20
    End Method
End Class


Function Main()
    New MyGame()
End Function

Friday, February 3, 2017

Monkey-X - Circle Packing - Code Example

Import mojo

Class circle
    Field x:Int,y:Int
    Field radius:Int
    Method New()
        radius = 2
        Local exitloop:Bool=False
        While exitloop = False
            exitloop=True
            Self.x = Rnd(DeviceWidth)
            Self.y = Rnd(DeviceHeight)
            For Local i:=Eachin mycircle
                If i.x = x And i.y = y Then
                    Else
                    If circleoverlap(    i.x,i.y,i.radius,
                                        x,y,2) = True Then
                        exitloop=False
                    End If
                End If
            Next
        Wend
    End Method
    Method grow()
        If x-radius<0 Then Return
        If x+radius>DeviceWidth Then Return
        If y-radius<0 Then Return
        If y+radius>DeviceHeight Then Return
        For Local i:=Eachin mycircle
            If i.x=x And i.y=y Then
            Else
                If circleoverlap(    x,y,radius,
                                    i.x,i.y,i.radius)
                    Return
                End If 
            End If
        Next
        radius+=1
    End Method
    Method draw()
        SetColor 255,255,255
        DrawCircle x,y,radius
        SetColor 0,0,0
        DrawCircle x,y,radius-2
    End Method
    Function circleoverlap:Bool(x1:Int,y1:Int,r1:Int,x2:Int,y2:Int,r2:Int)
        Local dx:Int = x1-x2
        Local dy:Int = y1-y2
        Local r:Int = r1+r2
        If dx*dx+dy*dy <= r*r Then Return True Else Return False
    End Function    
End Class

Global mycircle:List<circle> = New List<circle>

Class MyGame Extends App
    Field counter:Int
    Method OnCreate()
        SetUpdateRate(5)
        mycircle.AddLast(New circle())
    End Method
    Method OnUpdate()   
        If counter>100 Then Return
        For Local i=0 Until 5
            mycircle.AddLast(New circle())
        Next
        For Local i:=Eachin mycircle
            i.grow
        Next
        counter+=1
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        For Local i:=Eachin mycircle
            i.draw
        Next
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Getting Started - Default Parameters - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()   
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        Scale 2,2
        defaultparameter(0,0)
        defaultparameter(0,20,100,200,"Not Default")
    End Method
End Class

' Like with variable declaration you can set a value to 
' a variable in a function or method.
Function defaultparameter(x:Int,y:Int,a:Int=10,b:Int=20,c:String="default")
    DrawText "a="+a+" b="+b+" c="+c,x,y
End Function

Function Main()
    New MyGame()
End Function

Monkey-X - Getting Started - Exit - code example


Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()   
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        Scale 2,2
        For Local i=0 To 10
            DrawText "value i = "+i,0,i*10
            If i>=5 Then Exit ' <<<<<<<<<< Exit here on condition
        Next
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Select and Default - code example


Import mojo

Class MyGame Extends App
    Field lastvalue:Int=0
    Field laststring:String
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()   
        If KeyDown(KEY_1) Then lastvalue = 1
        If KeyDown(KEY_2) Then lastvalue = 2
        If KeyDown(KEY_3) Then laststring = "the string"
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        Scale 2,2
        DrawText "Press the 1 or 2 or 3 keys",0,0
        Select lastvalue
            Case 1
                DrawText "Last key pressed is 1",10,20
            Case 2
                DrawText "Last key pressed is 2",10,20
            Default
                DrawText "1 or 2 key was not pressed.",10,20
        End Select
        Select laststring
            Case "the string"
                DrawText "3 Key was pressed.",10,40
            Default
                DrawText "3 Key was not pressed.",10,40
        End Select
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Floodfill map distance - code example


Import mojo

Global screenwidth:Int=640
Global screenheight:Int=480
Global mapwidth:Int=20
Global mapheight:Int=20
Global tilewidth:Float=Float(screenwidth)/Float(mapwidth)
Global tileheight:Float=Float(screenheight)/Float(mapheight)

Class MyGame Extends App
    Field flood:Bool=False
    Field fillval:Int=1
    Field delay:Int
    Field map:Int[][]
    Field mapd:Int[][] 'map containing the distance (distance map)
    Field floodx:Stack<Int> = New Stack<Int> 'flood 
    Field floody:Stack<Int> = New Stack<Int>
    Field floodv:Stack<Int> = New Stack<Int> 'distance
    Field mx:Int[] = [0,1,0,-1] 'expand up/right/down/left
    Field my:Int[] = [-1,0,1,0]
    Method OnCreate()
        SetUpdateRate(60)
        map = New Int[mapwidth][]
        For Local i=0 Until mapwidth
            map[i] = New Int[mapheight]
        Next
        mapd = New Int[mapwidth][]
        For Local i=0 Until mapwidth
            mapd[i] = New Int[mapheight]
        Next
        For Local x=0 Until mapwidth/2
            map[x][mapheight/2] = 6
        Next
    End Method
    Method OnUpdate()
        Local tx:Int=MouseX()/tilewidth
        Local ty:Int=MouseY()/tileheight
        If MouseDown(MOUSE_LEFT) And flood=False And map[tx][ty] <> 6
            Print "Flooding - "+Millisecs()
            floodx.Clear
            floody.Clear
            floodv.Clear
            For Local y=0 Until mapheight
            For Local x=0 Until mapwidth
                mapd[x][y] = 0
            Next
            Next
            floodx.Push(tx)
            floody.Push(ty)
            floodv.Push(1)
            flood = True
            fillval+=1
            If fillval > 5 Then fillval = 0
            map[tx][ty] = fillval
            mapd[tx][ty] = 1
        End If
        If flood = True
            If floodx.Length > 0
            Local x1:Int=floodx.Top
            Local y1:Int=floody.Top
            Local v1:Int=floodv.Top
            floodx.Pop
            floody.Pop
            floodv.Pop
            For Local i=0 Until 4
                Local x2:Int=x1+mx[i]
                Local y2:Int=y1+my[i]
                If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight
                If map[x2][y2] <> fillval
                If map[x2][y2] <> 6
                    map[x2][y2] = fillval
                    ' if you insert the new locations at the bottom
                    ' of the list then you will get correct distance values (flooding)
                    floodx.Insert(0,x2)
                    floody.Insert(0,y2)
                    floodv.Insert(0,v1+1)
                    'store the distance in the map
                    mapd[x2][y2] = v1+1
                End If
                End If
                End If
            Next
            Else
            flood=False
            Print "Flooding done"
            End If
        End If
    End Method
    Method OnRender()
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            Local col:Int=map[x][y]
            SetColor col*30,col*30,col*30
            DrawRect x*tilewidth,y*tileheight,tilewidth+1,tileheight+1
        Next
        Next
        For Local i=0 Until floodx.Length
                SetColor 255,255,0
            DrawCircle floodx.Get(i)*tilewidth+tilewidth/2,floody.Get(i)*tileheight+tileheight/2,tilewidth/2
        Next
        SetColor 255,255,255
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            DrawText mapd[x][y],x*tilewidth+tilewidth-10,y*tileheight+tileheight-10
        Next
        Next
        SetColor 255,255,255
        DrawText "Press Left Mouse (touch) to flood map..",0,0
    End Method

End Class

Function Main()
    New MyGame()
End Function

Monkey-X - RTS - Floodfill or Seedfill group pathfinding - code example


Import mojo

Global screenwidth:Int=640
Global screenheight:Int=480
Global mapwidth:Int=20
Global mapheight:Int=20
Global tilewidth:Float=Float(screenwidth)/Float(mapwidth)
Global tileheight:Float=Float(screenheight)/Float(mapheight)
Global map:Int[][]
Global mapd:Int[][] 'map containing the distance (distance map)
Global mx:Int[] = [0,1,0,-1] 'expand up/right/down/left
Global my:Int[] = [-1,0,1,0]


Class ai
    Field x:Int,y:Int
    Field speed:Int=Rnd(1,9)
    Field px:Int,py:Int,pdx:Int,pdy:Int
    Field delay:Int
    Field maxdelay:Int
    Method New()
        maxdelay=Rnd(20,60)
        Local exitloop:Bool=False
        While exitloop=False
        x=Rnd(mapwidth)
        y=Rnd(mapheight)
        If map[x][y] <> 6 Then exitloop = True
        Wend
        px = x*tilewidth
        py = y*tileheight
        pdx = px
        pdy = py
    End Method
    Method update()
        For Local s=0 Until speed
        If px<pdx Then px+=1
        If px>pdx Then px-=1
        If py<pdy Then py+=1
        If py>pdy Then py-=1
        If px=pdx And py=pdy
        Local lx:Stack<Int> = New Stack<Int>
        Local ly:Stack<Int> = New Stack<Int>
        Local lv:Stack<Int> = New Stack<Int>
        For Local i=0 Until 4
            Local x1:Int=x+mx[i]
            Local y1:Int=y+my[i]
            If x1>=0 And x1<mapwidth And y1>=0 And y1<mapheight
            If map[x1][y1] <> 6
            If mapd[x1][y1] <> 0
            Local cont:Bool=True
            For Local ii:=Eachin myai
                If ii.x = x1 And ii.y = y1 Then cont=False
            Next
            If cont=True
            lx.Push(x1)
            ly.Push(y1)
            lv.Push(mapd[x1][y1])
            End If
            End If
            End If
            End If
        Next
        ' fidn the lowest value around unit
        Local lowest:Int=1000
        For Local i=0 Until lx.Length            
            If lv.Get(i) < lowest
                lowest = lv.Get(i)
            End If
        Next
        ' if more then one lowest value then select random 
        Local exitloop:Bool=False
        While exitloop=False And lx.Length>0
        For Local i=0 Until lx.Length
            If lv.Get(i) = lowest And Rnd()<.2 Then
            x = lx.Get(i)            
            y = ly.Get(i)
            pdx = x*tilewidth
            pdy = y*tileheight
            exitloop=True
            End If
        Next    
        wend
        End If
        Next
    End Method
    Method draw()
        SetColor 255,0,0
        DrawOval px,py,tilewidth,tileheight
    End Method
End Class

Global myai:List<ai> = New List<ai>

Class MyGame Extends App
    Field flood:Bool=False
    Field fillval:Int=1
    Field delay:Int
    Field floodx:Stack<Int> = New Stack<Int> 'flood 
    Field floody:Stack<Int> = New Stack<Int>
    Field floodv:Stack<Int> = New Stack<Int> 'distance
    Method OnCreate()
        SetUpdateRate(60)
        map = New Int[mapwidth][]
        For Local i=0 Until mapwidth
            map[i] = New Int[mapheight]
        Next
        mapd = New Int[mapwidth][]
        For Local i=0 Until mapwidth
            mapd[i] = New Int[mapheight]
        Next
        For Local x=0 Until mapwidth/2
            map[x][mapheight/2] = 6
        Next
        For Local x=6 To 15
        For Local y=10 To 15
            map[x][y] = 6
        Next
        Next
        For Local i=0 To 20
            myai.AddLast(New ai)
        Next
    End Method
    Method OnUpdate()
        ' move the ai
        For Local i:=Eachin myai
            i.update
        Next
        '
        Local tx:Int=MouseX()/tilewidth
        Local ty:Int=MouseY()/tileheight
        If MouseDown(MOUSE_LEFT) And flood=False And map[tx][ty] <> 6
            Print "Flooding - "+Millisecs()
            floodx.Clear
            floody.Clear
            floodv.Clear
            For Local y=0 Until mapheight
            For Local x=0 Until mapwidth
                mapd[x][y] = 0
            Next
            Next
            floodx.Push(tx)
            floody.Push(ty)
            floodv.Push(1)
            flood = True
            fillval+=1
            If fillval > 5 Then fillval = 0
            map[tx][ty] = fillval
            mapd[tx][ty] = 1
        End If
        If flood = True
            If floodx.Length > 0
            Local x1:Int=floodx.Top
            Local y1:Int=floody.Top
            Local v1:Int=floodv.Top
            floodx.Pop
            floody.Pop
            floodv.Pop
            For Local i=0 Until 4
                Local x2:Int=x1+mx[i]
                Local y2:Int=y1+my[i]
                If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight
                If map[x2][y2] <> fillval
                If map[x2][y2] <> 6
                    map[x2][y2] = fillval
                    ' if you insert the new locations at the bottom
                    ' of the list then you will get correct distance values (flooding)
                    floodx.Insert(0,x2)
                    floody.Insert(0,y2)
                    floodv.Insert(0,v1+1)
                    'store the distance in the map
                    mapd[x2][y2] = v1+1
                End If
                End If
                End If
            Next
            Else
            flood=False
            Print "Flooding done"
            End If
        End If
    End Method
    Method OnRender()
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            Local col:Int=map[x][y]
            SetColor col*30,col*30,col*30
            DrawRect x*tilewidth,y*tileheight,tilewidth+1,tileheight+1
        Next
        Next
        For Local i=0 Until floodx.Length
                SetColor 255,255,0
            DrawCircle floodx.Get(i)*tilewidth+tilewidth/2,floody.Get(i)*tileheight+tileheight/2,tilewidth/2
        Next
        SetColor 255,255,255
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            DrawText mapd[x][y],x*tilewidth+tilewidth-10,y*tileheight+tileheight-10
        Next
        Next
        '
        For Local i:=Eachin myai
            i.draw
        Next
        '
        SetColor 255,255,255
        DrawText "Press Left Mouse (touch) to flood map and move units..",0,0
    End Method

End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Roguelike Maps - code example


' based on a description from the rogue basin forum
' what it does it place random dots with unique id
' connect closest of different id
' make same id of last point
' until all points
' loop through all lines and fill map under the lines.

Import mojo

Global mapwidth:Int=50
Global mapheight:Int=50
Global sw:Int=640
Global sh:Int=480

Class map
    Field mw:Int,mh:Int,sw:Int,sh:Int,tw:Float,th:Float
    Field mypoint:Stack<point> = New Stack<point>
    Field myline:Stack<line> = New Stack<line>
    Field map:Int[][]
    Method New(sw:Int,sh:Int,mw:Int,mh:Int)
        Self.sw = sw
        Self.sh = sh
        Self.mw = mw
        Self.mh = mh
        Self.tw = Float(sw)/Float(mw)
        Self.th = Float(sh)/Float(mh)
        map = New Int[mw][]
        For Local i=0 Until mw
            map[i] = New Int[mh]
        Next
        For Local i=0 Until mw*mh/200
            Local x:Int=Rnd(5,mw-5)
            Local y:Int=Rnd(5,mh-5)
            mypoint.Push(New point(i,x,y))
        Next
        makemap()
    End Method
    Method makemap()
        ' connect point to closest point with unique id
        'get first point
        Local x:Int=mypoint.Get(0).x
        Local y:Int=mypoint.Get(0).y
        Local id:Int=mypoint.Get(0).id 
        Local closestindex:Int=0
        While closestindex<>-1
            'find closest
            Local dist:Int=10000        
            closestindex=-1        
            For Local ii=0 Until mypoint.Length
                If mypoint.Get(ii).id <> id
                Local d:Int=distance(x,y,mypoint.Get(ii).x,mypoint.Get(ii).y) 
                If d<dist Then            
                    dist=d
                    closestindex = ii
                End If
                End If
            Next
            If closestindex>-1
                mypoint.Get(closestindex).id = id
                myline.Push(New line(x,y,mypoint.Get(closestindex).x,mypoint.Get(closestindex).y))
                x = mypoint.Get(closestindex).x
                y = mypoint.Get(closestindex).y
            End If
        Wend
        'make the map
        For Local i:=Eachin myline
            Local x1:Int=i.x1
            Local y1:Int=i.y1
            Local x2:Int=i.x2
            Local y2:Int=i.y2
            Local exitloop:Bool=False
            While exitloop=False
                If x1<x2 Then x1+=1
                If x1>x2 Then x1-=1
                If y1<y2 Then y1+=1
                If y1>y2 Then y1-=1
                If x1=x2 And y1=y2 Then exitloop=True
                ' create the tunnel size
                Local s:Int=Rnd(1,3)
                ' sometimes make a wider tunnel
                If Rnd(mw*mh)< (mw*mh/7) Then s=Rnd(s,s*3)
                putmap(x1,y1,s)
            Wend
        Next
    End Method
    Method putmap(x:Int,y:Int,s:Int)
        For Local y3=-s To s
        For Local x3=-s To s
            Local x4:Int=x+x3
            Local y4:Int=y+y3
            If x4>=0 And x4<mw And y4>=0 And y4<mh
            map[x4][y4] = 1
            End If
        Next
        Next    
    End Method
    Method draw()
        SetColor 155,50,0
        For Local y=0 Until mh
        For Local x=0 Until mw
            If map[x][y] = 1
                DrawRect x*tw,y*th,tw+1,th+1
            End If
        Next
        Next
        SetColor 255,255,0
        For Local i:=Eachin myline
            Local x1:Int=i.x1*tw
            Local y1:Int=i.y1*th
            Local x2:Int=i.x2*tw
            Local y2:Int=i.y2*th        
            DrawLine x1,y1,x2,y2
        Next
        SetColor 255,0,0
        For Local i:=Eachin mypoint
            DrawRect i.x*tw,i.y*th,5,5
            DrawText i.id,i.x*tw,i.y*th
        Next

    End Method
    Method distance:Int(x1:Int,y1:Int,x2:Int,y2:Int)
        Return Abs(x2-x1)+Abs(y2-y1)
    End Method    
End Class

Class point
    Field id:Int
    Field x:Int,y:Int
    Method New(id:Int,x:Int,y:Int)
        Self.id = id
        Self.x = x
        Self.y = y
    End Method
End Class
Class line
    Field x1:Int,y1:Int
    Field x2:Int,y2:Int
    Method New(x1:Int,y1:Int,x2:Int,y2:Int)
        Self.x1 = x1
        Self.y1 = y1
        Self.x2 = x2
        Self.y2 = y2
    End Method
End Class

Global mymap:map

Class MyGame Extends App
    Field cnt:Int=0
    Method OnCreate()
        SetUpdateRate(10)
        mymap = New map(640,480,mapwidth,mapheight)
    End Method
    Method OnUpdate()        
        cnt+=1
        If cnt>100 Or KeyDown(KEY_SPACE) Or MouseDown(MOUSE_LEFT) Then 
            Seed = Millisecs()
            cnt=0
            Local w:Int=Rnd(50,200)
            Local h:Int=w
            mymap = New map(640,480,w,h)
        End If
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymap.draw
        SetColor 255,255,255
        DrawText "RogueLike maps - Press Space or Mouse Button for new map or wait",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Roguelike Explorer - code example


Import mojo

Global mapwidth:Int=50
Global mapheight:Int=50
Global sw:Int=640
Global sh:Int=480

Class player
    Field x:Int,y:Int,controldelay:Int
    Field tleft:Bool,tright:Bool,tup:Bool,tdown:Bool
    Field tleftx:Int=20
    Field tlefty:Int=sh-100
    Field trightx:Int=120
    Field trighty:Int=sh-100
    Field tupx:Int=70
    Field tupy:Int=sh-150
    Field tdownx:Int=70
    Field tdowny:Int=sh-50
    Method New()
         x = mymap.mypoint.Get(1).x
         y = mymap.mypoint.Get(1).y
         playerfog(x,y,6)
    End Method
    Method update()
        controldelay+=1
        If controldelay<10 Then Return
        'touch mouse input
        If MouseDown(MOUSE_LEFT) Or TouchDown
            Local x:Int
            Local y:Int
            Local w:Int=100
            Local h:Int=50
            x = tupx
            y = tupy
            If rectsoverlap(x,y,w,h,MouseX(),MouseY(),1,1) Then tup=True
            x = tdownx
            y = tdowny
            If rectsoverlap(x,y,w,h,MouseX(),MouseY(),1,1) Then tdown=True
            x = tleftx
            y = tlefty
            If rectsoverlap(x,y,w,h,MouseX(),MouseY(),1,1) Then tleft=True
            x = trightx
            y = trighty
            If rectsoverlap(x,y,w,h,MouseX(),MouseY(),1,1) Then tright=True
        End If

        'keyinput
        If KeyDown(KEY_UP) Or tup
            If y-1 >= 0 
                If mymap.map[x][y-1] = 1 Then y-=1
                controldelay = 0
                playerfog(x,y,6)
            End If
        End If
        If KeyDown(KEY_DOWN) Or tdown
            If y+1 < mymap.mh
                If mymap.map[x][y+1] = 1 Then y+=1
                controldelay = 0
                playerfog(x,y,6)
            End If
        End If
        If KeyDown(KEY_RIGHT) Or tright
            If x+1 < mymap.mw
                If mymap.map[x+1][y] = 1 Then x+=1
                controldelay = 0
                playerfog(x,y,6)
            End If
        End If
        If KeyDown(KEY_LEFT) Or tleft
            If x-1 >=0 
                If mymap.map[x-1][y] = 1 Then x-=1
                controldelay = 0
                playerfog(x,y,6)
            End If
        End If
        tup=False
        tright=False
        tdown=False
        tleft=false
    End Method
    Method draw()
        SetColor 255,255,255
        Local tw:Float=mymap.tw
        Local th:Float=mymap.th
        DrawRect x*tw,y*th,tw,th
        SetColor 255,255,0
        DrawRect tleftx,tlefty,100,50
        SetColor 255,255,255
        DrawText "Left",tleftx+50,tlefty+25,0.5,0.5
        SetColor 255,255,0
        DrawRect trightx,trighty,100,50
        SetColor 255,255,255
        DrawText "Right",trightx+50,trighty+25,0.5,0.5
        SetColor 255,255,0
        DrawRect tupx,tupy,100,50
        SetColor 255,255,255
        DrawText "Up",tupx+50,tupy+25,0.5,0.5
        SetColor 255,255,0
        DrawRect tdownx,tdowny,100,50
        SetColor 255,255,255
        DrawText "Down",tdownx+50,tdowny+25,0.5,0.5

    End Method
    Method playerfog(x1,y1,radius:Float)
        For Local y2=-radius To radius
        For Local x2=-radius To radius
            If (y2*y2+x2*x2) <= radius*radius+radius*0.8
                Local x3 = x2+x1
                Local y3 = y2+y1
                If x3>=0 And x3<mymap.mw And y3>=0 And y3<mymap.mh
                    mymap.fogmap[x3][y3] = True
                End If
            End If
        Next
        Next    
    End Method
    Method rectsoverlap:Bool(x1:Int, y1:Int, w1:Int, h1:Int, x2:Int, y2:Int, w2:Int, h2:Int)
        If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
        If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
        Return True
    End Method 
End Class

Class map
    Field mw:Int,mh:Int,sw:Int,sh:Int,tw:Float,th:Float
    Field mypoint:Stack<point> = New Stack<point>
    Field myline:Stack<line> = New Stack<line>
    Field map:Int[][]
    Field fogmap:Bool[][]
    Method New(sw:Int,sh:Int,mw:Int,mh:Int)
        Self.sw = sw
        Self.sh = sh
        Self.mw = mw
        Self.mh = mh
        Self.tw = Float(sw)/Float(mw)
        Self.th = Float(sh)/Float(mh)
        map = New Int[mw][]
        fogmap = New Bool[mw][]
        For Local i=0 Until mw
            map[i] = New Int[mh]
            fogmap[i] = New Bool[mh]
        Next
        For Local i=0 Until mw*mh/200
            Local x:Int=Rnd(5,mw-5)
            Local y:Int=Rnd(5,mh-5)
            If rectsoverlap(x*tw,y*th,1,1,0,sh-240,320,240) = False
            mypoint.Push(New point(i,x,y))
            End If
        Next
        makemap()
    End Method
    Method makemap()
        ' connect point to closest point with unique id
        'get first point
        Local x:Int=mypoint.Get(0).x
        Local y:Int=mypoint.Get(0).y
        Local id:Int=mypoint.Get(0).id 
        Local closestindex:Int=0
        While closestindex<>-1
            'find closest
            Local dist:Int=10000        
            closestindex=-1        
            For Local ii=0 Until mypoint.Length
                If mypoint.Get(ii).id <> id
                Local d:Int=distance(x,y,mypoint.Get(ii).x,mypoint.Get(ii).y) 
                If d<dist Then            
                    dist=d
                    closestindex = ii
                End If
                End If
            Next
            If closestindex>-1
                mypoint.Get(closestindex).id = id
                myline.Push(New line(x,y,mypoint.Get(closestindex).x,mypoint.Get(closestindex).y))
                x = mypoint.Get(closestindex).x
                y = mypoint.Get(closestindex).y
            End If
        Wend
        'make the map
        For Local i:=Eachin myline
            Local x1:Int=i.x1
            Local y1:Int=i.y1
            Local x2:Int=i.x2
            Local y2:Int=i.y2
            Local exitloop:Bool=False
            While exitloop=False
                If x1<x2 Then x1+=1
                If x1>x2 Then x1-=1
                If y1<y2 Then y1+=1
                If y1>y2 Then y1-=1
                If x1=x2 And y1=y2 Then exitloop=True
                ' create the tunnel size
                Local s:Int=Rnd(1,3)
                ' sometimes make a wider tunnel
                If Rnd(mw*mh)< (mw*mh/7) Then s=Rnd(s,s*3)
                putmap(x1,y1,s)
            Wend
        Next
    End Method
    Method putmap(x:Int,y:Int,s:Int)
        For Local y3=-s To s
        For Local x3=-s To s
            Local x4:Int=x+x3
            Local y4:Int=y+y3
            If x4>=0 And x4<mw And y4>=0 And y4<mh
            map[x4][y4] = 1
            End If
        Next
        Next    
    End Method
    Method draw()
        SetColor 155,50,0
        For Local y=0 Until mh
        For Local x=0 Until mw
            If map[x][y] = 1 And fogmap[x][y] = true
                DrawRect x*tw,y*th,tw+1,th+1
            End If
        Next
        Next
    End Method
    Method distance:Int(x1:Int,y1:Int,x2:Int,y2:Int)
        Return Abs(x2-x1)+Abs(y2-y1)
    End Method    
    Method rectsoverlap:Bool(x1:Int, y1:Int, w1:Int, h1:Int, x2:Int, y2:Int, w2:Int, h2:Int)
        If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
        If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
        Return True
    End Method 
End Class

Class point
    Field id:Int
    Field x:Int,y:Int
    Method New(id:Int,x:Int,y:Int)
        Self.id = id
        Self.x = x
        Self.y = y
    End Method
End Class
Class line
    Field x1:Int,y1:Int
    Field x2:Int,y2:Int
    Method New(x1:Int,y1:Int,x2:Int,y2:Int)
        Self.x1 = x1
        Self.y1 = y1
        Self.x2 = x2
        Self.y2 = y2
    End Method
End Class

Global mymap:map
Global myplayer:player

Class MyGame Extends App
    Field mapexplored:Bool=False
    Field w:Int=mapwidth,h:Int=mapheight
    Method OnCreate()
        SetUpdateRate(60)
        mymap = New map(640,480,w,h)
        myplayer = New player()
    End Method
    Method OnUpdate()        
        If KeyDown(KEY_SPACE) Or mapexplored = True Then 
            mapexplored = False
            Seed = Millisecs()
            w+=2
            h+=2
            If w>300 Then w = 50 ; h = 50
            mymap = New map(640,480,w,h)
            myplayer = New player()
        End If
        myplayer.update
        If Rnd()<.01 And ismapexplored() Then mapexplored=True
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymap.draw
        myplayer.draw
        SetColor 255,255,255
        SetAlpha 0.5
        DrawText "RogueLike random maps and fog of war and player. space/mouse new map, cursors move.",0,0
        DrawText "If everything is explored a new map is created.",0,15
    End Method
End Class

Function ismapexplored:Bool()
    Local ex:Bool=True
    For Local y=0 Until mymap.mh
    For Local x=0 Until mymap.mw
        If mymap.map[x][y] = 1 And mymap.fogmap[x][y] = False Then ex=False
    Next
    Next
    Return ex
End Function

Function Main()
    New MyGame()
End Function

Monkey-X - Rectangle Collision Helper - code example


Import mojo

Class line
    Field x1:Int,y1:Int
    Field x2:Int,y2:Int
    Field w:Int,h:Int
    Field r:Int,g:Int,b:Int
    Method New(x1:Int,y1:Int,w:Int,h:Int)
        Self.x1 = x1
        Self.y1 = y1
        Self.w = w
        Self.h = h
        Self.x2 = x1+w
        Self.y2 = y1+h
    End Method
    Method newpos(x:Int,y:Int)
        x1=x
        y1=y
        x2=x1+w
        y2=y1+h
    End Method
    Method mysetcolor(r:Int,g:Int,b:Int)
        Self.r = r
        Self.g = g
        Self.b = b        
    End Method
    Method draw()
        SetColor r,g,b
        DrawRect x1,y1,w,h
    End Method
End Class

Class MyGame Extends App
    Field line1:line = New line(150,150,100,100)
    Field line2:line = New line(200,200,100,100)
    Method OnCreate()
        SetUpdateRate(60)
        line1.mysetcolor(200,0,0)
        line2.mysetcolor(0,200,0)
    End Method
    Method OnUpdate()    
        line1.newpos(MouseX(),MouseY())
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        drawthickline 10,10,10,DeviceHeight-10
        drawthickline 10,DeviceHeight-10,DeviceWidth-10,DeviceHeight-10
        line1.draw
        line2.draw
        ' draw the sidelines
        'left
        Local y1:Int=line1.y1
        Local y2:Int=line1.y2
        SetColor 200,50,0
        drawthickline 11,y1,11,y2        
        y1=line2.y1
        y2=line2.y2
        SetColor 50,200,0
        drawthickline 15,y1,15,y2
        'bottom
        Local x1:Int=line1.x1
        Local x2:Int=line1.x2
        SetColor 200,50,0
        drawthickline x1,DeviceHeight-11,x2,DeviceHeight-11
        x1=line2.x1
        x2=line2.x2
        SetColor 50,200,0
        drawthickline x1,DeviceHeight-15,x2,DeviceHeight-15
        'info
        Scale 2,2
        SetColor 255,255,255
        DrawText "When 2 sets of lines are overlapping then",30,0
        DrawText "a rectangular collision is happening...",30,20
        DrawText "Move block with mouse",30,(DeviceHeight-50)/2
        SetColor 255,255,0
        If rectsoverlap(    line1.x1,line1.y1,line1.w,line1.h,
                            line2.x1,line2.y1,line2.w,line2.h)
            DrawText "Collision is happening",30,40
        End If
    End Method
End Class

Function drawthickline(x1:Int,y1:Int,x2:Int,y2:Int)
    For Local y=-2 To 2
    For Local x=-2 To 2
        DrawLine x1+x,y1+y,x2+x,y2+y
    Next
    Next
End Function

Function rectsoverlap:Bool(x1:Int, y1:Int, w1:Int, h1:Int, x2:Int, y2:Int, w2:Int, h2:Int)
    If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
    If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
    Return True
End

Function Main()
    New MyGame()
End Function