Saturday, February 28, 2015

Monkey-X - Shitting hamster algorithm - code example


I read about this. A algorithm that lets the ai explore the entire map. It works by adding a value to the map where the hamster is and he then finds a new location with a lower value. The adding of the value in the map is called shitting. (looking for the cleanest place)

Code below :

Import mojo

Const numhamsters:Int=4
Global tilewidth:Int=20
Global tileheight:Int=20
Global mapwidth:Int=640/tilewidth
Global mapheight:Int=480/tileheight
Global searchmap:Int[][] = New Int[mapwidth][]

Class hamsters
    Field x:Int,y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
    Method update()
        Local x1:Int=0
        Local y1:Int=0
        Local val:Int=searchmap[x][y]
        searchmap[x][y] += 1
        Local exitloop:Bool = False
        Local cnt:Int=0
        While exitloop = False
            cnt+=1
            For Local y2=-1 To 1
            For Local x2=-1 To 1
                Local x3:Int=x+x2
                Local y3:Int=y+y2
                If x3>=0 And y3>= 0 And x3<mapwidth And y3<mapheight
                    If searchmap[x3][y3] <= val Or cnt>10
                        If Rnd(10)<2
                        x1 = x3 ; y1 = y3
                        exitloop = True
                        Exit
                        End If
                    End If
                End If
            Next
            Next
        Wend
        x=x1
        y=y1        
    End Method
    Method draw()
        SetColor 255,0,0
        DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight
    End Method
End Class

Global hamster:List<hamsters> = New List<hamsters>

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(20)
        For Local i=0 Until mapwidth
            searchmap[i] = New Int[mapheight]
        Next
        For Local i=0 Until numhamsters
            hamster.AddLast(New hamsters(Rnd(2,mapwidth-4),Rnd(2,mapheight-4)))
        Next
    End Method
    Method OnUpdate()
        For Local i:=Eachin hamster
            i.update
        Next        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            Local m:String=searchmap[x][y]
            PushMatrix()
            Scale 0.7,0.7
            DrawText m,(x*tilewidth)*1.4,(y*tileheight)*1.4
            PopMatrix()
        Next
        Next
        For Local i:=Eachin hamster
            i.draw
        Next
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Lists in arrays - code example


Here a example of how to put Lists in arrays.

Import mojo

Global a:List<test>[] = New List<test>[10]

Class test
    Field x:Int,y:Int,m:String
    Method New(x:Int,y:Int,m:String)
        Self.x = x
        Self.y = y
        Self.m = m
    End Method
End Class


Class MyGame Extends App
    Method OnCreate()
        a[0] = New List<test>        
        a[1] = New List<test>
        a[0].AddLast(New test(10,10,"List 1"))
        a[1].AddLast(New test(20,20,"List 2"))
        SetUpdateRate(60)
    End Method    
    Method OnUpdate()
    End Method    
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Lists inside arrays example.",0,0
        For Local i:=Eachin a[0]
            Local m:String=i.x+","+i.y+","+i.m
            DrawText m,0,15
        Next
        For Local i:=Eachin a[1]
            Local m:String=i.x+","+i.y+","+i.m
            DrawText m,0,30
        Next
    End Method    
End Class

Function Main()
    New MyGame()
End Function

Friday, February 27, 2015

Monkey-X - Map generator (zones) - code example


Here another map generator I made. It uses a method that I read about in one of my game ai books.

Code below :

Import mojo

Global tilewidth:Int=10
Global tileheight:Int=10
Global mapwidth:Int=640/tilewidth
Global mapheight:Int=480/tileheight
Global map:Int[][] = New Int[mapwidth][]
 
Class openlist
    Field x:Int,y:Int,delete:Bool=False
    Field val:Int
    Method New(x:Int,y:Int,val:Int)
        Self.x = x
        Self.y = y
        Self.val = val
    End Method
End Class 

Global nextmaptime:Int = Millisecs()+6000
 
Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
          map = New Int[mapwidth][]
        For Local i = 0 Until mapwidth
            map[i] = New Int[mapheight]
        Next
        createmap(Rnd(10)+5)
    End Method        
    Method OnUpdate()
        Seed = Millisecs()
        If Millisecs() > nextmaptime
            createmap(Rnd(10)+5)
            nextmaptime = Millisecs()+6000
        End If
    End Method
    Method OnRender()
        Cls 0,0,0
        SetColor 255,255,255
        drawmap
    End Method
End Class

Function drawmap:Void()
    SetColor 255,255,255
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        SetColor 200,map[x][y]*10,0
        If map[x][y] = 1 Then SetColor 0,0,200
        If map[x][y] = 7 Then SetColor 0,0,200
        If map[x][y] > 0
            DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight
        End If
    Next
    Next
End Function

Function createmap:Void(numrooms:Int=5)
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        map[x][y] = 0
    Next
    Next    
    Local ol:List<openlist> = New List<openlist>
    For Local i=0 To numrooms
        Local exitloop:Bool=False
        While exitloop = False
            Local x:Int = Rnd(mapwidth)
            Local y:Int = Rnd(mapheight)
            Local set:Bool=True
            For Local ii:=Eachin ol
                If ii.x = x And ii.y = y Then set=False
                If distance(ii.x,ii.y,x,y) < 7 Then set=False                
            Next
            If set = True Then
                ol.AddLast(New openlist(x,y,i+1))
                exitloop = True
            End If
        Wend
    Next
    Local exitloop = False
    Local cx:Int,cy:Int
    While ol.IsEmpty() = False
        For Local i:=Eachin ol
            If Rnd(1000)<2
                For Local y=-1 To 1
                For Local x=-1 To 1
                    Local x1=i.x+x
                    Local y1=i.y+y                    
                    If x1>=0 And y1>=0 And x1<mapwidth And y1<mapheight
                    If map[x1][y1] = 0
                        ol.AddLast(New openlist(x1,y1,i.val))
                        map[x1][y1] = i.val
                    End If
                    End If
                Next
                Next
                i.delete = True
            End If 
        Next
        For Local i:=Eachin ol
            If i.delete = True Then ol.Remove i
        Next
    Wend
End Function

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

Function Main()
    New MyGame()
End Function

Monkey-X - Screenwipe in and out - code example


Here is another screenwipe. This one draws a rectangle on top of the map which grows or shrinks.

Code below :

Import mojo

Class map
    Field tilewidth:Int,tileheight:Int
    Field mapwidth:Int,mapheight:Int
    Field map:Int[][]
    Field screenwipe:Bool=False
    Field screenwipemode:String
    Field screenwipesize:Int
    Method New(mapwidth:Int,mapheight:Int,tilewidth:Int,tileheight:Int)
        Self.tilewidth = tilewidth
        Self.tileheight = tileheight
        Self.mapwidth = mapwidth
        Self.mapheight = mapheight
        map = New Int[mapwidth][]
        For Local i = 0 Until mapwidth
            map[i] = New Int[mapheight]
        Next
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            setmap(x,y,Rnd(0,5))
        Next
        Next
    End Method    
    Method update()
    End Method
    Method setmap:Void(x:Int,y:Int,val:Int)
        If x>=0 And y>=0 And x<mapwidth And y<mapheight
            map[x][y] = val
        End If
    End Method
    Method screenwipeininit()
        screenwipesize = 640
        screenwipe = True
        screenwipemode = "fadein"
    End Method
    Method screenwipeoutinit()
        screenwipesize = 0
        screenwipe = True
        screenwipemode = "fadeout"
    End Method
    Method drawmap:Void()
        For Local y1=0 Until mapheight
        For Local x1=0 Until mapwidth
            drawtile(map[x1][y1],x1*tilewidth,y1*tileheight)
        Next
        Next
        If screenwipe = True Then
            SetColor 0,0,0
            DrawRect 640/2-screenwipesize/2,480/2-screenwipesize/2,screenwipesize,screenwipesize
            If screenwipemode = "fadein"
                screenwipesize -= 10
                If screenwipesize <= 0 Then 
                    screenwipemode = "fadedone" 
                    screenwipe=False
                End If
            End If
            If screenwipemode = "fadeout"
                screenwipesize += 10
                If screenwipesize >= 640 Then 
                    screenwipemode = "fadedone" 
                    screenwipe = False
                End If
            End If
        End If
    End Method
    Method drawtile(val:Int,x1:Int,y1:Int)
        Select val
            Case 0'water
                SetColor 0,0,255
                DrawRect x1,y1,tilewidth,tileheight
            Case 1'land
                SetColor 0,200,0
                DrawRect x1,y1,tilewidth,tileheight
            Case 2'forrest
                drawtile(1,x1,y1)
                SetColor 0,255,0
                DrawOval x1+5,y1+5,tilewidth-10,tileheight/2
                SetColor 150,10,0
                DrawRect x1+12,y1+tileheight-10,tilewidth-24,tileheight/2-5
            Case 3'hill
                drawtile(1,x1,y1)
                SetColor 0,255,0
                DrawOval x1+5,y1+10,tilewidth-10,tileheight-15
                SetColor 0,200,0
                DrawRect x1,y1+tileheight/1.5,tilewidth,10
            Case 4'mountain
                drawtile(1,x1,y1)
                SetColor 200,200,200
                DrawPoly(    [Float(x1+tilewidth/2),Float(y1),
                            Float(x1+tilewidth-5),Float(y1+tileheight-5),
                            Float(x1+5),Float(y1+tileheight-5)])
        End Select
    End Method

End Class

Global mymap:map = New map(20,14,32,32)
Global screenwipetp:Int=0
Global mydelay:Int

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
        mymap.screenwipeininit
        mydelay = Millisecs() + 3000
    End Method
    Method OnUpdate()
        If Millisecs() > mydelay 'pauze between fades
            If mymap.screenwipemode = "fadedone" And screenwipetp = 0
                screenwipetp = 1
                mymap.screenwipeoutinit
            End If
            If mymap.screenwipemode = "fadedone" And screenwipetp = 1
                screenwipetp = 0
                mymap.screenwipeininit    
            End If
            mydelay = Millisecs() + 3000
        End If
    End Method
    Method OnRender()
        Cls 0,0,0
        If screenwipetp = 1 And mymap.screenwipemode = "fadedone"
        Else
            mymap.drawmap
        End If
           SetColor 255,255,255
           DrawText "Screenwipe example : "+mymap.screenwipemode,0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Fade in and Fade out - code example


Here a example of how to do screen fades. It works by drawing a black rectangle ontop of the screen with a growing/shrinking setalpha value.

Code below :

Import mojo

Class map
    Field tilewidth:Int,tileheight:Int
    Field mapwidth:Int,mapheight:Int
    Field map:Int[][]
    Field alpha:Float,fade:Bool=False
    Field fademode:String
    Method New(mapwidth:Int,mapheight:Int,tilewidth:Int,tileheight:Int)
        Self.tilewidth = tilewidth
        Self.tileheight = tileheight
        Self.mapwidth = mapwidth
        Self.mapheight = mapheight
        map = New Int[mapwidth][]
        For Local i = 0 Until mapwidth
            map[i] = New Int[mapheight]
        Next
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            setmap(x,y,Rnd(0,5))
        Next
        Next
    End Method    
    Method update()
    End Method
    Method setmap:Void(x:Int,y:Int,val:Int)
        If x>=0 And y>=0 And x<mapwidth And y<mapheight
            map[x][y] = val
        End If
    End Method
    Method fadeininit()
        alpha = 1
        fade = True
        fademode = "fadein"
    End Method
    Method fadeoutinit()
        alpha = 0
        fade = True
        fademode = "fadeout"
    End Method
    Method drawmap:Void()
        For Local y1=0 Until mapheight
        For Local x1=0 Until mapwidth
            drawtile(map[x1][y1],x1*tilewidth,y1*tileheight)
        Next
        Next
        If fade = True Then
            SetAlpha alpha
            SetColor 0,0,0
            DrawRect 0,0,640,480
            SetAlpha 0
            If fademode = "fadein"
                alpha -= 0.02
                If alpha <= 0 Then fademode = "fadedone" ; fade=False
            End If
            If fademode = "fadeout"
                alpha += 0.02
                If alpha >= 1 Then fademode = "fadedone" ; fade = False
            End If
        End If
    End Method
    Method drawtile(val:Int,x1:Int,y1:Int)
        Select val
            Case 0'water
                SetColor 0,0,255
                DrawRect x1,y1,tilewidth,tileheight
            Case 1'land
                SetColor 0,200,0
                DrawRect x1,y1,tilewidth,tileheight
            Case 2'forrest
                drawtile(1,x1,y1)
                SetColor 0,255,0
                DrawOval x1+5,y1+5,tilewidth-10,tileheight/2
                SetColor 150,10,0
                DrawRect x1+12,y1+tileheight-10,tilewidth-24,tileheight/2-5
            Case 3'hill
                drawtile(1,x1,y1)
                SetColor 0,255,0
                DrawOval x1+5,y1+10,tilewidth-10,tileheight-15
                SetColor 0,200,0
                DrawRect x1,y1+tileheight/1.5,tilewidth,10
            Case 4'mountain
                drawtile(1,x1,y1)
                SetColor 200,200,200
                DrawPoly(    [Float(x1+tilewidth/2),Float(y1),
                            Float(x1+tilewidth-5),Float(y1+tileheight-5),
                            Float(x1+5),Float(y1+tileheight-5)])
        End Select
    End Method

End Class

Global mymap:map = New map(20,14,32,32)
Global fadetp:Int=0

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
        mymap.fadeininit
    End Method
    Method OnUpdate()
        If mymap.fademode = "fadedone" And fadetp = 0
            fadetp = 1
            mymap.fadeoutinit
        End If
        If mymap.fademode = "fadedone" And fadetp = 1
            fadetp = 0
            mymap.fadeininit
        End If
    End Method
    Method OnRender()
        Cls 0,0,0
        mymap.drawmap
        SetAlpha 1 
           SetColor 255,255,255
           DrawText "Screenfade example : "+mymap.fademode,0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Wednesday, February 25, 2015

Monkey-X - 3 dimensional arrays and Length - code example


Here a example of how to create and use 3 dimensional arrays in Monkey. Also it shows how to use the Length command with these.

Code below :

Import mojo

Global mapwidth:Int=3
Global mapheight:Int=3
Global mapdepth:Int=3

Global map:Int[mapwidth][][]

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
        For Local i = 0 Until mapwidth
            map[i] = New Int[mapheight][]
            For Local z=0 Until mapdepth
                map[i][z] = New Int[mapdepth]
            Next
        Next
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            map[x][y][0] = Int(Rnd(3))
            For Local z=1 Until mapdepth
                map[x][y][z] = Rnd(3,10)
            Next
        Next
        Next
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "3 Dimensional arrays and Length example",0,0
        For Local y=0 Until map[0].Length
        For Local x=0 Until map.Length
        For Local z=0 Until map[0][0].Length
            Local s:String="x:"+x+" y:"+y+" z:"+z+" = "
            DrawText s+""+map[x][y][z],x*132,y*64+(z*15)+32
        Next
        Next
        Next
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Scrolling platformer with vines big level - code example.


Here a version of the vine platformer with a bigger map. Explore!

Code below :

Import mojo

Global map:Int[][] = [      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,0,0,0,0,0,0,0,2,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,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,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,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,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,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,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,2,2,2,2,2,2,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,1,1,1,1,1,0,2,2,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,2,2,2,2,2,2,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,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,0,0,0,0,2,2,2,2,2,2,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,2,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,2,2,2,2,2,2,2,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,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,2,2,2,2,2,2,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,2,2,2,2,2,2,2,0,0,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,2,2,2,2,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,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,0,0,0,0,2,2,2,2,2,2,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,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,1,1,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,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,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,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,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,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,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,0,2,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,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,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,2,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,0,2,1,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,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,0,0,0,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,1,1,0,0,0,2,1,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,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,0,0,0,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,0,2,1,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,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,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,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,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,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,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,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,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,2,0,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,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,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,0,0,0,0,2,0,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,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,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,2,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,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,0,1,1,0,0,0,0,0,0,0,0,0,0,0,2,0,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,2,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,2,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,2,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,0,1,1,0,0,0,0,0,0,0,0,0,0,0,2,0,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,2,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,2,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ]


Const mapwidth:Int=150
Const mapheight:Int=30
Const tilewidth:Int=32
Const tileheight:Int=32
Global mapx:Int=0
Global mapy:Int=0
Global mapsx:Int=0
Global mapsy:Int=0

Class player    
    Field x:Float=32*3
    Field y:Float=32*6
    Field w:Int=32
    Field h:Int=32
    Field incy:Float=0
    Field isjumping:Bool = False
    Field facing:Int '0 = left , 1 = right
    Field jumpofvine:Bool=False
    Field jumpofvinetimeout:Int
    Method update()
        If pvc(0,0) = False Or jumpofvine = True Then regularmode
        If pvc(0,0) = True 
            If jumpofvine = False
                vinemode
            End If
        End If
    End Method
    Method vinemode()
        isjumping = False
        incy=0
        If KeyDown(KEY_SPACE)
            jumpofvine = True
            jumpofvinetimeout = Millisecs() + 1000
            isjumping = True
            incy=-4
        End If
        If KeyDown(KEY_UP)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(0,-1) = False
                    y-=1
                End If
            Next
        End If
        If KeyDown(KEY_DOWN)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(0,1) = False
                    y+=1
                End If
            Next
        End If
        If KeyDown(KEY_LEFT)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(-1,0) = False
                    x-=1
                    facing=0
                End If
            Next
        End If
        If KeyDown(KEY_RIGHT)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(1,0) = False
                    x+=1
                    facing = 1
                End If
            Next
        End If
    End Method
    Method regularmode()        
        If jumpofvine = True
            If Millisecs() > jumpofvinetimeout Then jumpofvine=False
        End If
        'Left and Right movement
        If KeyDown(KEY_RIGHT)
            For Local i=0 Until 4 ' move with 4 pixels at a time
                If ptc(1,0) = False
                    x+=1
                    facing = 1
                End If
            Next
        End If
        If KeyDown(KEY_LEFT)
            For Local i=0 Until 4
                If ptc(-1,0) = False
                    x-=1
                    facing = 0
                End If
            Next
        End If
        'player gravity part
        'if in the air and not in jump
        If isjumping = False
            If ptc(0,1) = False
                isjumping=True
                incy=0
            End If
        End If
        ' jump
        If KeyDown(KEY_SPACE)
            If isjumping = False
                isjumping = True
                incy=-4
            End If
        End If
        ' if we are in a jump/falling down
        If isjumping=True
            If incy>=0 'if we are going down
                If incy<4 Then incy+=.1
                For Local i=0 Until(incy)
                    If ptc(0,1) = False
                        y+=1
                    Else
                        isjumping = False
                    End If
                Next
            End If
            If incy<0 'if we are going up
                incy+=.1
                For Local i=0 Until Abs(incy)
                    If ptc(0,-1) = False
                        y-=1
                    Else
                        incy=0
                    End If
                Next
            End If
        End If    
    End Method
    Method draw()
        SetColor 255,255,0
        DrawRect x,y,w,h
    End Method
End Class

Global p:player = New player

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()    
        p.update    
        alignmap
    End Method
    Method OnRender()
        Cls 0,0,0 
        drawmap
        p.draw
        SetColor 0,0,0
        DrawRect 0,0,DeviceWidth(),32
        SetColor 255,255,255
        DrawText "Use Cursor left/right to move, space to jump",0,0
        DrawText "Use the green(vines) to climb around. ",0,16
    End Method
End Class

Function alignmap:Bool()
        For Local i=0 Until 4
        If p.x > DeviceWidth / 2
            If mapx+20 < mapwidth-1
                mapsx-=1
                If mapsx < 0 Then 
                    mapsx = 31
                    mapx += 1
                Endif
                p.x-=1
            End If
        End If
        Next

        For Local i=0 Until 4
        If p.x < DeviceWidth / 2
            If mapx > 0
                mapsx+=1
                If mapsx > 32 Then 
                    mapsx = 0
                    mapx -= 1
                Endif
                p.x+=1
            End If
        End If
        Next
        ' scrolling down
        For Local i=0 Until 16
        If p.y > DeviceHeight / 2
            If mapy+14 < mapheight-1
                mapsy-=1
                If mapsy < 0 Then 
                    mapsy = 31
                    mapy += 1
                Endif
                p.y-=1
            End If
        End If
        Next
        ' scrolling up
        For Local i=0 Until 16
        If p.y < DeviceHeight / 2
            If mapy > 0
                mapsy+=1
                If mapsy > 31 Then 
                    mapsy = 0
                    mapy -= 1
                Endif
                p.y+=1
            End If
        End If
        Next
End Function


'player collide with vines blocks true/false
Function pvc:Bool(offsetx:Int=0,offsety:Int=0)
    Local cx = (p.x+offsetx)/tilewidth+mapx
    Local cy = (p.y+offsety)/tileheight+mapy
    For Local y2=cy-1 Until cy+4
    For Local x2=cx-1 Until cx+4
        If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight
            If map[y2][x2] = 2
                Local x3 = (x2-mapx)*tilewidth-32+mapsx
                Local y3 = (y2-mapy)*tileheight+mapsy
                If rectsoverlap(p.x+offsetx,p.y+offsety,p.w,p.h,x3,y3,tilewidth,tileheight) = True
                    Return True
                End If
            End If
        End If
    Next
    Next
    Return False
End Function

'player collide with solid blocks true/false
Function ptc:Bool(offsetx:Int=0,offsety:Int=0)
    Local cx = (p.x+offsetx)/tilewidth+mapx
    Local cy = (p.y+offsety)/tileheight+mapy
    For Local y2=cy-1 Until cy+4
    For Local x2=cx-1 Until cx+4
        If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight
            If map[y2][x2] = 1 
                Local x3 = (x2-mapx)*tilewidth-32+mapsx
                Local y3 = (y2-mapy)*tileheight+mapsy
                If rectsoverlap(p.x+offsetx,p.y+offsety,p.w,p.h,x3,y3,tilewidth,tileheight) = True
                    Return True
                End If
            End If
        End If
    Next
    Next
    Return False
End Function


Function drawmap:Void()
    For Local y=0 To 14
    For Local x=0 To 20
        Local x1 = ((x*tilewidth)+mapsx)-tilewidth
        Local y1 = ((y*tileheight)+mapsy)
        Select map[y+mapy][x+mapx]
            Case 1'Wall
            SetColor 100,100,100
            DrawRect x1,y1,tilewidth,tileheight
            Case 2'spriny
            SetColor 0,100,0
            DrawRect x1,y1,tilewidth,tileheight
          End Select
     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

Function Main()
    New MyGame()
End Function

Tuesday, February 24, 2015

Monkey-X - Simple single screen map editor - code example


Here a example of a map editor for single screen maps. The theme is topdown.

Code below :

Import mojo

Class mapeditor
    Field tilewidth:Int,tileheight:Int
    Field mapwidth:Int,mapheight:Int
    Field map:Int[][],shoremap:String[][]
    Field ctile:Int=1 'current drawing tile
    Method New(mapwidth:Int,mapheight:Int,tilewidth:Int,tileheight:Int)
        Self.tilewidth = tilewidth
        Self.tileheight = tileheight
        Self.mapwidth = mapwidth
        Self.mapheight = mapheight
        map = New Int[mapwidth][]
        shoremap = New String[mapwidth][]
        For Local i = 0 Until mapwidth
            map[i] = New Int[mapheight]
            shoremap[i] = New String[mapheight]
        Next
    End Method
    Method update()
        Local x1 = MouseX() / tilewidth
        Local y1 = MouseY() / tileheight
        If MouseDown(MOUSE_LEFT)
            setmap(x1,y1,ctile)
            makeshoremap
        End If
        If KeyDown(KEY_0) Then ctile = 0
        If KeyDown(KEY_1) Then ctile = 1
        If KeyDown(KEY_2) Then ctile = 2
        If KeyDown(KEY_3) Then ctile = 3
        If KeyDown(KEY_4) Then ctile = 4                                
    End Method
    Method setmap:Void(x:Int,y:Int,val:Int)
        If x>=0 And y>=0 And x<mapwidth And y<mapheight
            map[x][y] = val
        End If
    End Method
    Method drawmap:Void()
        For Local y1=0 Until mapheight
        For Local x1=0 Until mapwidth
            drawtile(map[x1][y1],x1*tilewidth,y1*tileheight)
        Next
        Next
        drawshoremap
        SetColor 255,255,255
        Local mx:Int=MouseX()/tilewidth
        Local my:Int=MouseY()/tileheight
        Local x1:Int=mx*tilewidth
        Local y1:Int=my*tileheight
        drawboxedrect x1,y1,tilewidth,tileheight
        If KeyDown(KEY_SPACE)
            SetColor 0,0,0
            DrawRect 0,0,640,36
            Local y1:Int=1
            Local x1:Int=1            
            For Local i:Int=0 To 4
                If ctile = i
                    SetColor 255,255,0
                    DrawRect x1-1,y1-1,34,34                
                End If
                drawtile(i,x1,y1)
                SetColor 255,255,255
                Select i
                    Case 0;DrawText "0",x1,y1
                    Case 1;DrawText "1",x1,y1
                    Case 2;DrawText "2",x1,y1
                    Case 3;DrawText "3",x1,y1
                    Case 4;DrawText "4",x1,y1                                          
                End Select
                x1+=34
            Next
        End If
    End Method
    Method drawtile(val:Int,x1:Int,y1:Int)
        Select val
            Case 0'water
                SetColor 0,0,255
                DrawRect x1,y1,tilewidth,tileheight
            Case 1'land
                SetColor 0,200,0
                DrawRect x1,y1,tilewidth,tileheight
            Case 2'forrest
                drawtile(1,x1,y1)
                SetColor 0,255,0
                DrawOval x1+5,y1+5,tilewidth-10,tileheight/2
                SetColor 150,10,0
                DrawRect x1+12,y1+tileheight-10,tilewidth-24,tileheight/2-5
            Case 3'hill
                drawtile(1,x1,y1)
                SetColor 0,255,0
                DrawOval x1+5,y1+10,tilewidth-10,tileheight-15
                SetColor 0,200,0
                DrawRect x1,y1+tileheight/1.5,tilewidth,10
            Case 4'mountain
                drawtile(1,x1,y1)
                SetColor 200,200,200
                DrawPoly(    [Float(x1+tilewidth/2),Float(y1),
                            Float(x1+tilewidth-5),Float(y1+tileheight-5),
                            Float(x1+5),Float(y1+tileheight-5)])
        End Select
    End Method
    Method drawshoremap:Void()
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            Local s:String=shoremap[x][y]
            Local x1:Int=x*tilewidth
            Local y1:Int=y*tileheight
            ' tile 1,2,3,4 is sea
            SetColor 0,150,0
            If s[0..1] = "1" Then DrawRect x1+(tilewidth/4),y1-2,tilewidth/2,2

            If s[1..2] = "1" Then DrawRect x1+tilewidth,y1+tileheight/4,2,tileheight/2    

            If s[2..3] = "1" Then DrawRect x1+(tilewidth/4),y1+tileheight,tilewidth/2,2

                If s[3..4] = "1" Then DrawRect x1-2,y1+tileheight/4,2,tileheight/2
        Next
        Next
    End Method

    Method makeshoremap:Void()
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth        
            shoremap[x][y]="0000"                  
        Next
        Next
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth        
            If map[x][y] > 0 
                If y-1>=0
                    If map[x][y-1] = 0
                           Local sm:String=shoremap[x][y]                    
                        sm = "1"+sm[1..4]
                        shoremap[x][y] = sm
                    End If
                End If
                If x+1 < mapwidth
                    If map[x+1][y] = 0
                        Local sm:String=shoremap[x][y]                    
                        sm = sm[0..1]+"1"+sm[2..4]                     
                        shoremap[x][y] = sm
                    End If
                End If
                If y+1 < mapheight
                    If map[x][y+1] = 0
                        Local sm:String=shoremap[x][y]                    
                        sm = sm[0..2]+"1"+sm[3..4]                
                        shoremap[x][y] = sm
                    End If
                End If
                If x-1 >= 0
                    If map[x-1][y] = 0
                        Local sm:String=shoremap[x][y]                    
                        sm = sm[0..3]+"1"
                        shoremap[x][y] = sm
                    End If
                End If
                End If
           Next
        Next
    End Method

End Class

Global mymapeditor:mapeditor = New mapeditor(20,14,32,32)

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()      
        mymapeditor.update  
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymapeditor.drawmap
        SetColor 255,255,255
        DrawText "Spacebar = tileview, 0 to 4 = tiles, Lmb = place tile",320,480-15,0.5,0.5
        Local x:Int=640-32
        Local y:Int=480-10
        PushMatrix()
        Translate x,y
        Rotate(45)
        Scale 0.7,0.7
        Translate -x,-y                
        DrawText "Editor",x,y
        PopMatrix()
    End Method
End Class


Function Main()
    New MyGame()
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

Function drawboxedrect:Void(x:Int,y:Int,w:Int,h:Int)
    DrawLine x,y,x+w,y
    DrawLine x,y,x,y+h
    DrawLine x,y+h,x+w,y+h
    DrawLine x+w,y,x+w,y+h
End Function

Monkey-X - Different sized (scaled) text - code example


Here a example on how to scale/resize the text you draw using the command DrawText.

Code below :

Import mojo

Global screen:Image
Global firsttime:Bool=True

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
        screen = CreateImage(640,480)
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        ' to save the cpu/gpu we make the screen only once
        ' we draw it then every frame
        If firsttime
            Local screenarray:Int[640*480] ' store the screen in this array
            firsttime = False
            Cls 0,0,0 
            SetColor 255,255,255
            For Local i=0 Until 100
                Local scale:Float = Rnd(0.2,2) ' get a scale value
                Local x:Int=Rnd(640)
                Local y:Int=Rnd(480)
                'This is where the resizing happens
                PushMatrix()            
                Scale scale,scale
                DrawText "Test",x,y
                PopMatrix()
            Next
            ReadPixels(screenarray, 0, 0, 640, 480)
            screen.WritePixels(screenarray,0,0,640,480)
            Cls
        End If
        Cls 0,0,0
        SetColor 255,255,255
        DrawImage screen,0,0
        DrawText "Different sized Text.",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Platformer Shotgun shooting - code example


Here a short example on how you can do shotguns in platformer games. 

Code below :

Import mojo

Global px:Float=640/2,py:Float=480/2
Global pw:Int=32,ph:Int=32
Global sgdelay:Int
Global sgshotshow:Int

Class sgbullets
    Field x:Float,y:Float
    Field incx:Float,incy:Float
    Field timeout:Int=Millisecs()+1000
    Field delete:Bool=False
    Method New(x:Float,y:Float)
        Self.x = x
        Self.y = y
        incx = Rnd(3.5,4.5)
        incy = Rnd(-0.3,0.3)
        If Rnd(10) < 2 Then incy=Rnd(-1,1)
    End Method
    Method update()
        x+=incx
        y+=incy
        If Millisecs() > timeout Then delete = True
        For Local i:=Eachin sgbullet
            If i.delete = True Then sgbullet.Remove i
        Next
    End Method
    Method draw()
        SetColor 200,200,200
        DrawOval x,y,3,3
    End Method
End Class

Global sgbullet:List<sgbullets> = New List<sgbullets>

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        If KeyDown(KEY_SPACE) And Millisecs() > sgdelay Or (Rnd(10)<2 And Millisecs() > sgdelay)
            sgdelay = Millisecs() + 700
            sgshotshow = Millisecs() + 500
            For Local i=0 Until 5
                sgbullet.AddLast(New sgbullets(px+32,py+10))
            Next
        End If
        For Local i:=Eachin sgbullet
            i.update
        Next        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Platformer Shotgun shooting example.",0,0
        DrawRect px,py,pw,ph
        SetColor 255,255,255
        If Millisecs() < sgshotshow
            PushMatrix()
            Translate px,py
            Rotate(45)
            Translate -px,-py
            DrawText "PANG",px+pw/3,py+ph
            PopMatrix()
        End If
        For Local i:=Eachin sgbullet
            i.draw
        Next
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - 2d Platformer Flame thrower - code example


Not the most realistic fire but it looks like a nice effect in a game.

Code below :

Import mojo

' player data
Global px:Int=640/2
Global py:Int=480/2
Global pw:Int=32
Global ph:Int=32
Global firestart:Bool=True
Global firetime:Int = Millisecs() + Rnd(100,200)

Class flames
    Field x:Float,y:Float,incx:Float=5,incy:Float
    Field mody:Float=0
    Field timeout:Int=Millisecs()+600+Rnd(25)
    Field flamerisetime:Int = Rnd(100,200)
    Field spread:Float
    Field delete:Bool=False
    Field radius:Float=2,col:Float=255
    Method New(x:Float,y:Float)
        Self.x = x
        Self.y = y+Rnd(-3,3)
        Self.incy = Rnd(-0.3,0.1)
    End Method
    Method update()    
        ' increase the size of the flame
        If radius<8 Then radius+=Rnd(0.4,0.7)
        ' decrease red color
        col-=3
        '         
        x+=incx
        y+=incy        
        ' increase the spread
        spread+=0.02
        incy += Rnd(-spread,spread)
        ' if the flame is near the end        
        If Millisecs() > (timeout-flamerisetime)            
            If mody>0 Then mody=0
            incx-=Rnd(0.2,0.9)
            mody -= Rnd(0.3)
            incy += mody
        End If
        
        ' if burned out then delete the flame
        If Millisecs() > timeout Then delete = True
        For Local i:=Eachin flame
            If i.delete = True Then flame.Remove i
        Next
    End Method
    Method draw()
        SetColor col,40,10
        DrawOval x,y,radius,radius
    End Method
End Class

Global flame:List<flames> = New List<flames>

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
        If firestart = False And Millisecs() > firetime
            firestart = True
            firetime = Millisecs() + Rnd(500,2000)
        End If
        If KeyDown(KEY_SPACE) Or firestart = True
            If Millisecs() > firetime Then 
                firestart = False
                firetime = Millisecs()+Rnd(500,1000)
            End If
            flame.AddLast(New flames(px+32,py+10))                
        End If
        For Local i:=Eachin flame
            i.update
        Next
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawRect px,py,pw,ph 
        For Local i:=Eachin flame
            i.draw
        Next
        SetColor 255,255,255
        DrawText "Press space to fire flame thrower..",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Scrolling Platformer with climbing vines - code example


Here a example of a scrolling platformer with climeable tiles.

Code below :

Import mojo

Global map:Int[][] = [      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,1,1,1,1,1,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,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,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,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,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ]

Const mapwidth:Int=40
Const mapheight:Int=30
Const tilewidth:Int=32
Const tileheight:Int=32
Global mapx:Int=0
Global mapy:Int=0
Global mapsx:Int=0
Global mapsy:Int=0

Class player    
    Field x:Float=32*3
    Field y:Float=32*6
    Field w:Int=32
    Field h:Int=32
    Field incy:Float=0
    Field isjumping:Bool = False
    Field facing:Int '0 = left , 1 = right
    Field jumpofvine:Bool=False
    Field jumpofvinetimeout:Int
    Method update()
        If pvc(0,0) = False Or jumpofvine = True Then regularmode
        If pvc(0,0) = True 
            If jumpofvine = False
                vinemode
            End If
        End If
    End Method
    Method vinemode()
        isjumping = False
        incy=0
        If KeyDown(KEY_SPACE)
            jumpofvine = True
            jumpofvinetimeout = Millisecs() + 1000
            isjumping = True
            incy=-4
        End If
        If KeyDown(KEY_UP)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(0,-1) = False
                    y-=1
                End If
            Next
        End If
        If KeyDown(KEY_DOWN)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(0,1) = False
                    y+=1
                End If
            Next
        End If
        If KeyDown(KEY_LEFT)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(-1,0) = False
                    x-=1
                    facing=0
                End If
            Next
        End If
        If KeyDown(KEY_RIGHT)
            For Local i=0 Until 4
                If pvc(0,0) = True And ptc(1,0) = False
                    x+=1
                    facing = 1
                End If
            Next
        End If
    End Method
    Method regularmode()        
        If jumpofvine = True
            If Millisecs() > jumpofvinetimeout Then jumpofvine=False
        End If
        'Left and Right movement
        If KeyDown(KEY_RIGHT)
            For Local i=0 Until 4 ' move with 4 pixels at a time
                If ptc(1,0) = False
                    x+=1
                    facing = 1
                End If
            Next
        End If
        If KeyDown(KEY_LEFT)
            For Local i=0 Until 4
                If ptc(-1,0) = False
                    x-=1
                    facing = 0
                End If
            Next
        End If
        'player gravity part
        'if in the air and not in jump
        If isjumping = False
            If ptc(0,1) = False
                isjumping=True
                incy=0
            End If
        End If
        ' jump
        If KeyDown(KEY_SPACE)
            If isjumping = False
                isjumping = True
                incy=-4
            End If
        End If
        ' if we are in a jump/falling down
        If isjumping=True
            If incy>=0 'if we are going down
                If incy<4 Then incy+=.1
                For Local i=0 Until(incy)
                    If ptc(0,1) = False
                        y+=1
                    Else
                        isjumping = False
                    End If
                Next
            End If
            If incy<0 'if we are going up
                incy+=.1
                For Local i=0 Until Abs(incy)
                    If ptc(0,-1) = False
                        y-=1
                    Else
                        incy=0
                    End If
                Next
            End If
        End If    
    End Method
    Method draw()
        SetColor 255,255,0
        DrawRect x,y,w,h
    End Method
End Class

Global p:player = New player

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()    
        p.update    
        alignmap
    End Method
    Method OnRender()
        Cls 0,0,0 
        drawmap
        p.draw
        SetColor 0,0,0
        DrawRect 0,0,DeviceWidth(),32
        SetColor 255,255,255
        DrawText "Use Cursor left/right to move, space to jump",0,0
        DrawText "Use the green(vines) to climb around. ",0,16
    End Method
End Class

Function alignmap:Bool()
        For Local i=0 Until 4
        If p.x > DeviceWidth / 2
            If mapx+20 < mapwidth-1
                mapsx-=1
                If mapsx < 0 Then 
                    mapsx = 31
                    mapx += 1
                Endif
                p.x-=1
            End If
        End If
        Next

        For Local i=0 Until 4
        If p.x < DeviceWidth / 2
            If mapx > 0
                mapsx+=1
                If mapsx > 32 Then 
                    mapsx = 0
                    mapx -= 1
                Endif
                p.x+=1
            End If
        End If
        Next
        ' scrolling down
        For Local i=0 Until 16
        If p.y > DeviceHeight / 2
            If mapy+14 < mapheight-1
                mapsy-=1
                If mapsy < 0 Then 
                    mapsy = 31
                    mapy += 1
                Endif
                p.y-=1
            End If
        End If
        Next
        ' scrolling up
        For Local i=0 Until 16
        If p.y < DeviceHeight / 2
            If mapy > 0
                mapsy+=1
                If mapsy > 31 Then 
                    mapsy = 0
                    mapy -= 1
                Endif
                p.y+=1
            End If
        End If
        Next
End Function


'player collide with vines blocks true/false
Function pvc:Bool(offsetx:Int=0,offsety:Int=0)
    Local cx = (p.x+offsetx)/tilewidth+mapx
    Local cy = (p.y+offsety)/tileheight+mapy
    For Local y2=cy-1 Until cy+4
    For Local x2=cx-1 Until cx+4
        If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight
            If map[y2][x2] = 2
                Local x3 = (x2-mapx)*tilewidth-32+mapsx
                Local y3 = (y2-mapy)*tileheight+mapsy
                If rectsoverlap(p.x+offsetx,p.y+offsety,p.w,p.h,x3,y3,tilewidth,tileheight) = True
                    Return True
                End If
            End If
        End If
    Next
    Next
    Return False
End Function

'player collide with solid blocks true/false
Function ptc:Bool(offsetx:Int=0,offsety:Int=0)
    Local cx = (p.x+offsetx)/tilewidth+mapx
    Local cy = (p.y+offsety)/tileheight+mapy
    For Local y2=cy-1 Until cy+4
    For Local x2=cx-1 Until cx+4
        If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight
            If map[y2][x2] = 1 
                Local x3 = (x2-mapx)*tilewidth-32+mapsx
                Local y3 = (y2-mapy)*tileheight+mapsy
                If rectsoverlap(p.x+offsetx,p.y+offsety,p.w,p.h,x3,y3,tilewidth,tileheight) = True
                    Return True
                End If
            End If
        End If
    Next
    Next
    Return False
End Function


Function drawmap:Void()
    For Local y=0 To 14
    For Local x=0 To 20
        Local x1 = ((x*tilewidth)+mapsx)-tilewidth
        Local y1 = ((y*tileheight)+mapsy)
        Select map[y+mapy][x+mapx]
            Case 1'Wall
            SetColor 100,100,100
            DrawRect x1,y1,tilewidth,tileheight
            Case 2'spriny
            SetColor 0,100,0
            DrawRect x1,y1,tilewidth,tileheight
          End Select
     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

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Chaining and Classes and Self - code example


Here a example of how to chain commands in Monkey. This by returning Self.

Code below :

Import mojo

Class test
    Field x:Int,y:Int
    Method incx:test(val:Int)
        x+=val
        If x>1000 Then x=0
        Return Self
    End Method
    Method incy:test(val:Int)
        y+=val
        If y>1000 Then y=0
        Return Self
    End Method
    Method drawvalue()
        DrawText "x:"+x+" y:"+y,0,15
    End Method
End Class

Global t:test = New test

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        t.incx(1).incy(1)
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Chaining example.",0,0
        t.drawvalue
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Rotating platforms and player - code example


Here a example of how you can have rotating platforms in platformer games. The alignment of the player on a rotating platform is not quite fixed yet but maybe I will find the fix.

Code below :

Import mojo

Const tilewidth = 32
Const tileheight = 32
Const mapwidth:Int=20
Const mapheight:Int=10
Global map:Int[][] = [      [1,1,1,1,1,1,1,1,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,1],
                            [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
                            [1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
                            [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
                            [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
                            [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
                            [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
                            [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ]

Class players
    Field x:Float = 640/2-16
    Field y:Float = 480/2
    Field pw:Int=32
    Field ph:Int=32
    Field incy:Float
    Field jump:Bool=False
    Method New()
    End Method
    Method update()
        playermovement
        playergravity
    End Method
    Method playergravity()
        ' If the player is on the ground and the space bar is pressed
        If jump = False And playertc(0,1) = False And colrp(0,1,False) = False
            jump = True
            incy = 0
            For Local i:=Eachin rotplat
                i.lockplayer=False
            Next            
        End If
        If jump = False And KeyDown(KEY_SPACE) = True
            incy = -4
            jump = True
            For Local i:=Eachin rotplat
                i.lockplayer=False
            Next
        End
        'If the player is in the jump
        If jump = True
            incy += 0.1
            'if the player is going up
            If incy <=0
                For Local i:Int = 0 Until Abs(incy)                
                    y -= 1
                    If playertc(0,-1) = True
                        incy = 0
                        Exit
                    End If
                End
            End
            ' if the player if going down
            If incy > 0
                For Local i:Int = 0 Until incy
                    y += 1
                    'if the player touches the ground
                    If playertc(0,1) = True
                        jump = False                        
                        Exit
                    End
                    'if the player lands on a rotating platform
                    If colrp(0,1,True) = True
                        jump = False
                        Exit
                    End If
                End
            End
        End
    End Method
    Method playermovement()
       If KeyDown(KEY_RIGHT)
           For Local i=0 Until 2
            If playertc(1,0) = False
                   x+=1
            End If
           Next
       End If
       If KeyDown(KEY_LEFT)
           For Local i=0 Until 2    
               If playertc(-1,0) = False
                   x-=1
               End If
           Next
       End If
       'if locked to rotating platform then modify position
       For Local i:=Eachin rotplat
               If i.lockplayer = True 
                   y=i.py-ph
                   x+=i.px-i.lx
               End If
       Next        
    End Method
    Method playertc:Bool(x1:Int,y1:Int)
        Local cx = (x + x1) / tilewidth
           Local cy = (y + y1) / tileheight
        For Local y2=cy-1 Until cy+2
        For Local x2=cx-1 Until cx+2
            If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight
                If map[y2][x2] > 0
                    If rectsoverlap(x+x1,y+y1,pw,ph,x2*tilewidth,
                                    y2*tileheight,tilewidth,tileheight) = True
                        Return True
                    End If
                End If
            End If
        Next
        Next
        Return False
    End Method
    Method colrp:Bool(x1:Int,y1:Int,set:Bool=False) 'player colide with rotating platforms
        For Local i:=Eachin rotplat
            If rectsoverlap(x+x1,y+y1+ph,pw,1,i.px,i.py,i.pw,1) = True Then
                If set=True Then i.lockplayer = True
                Return True
            End If
        Next
        Return False
    End Method
    Method draw()
        ' draw the player
        SetColor 255,255,0        
        DrawOval x,y,pw,ph        
    End Method
End Class

Class rotatingplatforms
    Field x:Float,y:Float,angle:Int
    Field px:Float,py:Float,pw:Int=32,ph:Int=12
    Field lx:Float
    Field lockplayer:Bool=False
    Method New(x:Float,y:Float,angle:Int)
        Self.x = x
        Self.y = y
        Self.angle = angle
    End Method
    Method update()
        angle+=1
        If angle>360 Then angle=angle-360
        If angle<0 Then angle=angle+360
        lx = px
        px = x+(Cos(angle)*64)
        py = y+(Sin(angle)*64)
    End Method
    Method draw()        
        SetColor 255,255,255
        DrawRect px,py,pw,ph
    End Method    
End Class

Global player:List<players> = New List<players>
Global rotplat:List<rotatingplatforms> = New List<rotatingplatforms>

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
        player.AddLast(New players())
        rotplat.AddLast(New rotatingplatforms(10*tilewidth,5*tileheight,0))
        rotplat.AddLast(New rotatingplatforms(10*tilewidth,5*tileheight,(360/3)*1))
        rotplat.AddLast(New rotatingplatforms(10*tilewidth,5*tileheight,(360/3)*2))                
    End
    Method OnUpdate()
        ' Player left and right movement
        For Local i:=Eachin player
            i.update
        Next
        For Local i:=Eachin rotplat
            i.update
        Next
    End
    Method OnRender()
        Cls(0,0,0)
        SetColor(255,255,255)
        ' draw the map
        For Local y:Int = 0 Until mapheight
        For Local x:Int = 0 Until mapwidth
            If map[y][x] = 1 Then DrawRect(x*tilewidth,y*tileheight,tilewidth,tileheight)
        End
        End
        DrawText "Platformer Example",10,10
        DrawText "Use cursor left/right and space bar",160,10
        For Local i:=Eachin rotplat    
            i.draw
        Next
        For Local i:=Eachin player
            i.draw
        Next
    End
End



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

Monkey-X - 2d platformer Machine gun - code example


Here a small example with a machine gun and a effect.

Code below :

Import mojo

' player data
Global px:Int=640/2
Global py:Int=480/2
Global pw:Int=32
Global ph:Int=32
Global firedelay:Int

Class bulleteffects
    Field x:Float,y:Float
    Field incx:Float,incy:Float
    Field color:Int=255
    Field timeout:Int=Millisecs()+350+Rnd(250)
    Field colordecrease:Float=0
    Field delete:Bool
    Method New(x:Float,y:Float)
        Self.x = x
        Self.y = y
        incx = Rnd(-0.6,1)
        incy = Rnd(-2,0)
    End Method
    Method update()
        colordecrease+=5
        x+=incx
        For Local i = 0 Until Abs(incy)
            If incy<0 Then y-=1 Else y+=1
            If y>py+ph Then incy=-incy ; Exit
        Next
        incy+=0.1        
        If Millisecs() > timeout Then delete = True
        For Local i:=Eachin bulleteffect
            If i.delete = True Then bulleteffect.Remove i 
        Next
    End Method
    Method draw()
        Local c:Int = color-colordecrease
        If c<0 Then c=0
        SetColor c,c,0
        DrawRect x,y,2,2
    End Method
End Class

Class bullets
    Field x:Float,y:Float,incx:Float=5,incy:Float
    Field timeout:Int=Millisecs()+3000
    Field delete:Bool=False
    Method New(x:Float,y:Float)
        Self.x = x
        Self.y = y
        incy = Rnd(-0.03,0.03)
    End Method
    Method update()
        x+=incx
        y+=incy
        If Millisecs() > timeout Then delete = True
        For Local i:=Eachin bullet
            If i.delete = True Then bullet.Remove i
        Next
    End Method
    Method draw()
        SetColor 255,40,10
        DrawOval x,y,3,3
    End Method
End Class

Global bulleteffect:List<bulleteffects> = New List<bulleteffects>
Global bullet:List<bullets> = New List<bullets>

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
        If KeyDown(KEY_SPACE)
            If Millisecs() > firedelay
                bulleteffect.AddLast(New bulleteffects(px+32,py+10))
                bullet.AddLast(New bullets(px+32,py+10))
                firedelay = Millisecs() + 50
            End If
        End If
        For Local i:=Eachin bulleteffect
            i.update
        Next
        For Local i:=Eachin bullet
            i.update
        Next
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawRect px,py,pw,ph 
        For Local i:=Eachin bulleteffect
            i.draw
        Next
        For Local i:=Eachin bullet
            i.draw
        Next
        SetColor 255,255,255
        DrawText "Press space to fire machine gun..",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Putting/Calling functions in/from Classes - code example


This might be useful to keep code organised.

Code below :

Import mojo

Class myfuncs
    Function drawvalue(val:Int,x:Int,y:Int)
        DrawText "value is : " + val,x,y
    End Function
    Function drawdistance(x1:Int,y1:Int,x2:Int,y2:Int,x:Int,y:Int)
        Local d:Int=Abs(x2-x1)+Abs(y2-y1)
        DrawText "distance is : "+d,x,y
    End Function
End Class

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        myfuncs.drawvalue(10,0,15)
        myfuncs.drawdistance(0,0,10,10,0,30)
    End Method
End Class


Function Main()
    New MyGame()
End Function

The Flash Applets can crash sometimes!

Sometimes the Flash applets crash on me when I have multiple on one page. I have no idea what causes it. I have had no crashes yet when there was only 1 on a page.

Sunday, February 22, 2015

Monkey-X - TileMap inside a Class - code example


Here a short example of how to put the map part of your game in a Class. OO.

Code below :

Import mojo

Class map
    Field tilewidth:Int,tileheight:Int
    Field mapwidth:Int,mapheight:Int
    Field map:Int[][]
    Method New(mapwidth:Int,mapheight:Int,tilewidth:Int,tileheight:Int)
        Self.tilewidth = tilewidth
        Self.tileheight = tileheight
        Self.mapwidth = mapwidth
        Self.mapheight = mapheight
        map = New Int[mapwidth][]
        For Local i = 0 Until mapwidth
            map[i] = New Int[mapheight]
        Next
    End Method
    Method update()
        Local x1 = MouseX() / tilewidth
        Local y1 = MouseY() / tileheight
        If MouseDown(MOUSE_LEFT)
            setmap(x1,y1,1)
        End If
        If KeyDown(KEY_SPACE)
            setmap(x1,y1,0)            
        End If
    End Method
    Method setmap:Void(x:Int,y:Int,val:Int)
        If x>=0 And y>=0 And x<mapwidth And y<mapheight
            map[x][y] = val
        End If
    End Method
    Method drawmap:Void()
        For Local y1=0 Until mapheight
        For Local x1=0 Until mapwidth
            If map[x1][y1] = 1
                SetColor 255,255,255
                DrawRect (x1*tilewidth),(y1*tileheight),tilewidth,tileheight
            End If
        Next
        Next
    End Method
End Class

Global mymap:map = New map(20,14,32,32)

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()      
        mymap.update  
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymap.drawmap
        SetColor 255,255,255
        DrawText "Left mouse button to set block, Space bar to erase block",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Rectangle Class and Fields - code example


I am trying to learn more about Classes and what you can do with them. Here a rectangle class.

Code below :

' Thanks to Jesse on the Monkey forum for the example.

Import mojo

Class Rectangle
  Field x:Float
  Field y:Float
  Field width:Float
  Field height:Float
  
  Method New(x:Float,y:Float,width:Float,height:Float)
    Self.x = x
    Self.y = y
    Self.width = width
    Self.height = height
  End Method
  
  Method Update()
    x = MouseX()
    y = MouseY()
  End Method

  Method draw:Void()
    DrawRect x,y,width,height
  End Method
End Class

Class MyGame Extends App
    Field rect:Rectangle
    Method OnCreate()
        rect = New Rectangle(0,0,150,150)
        SetUpdateRate(60)
    End Method
    
    Method OnUpdate()
        rect.Update()
    End Method
    
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Move the rectangle with the mouse.",0,0
        rect.draw()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Saturday, February 21, 2015

Monkey-X - 2d Maps with shore tiles system - code example


Here a short example of how to create random 2d maps with shore tiles. The shore tiles are created in the code by seeing if a water tile is a neighboor of a tile.


Code below :

Import mojo

Const mapwidth:Int=640/16
Const mapheight:Int=480/16
Const tilewidth:Int=16
Const tileheight:Int=16
Global map:Int[mapwidth][]
Global islandmap:Int[mapwidth][]
Global shoarmap:String[mapwidth][]
Global numland:Int = 0
Global percland:Float = 1.7
Global remakecnt:Int=0
Global maptype:Int=2
Global debug:String=""
Class Openlist
    Field x:Int, y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(5)
        Seed = Millisecs()
        'Set up the map array to be multi dimensional
        For Local i=0 Until mapwidth
            map[i] = New Int[mapheight]
            islandmap[i] = New Int[mapheight]
            shoarmap[i] = New String[mapheight]
        Next
        ' make the map the first time
        makegamemap
        makeshoarmap
    End Method
    Method OnUpdate()
        ' how much land must it have numoflandtiles </mapsize/percland
        'debug = shoarmap[MouseX()/tilewidth][MouseY()/tileheight]
        '#rem
        remakecnt+=1
        If remakecnt > 20
            makegamemap()
            makeshoarmap
        End If
        '#end
    End Method
    Method OnRender()
        Cls 0,0,0 
        If remakecnt < 9
            drawmap
            drawshoarmap        
            SetColor 255,255,255
            DrawText debug,0,100
              Local numislands=getnumberislands()
                SetColor 10,10,10
                SetAlpha 0.6
            DrawRect 0,0,200,numislands*15+15
            SetAlpha 1
            SetColor 255,255,255
            DrawText "Different types of maps / 2 cont, 3 cont, islands.",0,0
            For Local y=1 To numislands
                DrawText "Landmass "+y+" is "+getlandmass(y)+" tiles.",0,y*15
            Next
        Else
            drawmap
            drawshoarmap
            SetColor 255,255,255
            If maptype < 4 Then DrawText "Please wait.... Generating "+maptype+" continents.",0,0
            If maptype = 4 Then DrawText "Please wait.... Generating islands..",0,0
        End If
        
    End Method
End Class

Function makegamemap:Void()
     Local exitloop:Bool=False
     While exitloop = False
        remakecnt=0
        percland = Rnd(2.0,3.5)
        makemap
        makeislandmap
        If maptype = 4 And createislandsmap() = True Then exitloop = True
        If maptype = 3 And create3landmasses() = True Then exitloop = True
        If maptype = 2 And create2landmasses() = True Then exitloop = True
    Wend
    maptype+=1
    If maptype > 4 Then maptype=2
End Function

Function makeislandmap:Void()
    'first clear the array
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        islandmap[x][y] = 0
    Next
    Next
    ' create an open list
    Local openlist:List<Openlist> = New List<Openlist>
    Local currentisland:Int=0
    ' loop through the array
    For Local y1=0 Until mapheight
    For Local x1=0 Until mapwidth
        ' if land tile and not indexed as island
        If map[x1][y1]>=5 And islandmap[x1][y1] = 0
            currentisland+=1
            openlist.Clear()
            'move this position onto the openlist
            openlist.AddLast(New Openlist(x1,y1))
            Local tx:Int=0, ty:Int=0            
            While openlist.IsEmpty() = False
                ' get a x,y value from the open list
                For Local i:=Eachin openlist
                    tx = i.x
                    ty = i.y
                    openlist.Remove i
                    Exit
                Next
                ' get 8 new positions
                For Local y2=-1 To 1
                For Local x2=-1 To 1
                    Local x3:Int=tx+x2
                    Local y3:Int=ty+y2
                    If x3>=0 And y3>=0 And x3<mapwidth And y3<mapheight
                    ' if land tile and not assisgned before a island
                    If map[x3][y3]>=5
                    If islandmap[x3][y3] = 0
                        ' add to open list
                        openlist.AddLast(New Openlist(x3,y3))
                        ' set current connected landmass
                        islandmap[x3][y3] = currentisland
                    End If
                    End If
                    End If
                Next
                Next
            Wend
        End If
    Next
    Next
End Function

Function drawmap:Void()
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        Local val:Int=map[x][y]
        ' tile 1,2,3,4 is sea
        If val<5 Then SetColor 0,0,val*10+100
        ' tile 5 6 7 8 is grasslands/trees
        If val>=5 And val <9 Then SetColor 0,val*15,0
        'tiles 9 10 11 12 13 is mountains
        If val>=9 Then SetColor val*15,val*4,0
        ' draw the tile
        DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight
    Next
    Next
End Function

Function drawshoarmap:Void()
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        Local s:String=shoarmap[x][y]
        Local x1:Int=x*tilewidth
        Local y1:Int=y*tileheight
        ' tile 1,2,3,4 is sea
        SetColor 0,150,0
        If s[0..1] = "1" Then DrawRect x1+(tilewidth/4),y1-2,tilewidth/2,2

        If s[1..2] = "1" Then DrawRect x1+tilewidth,y1+tileheight/4,2,tileheight/2    

        If s[2..3] = "1" Then DrawRect x1+(tilewidth/4),y1+tileheight,tilewidth/2,2

        If s[3..4] = "1" Then DrawRect x1-2,y1+tileheight/4,2,tileheight/2

    Next
    Next
End Function

Function makeshoarmap:Void()
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth        
        shoarmap[x][y]="0000"                  
    Next
    Next
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth        
        If islandmap[x][y] > 0 
            If y-1>=0
                If islandmap[x][y-1] = 0
                    Local sm:String=shoarmap[x][y]                    
                    sm = "1"+sm[1..4]
                    shoarmap[x][y] = sm
                End If
            End If
            If x+1 < mapwidth
                If islandmap[x+1][y] = 0
                    Local sm:String=shoarmap[x][y]                    
                    sm = sm[0..1]+"1"+sm[2..4]                     
                    shoarmap[x][y] = sm
                End If
            End If
            If y+1 < mapheight
                If islandmap[x][y+1] = 0
                    Local sm:String=shoarmap[x][y]                    
                    sm = sm[0..2]+"1"+sm[3..4]                
                    shoarmap[x][y] = sm
                End If
            End If
            If x-1 >= 0
                If islandmap[x-1][y] = 0
                    Local sm:String=shoarmap[x][y]                    
                    sm = sm[0..3]+"1"
                    shoarmap[x][y] = sm
                End If
            End If
        End If
    Next
    Next
End Function


Function makemap:Void()
    numland=0
    ' exit loop if conditions on land percentage is good
       While numland<(mapwidth*mapheight/percland)
        ' erase the old data
        For Local y=0 Until mapheight
           For Local x=0 Until mapwidth
               map[x][y] = 0
        Next
        Next
        'lowest hold the highest tile value
        Local lowest = 0
        ' while land height is below 13
        While lowest < 13
            Local x1 = Rnd(mapwidth)
               Local y1 = Rnd(mapheight)
               ' create a radius for draw oval
            Local radius = Rnd(3,6)
            ' loop and create oval
            For Local y2=-radius To radius
            For Local x2=-radius To radius
                If ((x2*x2)+(y2*y2)) <= radius*radius+radius*0.8
                    Local x3 = x1+x2
                    Local y3 = y1+y2
                    If x3>=0 And y3>=0 And x3<mapwidth And y3<mapheight
                        ' add current position with added older tile value 
                        map[x3][y3]=map[x3][y3]+1
                        ' if current value is higher then lowest loop value
                        ' then store it in the loop exit variable
                        If map[x3][y3] > lowest Then lowest = map[x3][y3]
                    End If
                End If
            Next
            Next
        Wend
        'Count the number of land tiles
        numland=0
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            ' if the value is above 4 then add landtile counter
            If map[x][y] >= 5 Then numland+=1
        Next
        Next
    Wend
End Function

Function createislandsmap:Bool()
    Local nislands:Int=getnumberislands()
    Local c:Int=0
    If nislands<7 Then Return False
    For Local i=1 To nislands
        Local v:Int=getlandmass(i)
        If v>25 Then c+=1
    Next
    If c>5 Then Return True    
    Return False
End Function


Function create3landmasses:Bool()
    Local nislands:Int=getnumberislands()
    Local c:Int=0
    If nislands<>3 Then Return False
    For Local i=1 To nislands
        Local v:Int=getlandmass(i)
        If v>100 Then c+=1
    Next
    If c>2 Then Return True    
    Return False
End Function


Function create2landmasses:Bool()
    Local nislands:Int=getnumberislands()
    Local c:Int=0
    If nislands<>2 Then Return False
    For Local i=1 To nislands
        Local v:Int=getlandmass(i)
        If v>200 Then c+=1
    Next
    If c>1 Then Return True    
    Return False
End Function

Function getlandmass:Int(islandnumber:Int=1)
    Local totaltiles:Int=0
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        If islandmap[x][y] = islandnumber Then totaltiles+=1
    Next
    Next
    Return totaltiles
End Function

Function getnumberislands:Int()
    Local highestnumber:Int=0
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        If islandmap[x][y] > highestnumber Then highestnumber = islandmap[x][y]
    Next
    Next
    Return highestnumber
End Function

Function Main()
    New MyGame()
End Function

Monkey-X - Balanced 2d maps - code example


I tried to make my map generation code make balanced maps. Here are 3 types of maps. 2 continents and 3 continents and islands. In strategy games you have not many fun options for creating the maps other then making them yourself using a editor. It takes a while sometimes to create the islands maps.

Code below :

Import mojo

Const mapwidth:Int=640/16
Const mapheight:Int=480/16
Const tilewidth:Int=16
Const tileheight:Int=16
Global map:Int[mapwidth][]
Global islandmap:Int[mapwidth][]
Global numland:Int = 0
Global percland:Float = 1.7
Global remakecnt:Int=0
Global maptype:Int=2
Class Openlist
    Field x:Int, y:Int
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
End Class

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(5)
        Seed = Millisecs()
        'Set up the map array to be multi dimensional
        For Local i=0 Until mapwidth
            map[i] = New Int[mapheight]
            islandmap[i] = New Int[mapheight]
        Next
        ' make the map the first time
        makegamemap
    End Method
    Method OnUpdate()
        ' how much land must it have numoflandtiles </mapsize/percland
        remakecnt+=1
        If remakecnt > 20
            makegamemap()
        End If
    End Method
    Method OnRender()
        Cls 0,0,0 
        If remakecnt < 9
            drawmap        
              Local numislands=getnumberislands()
                SetColor 10,10,10
                SetAlpha 0.6
            DrawRect 0,0,200,numislands*15+15
            SetAlpha 1
            SetColor 255,255,255
            DrawText "Different types of maps / 2 cont, 3 cont, islands.",0,0
            For Local y=1 To numislands
                DrawText "Landmass "+y+" is "+getlandmass(y)+" tiles.",0,y*15
            Next
        Else
            drawmap
            SetColor 255,255,255
            If maptype < 4 Then DrawText "Please wait.... Generating "+maptype+" continents.",0,0
            If maptype = 4 Then DrawText "Please wait.... Generating islands..",0,0
        End If
        
    End Method
End Class

Function makegamemap:Void()
     Local exitloop:Bool=False
     While exitloop = False
        remakecnt=0
        percland = Rnd(2.0,3.5)
        makemap
        makeislandmap
        If maptype = 4 And createislandsmap() = True Then exitloop = True
        If maptype = 3 And create3landmasses() = True Then exitloop = True
        If maptype = 2 And create2landmasses() = True Then exitloop = True
    Wend
    maptype+=1
    If maptype > 4 Then maptype=2
End Function

Function makeislandmap:Void()
    'first clear the array
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        islandmap[x][y] = 0
    Next
    Next
    ' create an open list
    Local openlist:List<Openlist> = New List<Openlist>
    Local currentisland:Int=0
    ' loop through the array
    For Local y1=0 Until mapheight
    For Local x1=0 Until mapwidth
        ' if land tile and not indexed as island
        If map[x1][y1]>=5 And islandmap[x1][y1] = 0
            currentisland+=1
            openlist.Clear()
            'move this position onto the openlist
            openlist.AddLast(New Openlist(x1,y1))
            Local tx:Int=0, ty:Int=0            
            While openlist.IsEmpty() = False
                ' get a x,y value from the open list
                For Local i:=Eachin openlist
                    tx = i.x
                    ty = i.y
                    openlist.Remove i
                    Exit
                Next
                ' get 8 new positions
                For Local y2=-1 To 1
                For Local x2=-1 To 1
                    Local x3:Int=tx+x2
                    Local y3:Int=ty+y2
                    If x3>=0 And y3>=0 And x3<mapwidth And y3<mapheight
                    ' if land tile and not assisgned before a island
                    If map[x3][y3]>=5
                    If islandmap[x3][y3] = 0
                        ' add to open list
                        openlist.AddLast(New Openlist(x3,y3))
                        ' set current connected landmass
                        islandmap[x3][y3] = currentisland
                    End If
                    End If
                    End If
                Next
                Next
            Wend
        End If
    Next
    Next
End Function

Function drawmap:Void()
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        Local val:Int=map[x][y]
        ' tile 1,2,3,4 is sea
        If val<5 Then SetColor 0,0,val*10+100
        ' tile 5 6 7 8 is grasslands/trees
        If val>=5 And val <9 Then SetColor 0,val*15,0
        'tiles 9 10 11 12 13 is mountains
        If val>=9 Then SetColor val*15,val*4,0
        ' draw the tile
        DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight
    Next
    Next
End Function

Function makemap:Void()
    numland=0
    ' exit loop if conditions on land percentage is good
       While numland<(mapwidth*mapheight/percland)
        ' erase the old data
        For Local y=0 Until mapheight
           For Local x=0 Until mapwidth
               map[x][y] = 0
        Next
        Next
        'lowest hold the highest tile value
        Local lowest = 0
        ' while land height is below 13
        While lowest < 13
            Local x1 = Rnd(mapwidth)
               Local y1 = Rnd(mapheight)
               ' create a radius for draw oval
            Local radius = Rnd(3,6)
            ' loop and create oval
            For Local y2=-radius To radius
            For Local x2=-radius To radius
                If ((x2*x2)+(y2*y2)) <= radius*radius+radius*0.8
                    Local x3 = x1+x2
                    Local y3 = y1+y2
                    If x3>=0 And y3>=0 And x3<mapwidth And y3<mapheight
                        ' add current position with added older tile value 
                        map[x3][y3]=map[x3][y3]+1
                        ' if current value is higher then lowest loop value
                        ' then store it in the loop exit variable
                        If map[x3][y3] > lowest Then lowest = map[x3][y3]
                    End If
                End If
            Next
            Next
        Wend
        'Count the number of land tiles
        numland=0
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            ' if the value is above 4 then add landtile counter
            If map[x][y] >= 5 Then numland+=1
        Next
        Next
    Wend
End Function

Function createislandsmap:Bool()
    Local nislands:Int=getnumberislands()
    Local c:Int=0
    If nislands<7 Then Return False
    For Local i=1 To nislands
        Local v:Int=getlandmass(i)
        If v>25 Then c+=1
    Next
    If c>5 Then Return True    
    Return False
End Function


Function create3landmasses:Bool()
    Local nislands:Int=getnumberislands()
    Local c:Int=0
    If nislands<>3 Then Return False
    For Local i=1 To nislands
        Local v:Int=getlandmass(i)
        If v>100 Then c+=1
    Next
    If c>2 Then Return True    
    Return False
End Function


Function create2landmasses:Bool()
    Local nislands:Int=getnumberislands()
    Local c:Int=0
    If nislands<>2 Then Return False
    For Local i=1 To nislands
        Local v:Int=getlandmass(i)
        If v>200 Then c+=1
    Next
    If c>1 Then Return True    
    Return False
End Function

Function getlandmass:Int(islandnumber:Int=1)
    Local totaltiles:Int=0
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        If islandmap[x][y] = islandnumber Then totaltiles+=1
    Next
    Next
    Return totaltiles
End Function

Function getnumberislands:Int()
    Local highestnumber:Int=0
    For Local y=0 Until mapheight
    For Local x=0 Until mapwidth
        If islandmap[x][y] > highestnumber Then highestnumber = islandmap[x][y]
    Next
    Next
    Return highestnumber
End Function

Function Main()
    New MyGame()
End Function