Sunday, December 25, 2016

Monkey-X - Hollyday Greetings Screen - code example

Import mojo

Global tr:Int=90
Global tg:Int=10
Global tb:Int=150

Class dot
    Field x:Float,y:Float
    Field rad:Int
    Field alpha:Float
    Field r:Int,g:Int,b:Int
    Method New()
        x = Rnd(640)
        y = Rnd(480)
        rad = Rnd(3,7)
        alpha = Rnd(0.4,0.8)
        Local c:Int=Rnd(50,255)
        If Rnd()<.8 Then 
            r = 255
            g = 255
            b = 255
            If Rnd()<.5
                rad=2
            End If
        else
                r = c/2+tr/2
                g = c/2+tg/2
                b = c/2+tb/2
        End If
    End Method
    Method draw()
        SetColor r,g,b
        SetAlpha alpha
        DrawCircle x,y,rad
    End Method
End Class

Class flake
    Field x:Float,y:Float
    Field angle:Float
    Field size:Float
    Field thick:Bool
    Field alpha:Float
    Method New(x:Float,y:Float,size:Int)
        Self.x = x
        Self.y = y
        Self.size = size
        alpha = Rnd(0.2,0.9)
        angle = Rnd(360)
        If Rnd()<.5 Then thick=True Else thick=False
    End Method
    Method draw()
        SetAlpha alpha
        PushMatrix()
        Translate(x,y)
        Rotate(angle)    
        Translate(-x,-y)
        SetColor 255,255,255
        For Local i=0 To 360-45 Step 45
            Local x1:Int=x+Cos(i)*size
            Local y1:Int=y+Sin(i)*size
            Local size2:Float=size/5+size/5
            For Local i2=0 Until 3
                Local x2:Int=x+Cos(i)*size2
                Local y2:Int=y+Sin(i)*size2
                Local size3:Int
                If i2 = 0 Then size3=size/4
                If i2 = 1 Then size3=size/3
                If i2 = 2 Then size3=size/5
                Local x3:Int=x2+Cos(i-40)*size3
                Local y3:Int=y2+Sin(i-40)*size3
                Local x4:Int=x2+Cos(i+40)*size3
                Local y4:Int=y2+Sin(i+40)*size3
                DrawLine x2,y2,x3,y3
                DrawLine x2,y2,x4,y4
                If thick = True
                    DrawLine x2+1,y2,x3+1,y3
                    DrawLine x2+1,y2,x4+1,y4
                End If
                size2+=size/5
            Next
            DrawLine x,y,x1,y1
            If thick = True Then
                DrawLine x+1,y,x1+1,y1            
            End If
        Next
        PopMatrix()
        SetAlpha 1
    End Method
    Method newang:Int(ang1:Int,m:Int)
        ang1 += m
        If ang1<0 Then Return 360+m
        If ang1>359 Then Return 0+m
    End Method
End Class

Global myflakes:List<flake> = New List<flake>
Global mydots:List<dot> = New List<dot>

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
        Seed = 3
        For Local i=0 Until 170
            mydots.AddLast(New dot())
        Next
        For Local y=0 Until 480+128 Step 128
        For Local x=0 Until 640+128 Step 128
            Local mx:Int=Rnd(-64,64)
            Local my:Int=Rnd(-64,64)
            myflakes.AddLast(New flake(x+mx,y+my,Rnd(32,64)))
        Next
        Next

    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls tr,tg,tb
        SetColor 255,255,255
        For Local i:=Eachin mydots
            i.draw
        Next
        For Local i:=Eachin myflakes
            i.draw
        Next
        Scale 4,4
        SetAlpha .76
        SetColor 255,255,255
        DrawText "Merry Christmas",DeviceWidth/(2*4),20,.5,.5
        DrawText "And a",DeviceWidth/(2*4),DeviceHeight/4/4,.5,.5
        DrawText "Happy new Year",DeviceWidth/(2*4),DeviceHeight/3/4,.5,.5        
        Scale 1,1
        SetAlpha 1
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Random Maze and Random Cave tiles - code example


Import mojo

Global sw:Int=640
Global sh:Int=480
Global mapwidth:Int=19
Global mapheight:Int=15
Global smooth1:Int=10
Global minsmooth1:Int=3
Global maxsmooth1:Int=30
Global smooth2:Int=20
Global minsmooth2:Int=3
Global maxsmooth2:Int=30
Global myseed:Int=300
Global tilewidth:Int=32
Global tileheight:Int=32
Global maxsize:Int=tilewidth/2
Global size:Int=tilewidth/2

Class map
    Field image:Image[][]
    Field imagepixels:Int[]
    Field imagemap:Int[][]
    Field map1:Int[][]
    Field map2:Int[][]
    Field map3:Int[][][]
    Field mazex:Stack<Int> = New Stack<Int>
    Field mazey:Stack<Int> = New Stack<Int>            
    Method New()
        imagemap = New Int[tilewidth][]
        For Local i=0 Until tilewidth
            imagemap[i] = New Int[tileheight]
        Next        
        map1 = New Int[mapwidth][]
        For Local i=0 Until mapwidth
            map1[i] = New Int[mapheight]
        Next        
        
        map2 = New Int[mapwidth/2][]
        map3 = New Int[mapwidth/2][][]    
        For Local i=0 Until mapwidth/2
            map2[i] = New Int[mapheight/2]
            map3[i] = New Int[mapheight/2][]
            For Local z = 0 Until mapheight/2
                map3[i][z] = New Int[4]
            Next            
        Next
        image = New Image[mapwidth][]
        For Local i=0 Until mapwidth
            image[i] = New Image[mapheight]
        Next
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            image[x][y] = CreateImage(tilewidth,tileheight)
        Next
        Next
        imagepixels = New Int[tilewidth*tileheight]
        Seed = myseed
        makemaze()
        tilesonmap()
        'maketile()
        'map1[0][0]=1
        'finalizeimage(0,0)


    End Method
    Method tilesonmap()
        Local top:Bool=False
        Local right:Bool=False
        Local bottom:Bool=False
        Local left:Bool=False
        For Local y=1 Until mapheight-1
        For Local x=1 Until mapwidth-1
            If map1[x][y] = 1
            If map1[x][y-1] = 1 Then top=True Else top=False
            If map1[x+1][y] = 1 Then right=True Else right=False
            If map1[x][y+1] = 1 Then bottom=True Else bottom=False
            If map1[x-1][y] = 1 Then left=True Else left = False
            maketile(top,right,bottom,left)
            finalizeimage(x,y)
            End If
        Next
        Next

        For Local x=1 Until mapwidth-1
            top=False
            If map1[x][0] = 1
            If map1[x+1][0] = 1 Then right = True Else right=False
            If map1[x][1] = 1 Then bottom = True Else bottom=False
            If map1[x-1][0] = 1 Then left = True Else left=False
            maketile(top,right,bottom,left)
            finalizeimage(x,0)            
            End If
            bottom=False
            If map1[x][mapheight-1] = 1
            If map1[x][mapheight-2] = 1 Then top=True Else top=False
            If map1[x+1][mapheight-1] = 1 Then right=True Else right =False
            If map1[x-1][mapheight-1] = 1 Then left = True Else left=False
            maketile(top,right,bottom,left)
            finalizeimage(x,mapheight-1)            
            End If            
        Next


        For Local y=1 Until mapheight-1
            left=False
            If map1[0][0] = 1
            If map1[0][y-1] = 1 Then top = True Else top=False
            If map1[1][y] = 1 Then right=True Else right=False
            If map1[0][y+1] = 1 Then bottom=True Else bottom=False
            maketile(top,right,bottom,left)
            finalizeimage(0,y)            
            End If
            right=False
            If map1[mapwidth-1][y] = 1
            If map1[mapwidth-1][y-1] = 1 Then top=True Else top=False
            If map1[mapwidth-1][y+1] = 1 Then bottom = True Else bottom=False
            If map1[mapwidth-2][y] = 1 Then left=True Else left = False
            maketile(top,right,bottom,left)
            finalizeimage(mapwidth-1,y)            
            End If            
        Next

        
        If map1[mapwidth-1][mapheight-1] = 1
            bottom=False
            right=False
            If map1[mapwidth-2][mapheight-1] = 1 Then left=True Else left=False
            If map1[mapwidth-1][mapheight-2] = 1 Then top=True Else top=False
            maketile(top,right,bottom,left)
            finalizeimage(mapwidth-1,mapheight-1)            

        End If

    End Method
    Method maketile(top:Bool=False,right:Bool=False,bottom:Bool=False,left:Bool=False)
        For Local y=0 Until tileheight
        For Local x=0 Until tilewidth
            imagemap[x][y] = 0
        Next
        Next
        smooth1 = Rnd(minsmooth1,maxsmooth1)
        smooth2 = Rnd(minsmooth2,maxsmooth2)
        If Rnd()<.8 Then smooth1 = Rnd(minsmooth1,10)
        Local ang:Int=0
        Local x:Int=tilewidth/2
        Local y:Int=tileheight/2
        Local d:Int=size-1
        Local linex:Stack<Int> = New Stack<Int>
        Local liney:Stack<Int> = New Stack<Int>
        Local drawme:Stack<Bool> = New Stack<Bool>
        Local ex:Bool=False
        Local topset:Bool=False
        Local rightset:Bool=False
        Local bottomset:Bool=False
        Local leftset:Bool=False
        If right=True Then ang=17
        linex.Push(x+Cos(ang)*d)
        liney.Push(y+Sin(ang)*d)
        drawme.Push(True)
        While ang<(360-smooth2)
            ang+=smooth2
            If bottom=True And bottomset=False
            If (ang>70 And ang<120) Then 
                bottomset=True
                ang=90-20
                linex.Push(x+Cos(ang)*d)'
                 liney.Push(y+tileheight/2)
                 drawme.Push(True)
                ang=90+21
                   linex.Push(x+Cos(ang)*d)'
                 liney.Push(y+tileheight/2)
                 drawme.Push(False)
                ang+=smooth2
               End If
               End If
            If left=True And leftset=False
            If (ang>160-smooth2 And ang<200) Then 
                leftset=True
                ang=180-20
                linex.Push(x-tilewidth/2)'
                 liney.Push(y+Sin(ang)*d)
                 drawme.Push(True)                 
                ang=180+21
                linex.Push(x-tilewidth/2)'
                 liney.Push(y+Sin(ang)*d)
                 drawme.Push(False)                 
                ang+=smooth2
               End If
               End If
            If top=True And topset=False
            If (ang>250 And ang<290) Then 
                topset=True
                ang=270-20
                linex.Push(x+Cos(ang)*d)'
                 liney.Push(y-tileheight/2)
                 drawme.Push(True)
                ang=270+21
                linex.Push(x+Cos(ang)*d)'
                 liney.Push(y-tileheight/2)
                 drawme.Push(False)                 
                ang+=smooth2
               End If
               End If
            If right=True And rightset=False
            If (ang>340-smooth2) Then
                rightset=True
                ang=360-20
                linex.Push(x+tilewidth/2)'
                 liney.Push(y+Sin(ang)*d)
                 drawme.Push(True)
                ang=21
                linex.Push(x+tilewidth/2)'
                 liney.Push(y+Sin(ang)*d)
                 drawme.Push(False)                 
                ang+=smooth2
                ang=360
                ex=True
               End If
               End If
               If ex=False
            d = size-1
            Local d2:Int=d+Rnd(-d/smooth1,d/smooth1)
            If d2>maxsize Then d2=maxsize
            linex.Push(x+Cos(ang)*d2)
            liney.Push(y+Sin(ang)*d2)
               drawme.Push(True)            
            'linex.Push(x+Cos(ang)*d)'
            'liney.Push(y+Sin(ang)*d)
            End If
        Wend

        linex.Push(linex.Get(0))
        liney.Push(liney.Get(0))
        drawme.Push(True)        
        For Local i=1 Until linex.Length
            Local x1:Int=linex.Get(i-1)
            Local y1:Int=liney.Get(i-1)
            Local x2:Int=linex.Get(i)
            Local y2:Int=liney.Get(i)            
            If drawme.Get(i) = True Then
            'If drawme.Get(i) = True
            line x1,y1,x2,y2
            'End if
            End If
        Next
        '    
        floodimagemap(2) 'walkable tiles is no 2
    End Method
    Method floodimagemap(fillval:Int)
        Local fx:Stack<Int> = New Stack<Int>
        Local fy:Stack<Int> = New Stack<Int>
        Local mx:Int[] = [0,1,0,-1]
        Local my:Int[] = [-1,0,1,0]
        fx.Push(tilewidth/2)
        fy.Push(tileheight/2)
        While fx.Length > 0
            Local x1:Int=fx.Top
            Local y1:Int=fy.Top
            fx.Pop
            fy.Pop
            For Local i=0 Until 4
                Local x2:Int=x1+mx[i]
                Local y2:Int=y1+my[i]
                If x2>=0 And x2<tilewidth And y2>=0 And y2<tileheight
                If imagemap[x2][y2] = 0
                    imagemap[x2][y2] = fillval
                    fx.Insert(0,x2)
                    fy.Insert(0,y2)
                End If
                End If
            Next
        Wend
    End Method
    Method finalizeimage(tx:Int,ty:Int)
        For Local i=0 Until tilewidth*tileheight
            imagepixels[i] = 0
        Next
        Local cnt:Int=0
        For Local y=0 Until tileheight
        For Local x=0 Until tilewidth
        If imagemap[x][y] = 1
        imagepixels[cnt] = argb(255,255,255)
        End If
        If imagemap[x][y] = 2
        imagepixels[cnt] = argb(55,55,55)
        End If

        cnt+=1
        Next
        Next
        image[tx][ty].WritePixels(imagepixels, 0, 0, tilewidth, tileheight, 0)        
    End Method
    
    Method makemaze()
        Local ax:Int[] = [0,1,0,-1]
        Local ay:Int[] = [-1,0,1,0]
        mazex.Push(Rnd(mapwidth/2))
        mazey.Push(Rnd(mapheight/2))                                
        While mazex.IsEmpty = False            
            Local x:Int=mazex.Top
            Local y:Int=mazey.Top
            Local d:Int[] = New Int[4]
            Local deadend:Bool=True
            For Local i:=0 Until ax.Length
                Local x2:Int=x+ax[i]
                Local y2:Int=y+ay[i]
                If x2>=0 And x2<mapwidth/2 And y2>=0 And y2<mapheight/2
                    If map2[x2][y2] = 0 
                        d[i] = 1
                        deadend=False
                    End If
                End If
            Next
            
            If deadend = False                
                Local eloop:Bool=False
                While eloop = False
                    Local r:Int=Rnd(0,4)
                    If d[r] = 1 Then                        
                        eloop = True
                        Local nx:Int=x+ax[r]
                        Local ny:Int=y+ay[r]
                        map3[x][y][r] = 1                                                                        
                        mazex.Push(nx)
                        mazey.Push(ny)                        
                        map2[x][y] = 1
                        map2[nx][ny] = 1
                    End If
                Wend
            Else    ' if nothing happened than backtrace
                mazex.Pop()
                mazey.Pop()
            End If
        Wend
        ' convert the map into a tilemap
        For Local y:=0 Until mapheight/2
        For Local x:=0 Until mapwidth/2
            Local x2:Int=x*2
            Local y2:Int=y*2
            If map2[x][y] = 1 Then map1[x2+1][y2+1] = 1
            If map3[x][y][0] = 1 Then map1[x2+1][y2] = 1
            If map3[x][y][1] = 1 Then map1[x2+2][y2+1] = 1
            If map3[x][y][2] = 1 Then map1[x2+1][y2+2] = 1
            If map3[x][y][3] = 1 Then map1[x2][y2+1] = 1            
        Next
        Next                
    End Method    
    Method line:Void(x1:Int,y1:Int,x2:Int,y2:Int)
        Local dx:Int, dy:Int, sx:Int, sy:Int, e:Int
        dx = Abs(x2 - x1)
          sx = -1
          If x1 < x2 Then sx = 1      
          dy = Abs(y2 - y1)
          sy = -1
          If y1 < y2 Then sy = 1
          If dx < dy Then 
              e = dx / 2 
          Else 
              e = dy / 2          
          End If
          Local exitloop:Bool=False
          While exitloop = False
              If x1>=0 And x1<tilewidth And y1>=0 And y1<tileheight
            imagemap[x1][y1] = 1
            End If
            
            If x1 = x2 
                If y1 = y2
                    exitloop = True
                End If
            End If
            If dx > dy Then
                x1 += sx ; e -= dy 
                  If e < 0 Then e += dx ; y1 += sy
            Else
                y1 += sy ; e -= dx 
                If e < 0 Then e += dy ; x1 += sx
            Endif
          Wend
    End Method    
    Function argb:Int(r:Int, g:Int, b:Int ,alpha:Int=255)
        Return (alpha Shl 24) | (r Shl 16) | (g Shl 8) | b          
    End Function     
    Method draw()    
        SetColor 255,255,255
        For Local y=0 Until mapheight
        For Local x=0 Until mapwidth
            If map1[x][y] = 1
                DrawImage image[x][y],x*tilewidth,y*tileheight
            End If
        Next
        Next
    End Method
End Class

Global mymap:map

Class MyGame Extends App
    Field cnt:Int=0
    Method OnCreate()
        SetUpdateRate(60)
        myseed=1
        mymap = New map
    End Method
    Method OnUpdate()
        cnt+=1
        If MouseDown(MOUSE_LEFT) Or cnt>120
            cnt=0
            myseed = Millisecs()
            mymap = New map
        End If
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymap.draw
        SetColor 255,255,255
        DrawText "Press mouse to draw new map or wait",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Flood Fill (seed fill) and 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
            map[tx][ty] = fillval
            floodx.Push(tx)
            floody.Push(ty)
            floodv.Push(1)
            flood = True
            fillval+=1
            If fillval > 5 Then fillval = 0
        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 Not (map[x2][y2] = fillval) And Not (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
            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 to flood map..",0,0
    End Method

End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Cos and Sin fun 01 - code example


Import mojo

Global smooth1:Int=10
Global smooth2:Int=20
Global myseed:Int=300
Global size:Int=50

Class MyGame Extends App
    
    Method OnCreate()
        SetUpdateRate(30)
    End Method
    Method OnUpdate()
        If KeyDown(KEY_RIGHT) Then smooth1+=1
        If KeyDown(KEY_LEFT) Then smooth1-=1
        If smooth1 <1 Then smooth1 = 2
        If smooth1 >100 Then smooth1 = 100
        If KeyDown(KEY_UP) Then smooth2+=1
        If KeyDown(KEY_DOWN) Then smooth2-=1
        If smooth2 <1 Then smooth2 = 2
        If smooth2 >100 Then smooth2 = 100
        If KeyDown(KEY_EQUALS) Then myseed+=1
        If KeyDown(KEY_MINUS) Then myseed-=1
        If KeyDown(KEY_9) Then size-=1
        If KeyDown(KEY_0) Then size+=1
        If size<5 Then size = 5
        If size>200 Then size=200
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        '
        Local sx:Int
        Local sy:Int
        Local ex:Int
        Local ey:Int
        Local ang:Int=0
        Local x:Int=320
        Local y:Int=240
        Local d:Int=size
        Local x1:Int=x+Cos(ang)*d
        Local y1:Int=y+Sin(ang)*d
        sx=x1
        sy=y1
        Seed = myseed

        While ang<(360-smooth2)
            ang+=smooth2
            d = size
            Local x2:Int=x+Cos(ang)*d
            Local y2:Int=y+Sin(ang)*d
            Local d2:Int=d+Rnd(-d/smooth1,d/smooth1)
            Local x3:Int=x+Cos(ang-10)*d2
            Local y3:Int=y+Sin(ang-10)*d2
               DrawLine x1,y1,x3,y3
            DrawLine x3,y3,x2,y2
'            DrawLine x1,y1,x3,y3
            x1=x2
            y1=y2
        Wend
        DrawLine x1,y1,sx,sy
        '
        DrawText "Press Cursor Up and Cursor Down - Cursor Left and Cursor Down",0,0
        DrawText "Press + and -",0,20
        DrawText "Press 9 and 0",0,40
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Random Colored Textures - code example





Import mojo

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


Class texture

    Field mapimage:Image
    Field mappixels:Int[]
    Field map:Int[][]
    Field iw:Int=screenwidth
    Field ih:Int=screenheight

    Field sc:Int=1'Rnd(1,3)
    Method New()   
        mappixels = New Int[iw*ih]
        mapimage = CreateImage(iw,ih)
        map = New Int[iw][]
        For Local i = 0 Until iw
            map[i] = New Int[ih]
        Next

        render1()

    End Method
    Method render1()        
        'noisey layer
        noisylayer()
        If Rnd()<.5 Then cellularlayer()



        ' lines down
        If Rnd()<.5
        Local c:Int=Rnd(1,5)
        For Local i=0 Until c
        Local val:Int=Rnd(-60,60)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local y:Int=0
        Local v1:Int=Rnd(6,20)
        Local v2:Int=Rnd(2,v1)
        While y<ih
        For Local x=0 To iw
            For Local i=0 To v2
            decmappixel(x,y+i,val)
            Next
        Next
        y+=v1
        Wend
        Next
        End If
        ' line right
        If Rnd()<.5
        Local c:Int=Rnd(1,5)
        For Local i=0 Until c
        Local val:Int=Rnd(-60,60)
        If Rnd()<.5 Then val = Rnd(2,10)
        'For Local x=0 To iw Step 8
        Local v1:Int=Rnd(3,iw/20)
        Local v2:Int=Rnd(2,v1)
        Local x=0
        While x<iw
        For Local y=0 To ih 
            For Local i=0 To v2
            decmappixel(x+i,y,val)
            Next
        Next
        x+=v1
        Wend
        Next
        End If
        'lines right
        If Rnd()<.5
        Local c:Int=Rnd(1,5)
        For Local i=0 Until c
        Local val:Int=Rnd(-60,60)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local y:Int=0
        Local v1:Int=Rnd(3,ih/10)
        Local v2:Int=Rnd(2,v1)
        'For Local y=0 To ih Step 8
        While y<ih
        For Local x=0 To iw
            For Local i=0 To v2
            addmappixel(x,y+i,val)
            If Rnd()<.5 Then addmappixel(x+i,y,val)
            Next
        Next
        y+=v1
        Wend
        Next
        End If
        ' lines down
        If Rnd()<.5
        Local c:Int=Rnd(1,5)
        For Local i=0 Until c
        Local t:Int=Rnd(1,5)
        For Local i=0 Until t
        Local val:Int=Rnd(-60,60)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local v1:Int=Rnd(3,iw/5)
        Local v2:Int=v1/2
        Local x:Int=0
        While x<iw
        For Local y=0 To ih 
            For Local i=0 To v2
            addmappixel(x+i,y,val)
            If Rnd()<.5 Then addmappixel(x+i,y,val)
            Next
        Next
        x+=v1
        Wend
        Next
        Next
        End If
        'diagonal lines
        If Rnd()<.5
        Local c:Int=Rnd(1,5)
        For Local i=0 Until c
        Local val:Int=Rnd(-60,60)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local x:Int=0
        Local x1:Int=-iw
        Local v1:Int=Rnd(8,iw/5)
        Local v2:Int=Rnd(3,v1)
        While x1<iw 
        For Local y=0 To ih
            For Local i=0 To v2
                addmappixel(x1+(x+i),y,val)
                'If Rnd()<.5 Then addmappixel(x1+(x+i),y)
            Next
            x+=1
        Next
        x=0
        x1+=v1
        Wend
        Next
        End If

        'blocks
        If Rnd()<.5
            Local x1:Int=0
            Local y1:Int=0
            Local sw:Int=Rnd(15,iw/10)
            Local sh:Int=Rnd(15,ih/10)
            Local sx:Int=Rnd(sw,sw*2)
            Local sy:Int=Rnd(sh,sh*2)
            Local t:Int
            If Rnd()<.5 Then 
                t=Rnd(-80,-30)
                Else 
                t=Rnd(30,80)
            End if
            While y1<ih
                addr2(x1,y1,sw,sh,t)
                x1+=sx
                If x1>iw
                x1=0
                y1+=sy
                End If                
            Wend
        End If


        'triangle up
        If Rnd()<.2 Then addtriangleup
        
        'triangle down
        If Rnd()<.2 Then addtriangledown


        'triangle left
        If Rnd()<.2 Then addtriangleleft
        'triangle Right
        If Rnd()<.2 Then addtriangleright
        If Rnd()<.2 Then addoval()            
        If Rnd()<.5 Then addheightmap
        tintmap
        mapimage.WritePixels(mappixels, 0, 0, iw, ih, 0)
    End Method

    Method update()
        
    End Method

    Method cellularlayer()
        'cellular layer
        For Local y=0 Until ih
        For Local x=0 Until iw
            If Rnd()<.5 Then
                map[x][y] = 1
            Else            
                map[x][y] = 0
            End If
        Next
        Next
        For Local i=0  Until 2
        ' loop through the map
        For Local y=0 Until ih
        For Local x=0 Until iw
            'count the neigbouring 1's 
            Local cnt = 0
            For Local y1=-1 To 1
            For Local x1=-1 To 1
                Local x2=x+x1
                Local y2=y+y1
                If x2>=0 And y2>=0 And x2<iw And y2<ih
                    If map[x][y] = 1 Then cnt+=1
                End If
            Next
            Next
            ' if 3 walls and map is a wall then map x,y is not a wall anymore
            If cnt < 4                
                    map[x][y] = 0
            End If
            ' if more then 4 walls then map x,y is wall
            If cnt >= 5 Then map[x][y] = 1
        Next
        Next
        Next

        For Local x=0 Until iw
        For Local y=0 Until ih
            If map[x][y] = 1 Then 
            addr2(x,y,1,1,100)
            Else
            addr2(x,y,1,1,40)
            End If
        Next
        Next
    End Method


    Method noisylayer()    
        Local var1:Int=Rnd(3,130)
        Local var2:Int=Rnd(20,200)
        Local depth:Int=Rnd(1,25)
        For Local i=0 To iw*ih*depth
            Local x1:Int=Rnd(iw)
            Local y1:Int=Rnd(ih)
            Local cnt:Int=0
            For Local y2=-5 To 5
            For Local x2=-5 To 5
                Local x3:Int=x1+x2
                Local y3:Int=y1+y2
                If x3>=0 And x3<iw And y3>=0 And y3<ih
                If getred(getmappixel(x3,y3)) > var2 Then
                    'addmappixel(x3,y3)
                    cnt+=1    
                End If
                End If
            Next
            Next
            If cnt<var1
                addmappixel(x1,y1,Rnd(2,20))
            End If
            cnt=0
        Next
    End Method
    Method addtriangleup()
        Local val:Int=Rnd(-120,120)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local wa:Float=0
        Local wb:Float=iw 
        Local s:Float=Float(ih)/Float(iw)
        For Local y=0 To ih
        For Local x=wa To wb
            addmappixel(x,y,val)            
        Next
            wa+=s
            wb-=s    
        Next
    End Method


    Method addtriangledown()
        Local val:Int=Rnd(-120,120)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local wa:Float=0
        Local wb:Float=iw 
        Local s:Float=Float(ih)/Float(iw)
        For Local y=ih To 0 Step -1
        For Local x=wa To wb
            addmappixel(x,y,val)            
        Next
            wa+=s
            wb-=s    
        Next
    End Method

    Method addtriangleleft()    
        Local val:Int=Rnd(-120,120)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local ha:Float=0
        Local hb:Float=ih
        Local s:Float=((Float(iw)/Float(ih))/3.5)
        For Local x=iw To 0 Step -1
        For Local y=ha To hb
            addmappixel(x,y,val)            
        Next
            ha+=s
            hb-=s    
        Next
    End Method

    Method addoval()
        'oval
        Local val:Int=Rnd(-100,100)
        If Rnd()<.5 Then val=Rnd(-15,15)
        addo(iw/2,ih/2,ih/2,val)
    End Method

    Method addtriangleright()
        Local val:Int=Rnd(-120,120)
        If Rnd()<.5 Then val = Rnd(2,10)
        Local ha:Float=0
        Local hb:Float=ih
        Local s:Float=((Float(iw)/Float(ih))/3.5)
        For Local x=0 To iw
        For Local y=ha To hb
            addmappixel(x,y,val)            
        Next
            ha+=s
            hb-=s    
        Next
    End Method


    Method addheightmap()
        'heightmap
        Local mw:Int=Rnd(5,iw/10)
        Local mh:Int=Rnd(5,ih/10)
        Local cnt:Float=Rnd(1,4)
        For Local i:Int=0 To iw*ih*cnt
            Local x:Int=Rnd(-10,iw)
            Local y:Int=Rnd(-10,ih)
            Local w:Int=Rnd(3,mw)
            Local h:Int=Rnd(3,mh)
            Local val:Int
            If Rnd()<.5 Then val=-1 Else val=1
            addr(x,y,w,h,val)
        Next        
    End Method

    Method tintmap()
        'tint random
        Local r1:Int=Rnd(0,125)
        Local g1:Int=Rnd(0,125)
        Local b1:Int=Rnd(0,125)
        For Local y=0 Until ih
        For Local x=0 Until iw    
            Local r2:Int=getred(getmappixel(x,y))
            Local g2:Int=r2
            Local b2:Int=r2
            setmappixel(x,y,argb(r1+r2/2,g1+g2/2,b1+b2/2))
        Next
        Next
    End Method

    Method decmappixel(x:Int,y:Int,val:Int=10)
        Local pos:Int=(y*iw)+x
        If pos<0 Or pos>=iw*ih Then Return
        Local r:Int=getred(mappixels[pos])-val
        Local g:Int=getgreen(mappixels[pos])-val
        Local b:Int=getblue(mappixels[pos])-val        
        Local nr:Int=Clamp(r,0,255)
        Local ng:Int=Clamp(g,0,255)
        Local nb:Int=Clamp(b,0,255)         
        mappixels[pos] = argb(nr,ng,nb)
    End Method
    Method addmappixel(x:Int,y:Int,val:Int=10)
        Local pos:Int=(y*iw)+x
        If pos<0 Or pos >=iw*ih Then Return
        Local r:Int=getred(mappixels[pos])+val
        Local g:Int=getgreen(mappixels[pos])+val
        Local b:Int=getblue(mappixels[pos])+val        
        Local nr:Int=Clamp(r,0,255)
        Local ng:Int=Clamp(g,0,255)
        Local nb:Int=Clamp(b,0,255)                
        mappixels[pos] = argb(nr,ng,nb)
    End Method


    Method setmappixel:Int(x:Int,y:Int,col)
        Local pos:Int=(y*iw)+x
        If pos<0 Or pos>=iw*ih Then Return 0
        mappixels[pos] = col
    End Method

    Method getmappixel:Int(x:Int,y:Int)
        Local pos:Int=(y*iw)+x
        If pos<0 Or pos>=iw*ih Then Return 0
        Return mappixels[pos]
    End Method

    Method getpixel2:Int(x:Int,y:Int)
        Local pos:Int=(y*iw)+x
        If pos<0 Or pos>=iw*ih Then Return 0        
        Return mappixels[pos]
    End Method


    Method draw()
        DrawImage mapimage,0,0,0,sc,sc
        SetColor 0,0,0
        DrawRect iw-200,ih-200,200,200
        SetColor 255,255,255
        DrawImage mapimage,iw-200+1,ih-200+1,0,198.0/Float(iw),198.0/Float(ih)
        SetColor 0,0,0
        DrawRect iw-64,ih-64,64,64
        SetColor 255,255,255
        DrawImage mapimage,iw-64+1,ih-64+1,0,62.0/Float(iw),62.0/Float(ih)

    End Method
    Method addr2(x1,y1,w1,h1,val:Int)
        For Local y2=y1 Until y1+h1
        For Local x2=x1 Until x1+w1
            Local pc = y2*iw+x2
            If pc >= 0 And pc < iw*ih
                Local r1:Int=getred(mappixels[pc])+val
                Local g1:Int=getgreen(mappixels[pc])+val
                Local b1:Int=getblue(mappixels[pc])+val
                r1 = Clamp(r1,0,255)                                
                g1 = Clamp(g1,0,255)
                b1 = Clamp(b1,0,255)
                mappixels[pc] = argb(r1,g1,b1)
            End If
        Next
        Next    
       End Method

    Method addr(x1,y1,w1,h1,val:Int)
        For Local y2=y1 Until y1+h1
        For Local x2=x1 Until x1+w1
            Local pc = y2*iw+x2
            If pc >= 0 And pc < iw*ih
                Local r1:Int=getred(mappixels[pc])+val
                Local g1:Int=getgreen(mappixels[pc])+val
                Local b1:Int=getblue(mappixels[pc])+val
                r1 = Clamp(r1,0,255)                                
                g1 = Clamp(g1,0,255)
                b1 = Clamp(b1,0,255)
                If r1>20 Then mappixels[pc] = argb(r1,g1,b1)
            End If
        Next
        Next    
       End Method
    Method drawr(x1,y1,w1,h1,col)
        For Local y2=y1 Until y1+h1
        For Local x2=x1 Until x1+w1
            Local pc = y2*iw+x2
            If pc >= 0 And pc < iw*ih
                mappixels[pc] = col
            End If
        Next
        Next    
       End Method
    Method addo(x1,y1,radius:Float,val:Int=10)
        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
                Local pc = y3*iw+x3
                If pc>=0 And pc < iw*ih
                    Local r1:Int=getred(mappixels[pc])
                    Local g1:Int=getgreen(mappixels[pc])
                    Local b1:Int=getblue(mappixels[pc])                                        
                    Local r2:Int=r1+val
                    Local g2:Int=g1+val
                    Local b2:Int=b1+val
                    r2 = Clamp(r2,0,255)
                    g2 = Clamp(g2,0,255)
                    b2 = Clamp(b2,0,255)                                        
                    mappixels[pc] = argb(r2,g2,b2)
                End If
            End If
        Next
        Next    
    End Method 
    Method drawo(x1,y1,radius:Float,col:Int)
        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
                Local pc = y3*iw+x3
                If pc>=0 And pc < iw*ih
                    mappixels[pc] = col
                End If
            End If
        Next
        Next    
    End Method    
    Function argb:Int(r:Int, g:Int, b:Int ,alpha:Int=255)
       Return (alpha Shl 24) | (r Shl 16) | (g Shl 8) | b          
    End Function
    Function getred:Int(rgba:Int)    
        Return((rgba Shr 16) & $FF)    
    End Function              
    Function getgreen:Int(rgba:Int)    
        Return((rgba Shr 8) & $FF)    
    End Function    
    Function getblue:Int(rgba:Int)    
        Return(rgba & $FF)    
    End Function    
    Function getalpha:Int(rgba:Int)    
        Return ((rgba Shr 24) & $FF)    
    End Function    
End Class

Global mytexture:texture

Class MyGame Extends App
    Field cnt:Int=0
    Method OnCreate()
        SetUpdateRate(1)
           Seed = GetDate[5]
        mytexture = New texture()
    End Method
    Method OnUpdate()
        cnt+=1
        If cnt>6 Then
            mytexture = New texture()
            cnt=0
        End If
    End Method
    Method OnRender()
        Cls 50,50,50
        mytexture.draw
        SetColor 255,255,255
     End Method
End Class


Function Main()
    New MyGame()
End Function

Monday, December 19, 2016

Monkey-X - Beginners - image Width and Height - code example


Import mojo

Class MyGame Extends App
    '
    Field image:Image
    '
    Method OnCreate:Int()
        SetUpdateRate(60)        
        ' create an image 
        image = CreateImage(64, 64)
        ' create an array for that image
        Local pixels:Int[image.Width * image.Height]
        ' draw the color red in the pixels array
        For Local i:Int = 0 Until image.Width * image.Height
            pixels[i] = argb(200,0,0)
        Next
        ' copy the array to the image
        image.WritePixels(pixels, 0, 0, image.Width, image.Height, 0)
    End Method
    
    Method OnRender:Int()
        Cls 0,0,0
        DrawImage(image, 50,50)
        SetColor 255,255,255
        DrawText "Image Width is : "+image.Width+" Image Height is : "+image.Height,0,0
    End Method
    
End Class

Function Main:Int()
    New MyGame()
End Function

'helper function
Function argb:Int(r:Int, g:Int, b:Int ,alpha:Int=255)
        Return (alpha Shl 24) | (r Shl 16) | (g Shl 8) | b          
End Function

Monkey-X - Beginners - Block Commenting #Rem - code example

#Rem
Anything typed here
will not cause a error.
#End
Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        
        ' You can disable a part of the code between #rem and #end
        #Rem
        DebugLog "This will not"
        DebugLog "be executed."
        #End
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - String - FromChar - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        ' character code 97 is a.
        ' character code to character
        DebugLog String.FromChar(97)
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - String - ToChars - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        ' create a array with array with the character codes of each
        ' character in a string.
        Local a:Int[]
        Local b:String="abcdefghijklmnopqrstuvwxyz"
        a = b.ToChars()
        Local deb:String
        For Local i=0 Until a.Length
            deb+=b[i..i+1]+"="+a[i]+","
        Next
        DebugLog deb
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - String - Split - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        Local a:String[]
        Local b:String="This is a test man"
        a = b.Split(" ")
        DebugLog "variable b is : "+b
        DebugLog "We split variable b at the ' ' character"
        For Local i=0 Until a.Length
            DebugLog a[i]
        Next
        a = New String[1]
        b="0,1,2,3,4,5"
        a = b.Split(",")
        DebugLog "variable b is : "+b
        DebugLog "We split the variable b at the ',' character"
        For Local i=0 Until a.Length
            DebugLog a[i]
        next
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - String - Replace - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        Local a:String="This is certainly not a test."
        DebugLog "Original string before replace 'certainly' with 'maybe' :"+a
        DebugLog "New string : "+a.Replace("certainly","maybe") 
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - String - StartsWith and EndsWith - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        Local a:String="myfile.monkey"
        Local b:String="c:\myinstallation\"
        If a.EndsWith(".monkey") Then DebugLog "variable a ends with .monkey"
        If b.EndsWith("\") Then DebugLog "variable b ends with \"
        If b.StartsWith("c:") Then DebugLog "variable b starts with c:"    
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - String - ToUpper and ToLower - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        Local a:String="test."
        Local b:String="TEST."
        DebugLog a.ToUpper
        DebugLog b.ToLower
        DebugLog "This is A Test.".ToUpper
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Strings - Contains - code example

Import mojo

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(1)
        Local a:String="test"
        Local b:String="this is a test."
        If b.Contains(a) Then DebugLog "found "+a+" in string."
        If Not b.Contains("battle") Then DebugLog "did not find battle in string" 
    End Method
    Method OnUpdate()
    End Method
    Method OnRender()
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Error - code example

' Error command - Stop the program and give a error message.

Import mojo

Class MyGame Extends App
    Field cnt:Int=0
    Method OnCreate()
        SetUpdateRate(10)
    End Method
    Method OnUpdate()
        cnt+=1
        If cnt>10 Then Error "cnt is bigger then 10"
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - DebugLog and DebugStop - code example

Import mojo

Class MyGame Extends App
    Field cnt:Int=0
    Method OnCreate()
        SetUpdateRate(2)
    End Method
    Method OnUpdate()
        cnt+=1
        DebugLog "Contents of variable cnt :"+cnt
        If cnt>10 Then DebugStop
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        
    End Method
End Class

Function Main()
    New MyGame()
End Function

Monkey-X - Beginners - Tinting a color - code example


Import mojo

Class MyGame Extends App
    Field r1:Int=255
    Field g1:Int=0
    Field b1:Int=0
    Field r2:Int=0
    Field g2:Int=255
    Field b2:Int=0
    Field r3:Int,g3:Int,b3:Int
    Method OnCreate()
        SetUpdateRate(1)
        ' tint rgb1 with 2 to create 3
        r3=r1/2+r2/2
        g3=g1/2+g2/2
        b3=b1/2+b2/2
    End Method
    Method OnUpdate()        
    End Method
    Method OnRender()
        Cls 0,0,0 
        ' what is tinting?
        ' If you wish to make a color look more like another color
        ' then you could tint it. Say you have a greyscale image
        ' and want to turn it into red. You could tint it red.
        ' you take each color value and halve it. The color where you want to 
        ' tint it with you halve to. Then you add them together to form the new color.
        SetColor r1,g1,b1
        DrawText "Color 1",0,0
        DrawRect 0,20,50,480
        SetColor r2,g2,b2
        DrawText "Color we tint with",200,0
        DrawRect 200,20,50,480
        SetColor r3,g3,b3
        DrawText "Resulting 'tinted' color",400,0
        DrawRect 400,20,50,480
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Getting started - Class in List - updating and drawing - code example


Import mojo

' what is the size of the screen.
Global screenwidth:Int=640
Global screenheight:Int=480

Class alien
    ' initialisation of variables for this class.
    Field ax:Int
    Field ay:Int
    Field deleteme:Bool=False
    Method New(x:Int,y:Int)
        ' assign the location of the alien
        ax = x
        ay = y        
    End Method
    Method update()'update method
        ' copy the mouse x and y into local variables
        Local x:Int=MouseX()
        Local y:Int=MouseY()
        If MouseDown(MOUSE_LEFT) 'if mouse pressed
        If rectsoverlap(x,y,1,1,ax,ay,16,16) 'if ontop of alien
            deleteme = True 'flag for deletion
        End If
        End If
    End Method
    Method draw() 'draw method
        SetColor 255,255,255
        DrawRect ax,ay,16,16
    End Method
    ' little helper 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    
End Class

' Start a list to store classes into
Global myalien:List<alien> = New List<alien>

Class MyGame Extends App

    Method OnCreate()
        ' frames per second (refresh rate)
        SetUpdateRate(60)
        For Local i=0 Until 50
            myalien.AddLast(New alien(Rnd(screenwidth),Rnd(screenheight)))
        Next
    End Method
    Method OnUpdate()
        'update the alien
        For Local i:=Eachin myalien
            i.update
        Next
        'delete from list if set for deletion
        For Local i:=Eachin myalien
            If i.deleteme = True Then myalien.Remove(i)
        Next
    End Method
    Method OnRender()
        Cls 0,0,0 
        'draw the aliens
        For Local i:=Eachin myalien
            i.draw
        Next
        SetColor 255,255,255
        DrawText "Press on a alien to make him disappear.",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Getting started - Class setup - example


'One way of using monkey.

Import mojo

Global screenwidth:Int=640
Global screeneight:Int=480

Class game
    ' initialisation of variables for this class.
    Field hitpoint:Int=100
    Field gold:Int=234
    Field shieldequiped:Bool=False
    Field swordequiped:Bool=False
    Method New()
        'here the game class is set up
    End Method
    Method update()
        'here you place the game logic
    End Method
    Method draw()
        ' here you place the drawing commands
    End Method
End Class

' make mygame a global variable
Global mygame:game 

Class MyGame Extends App

    Method OnCreate()
        ' frames per second (refresh rate)
        SetUpdateRate(60)
        mygame = New game()
    End Method
    Method OnUpdate()
        ' execute the game update method
        mygame.update
        ' after initialisatoin you can read/write to the variables of the class
        If KeyDown(KEY_E) Then mygame.shieldequiped = True        
    End Method
    Method OnRender()
        Cls 0,0,0 
        ' execute the game draw method
        mygame.draw
        '
        SetColor 255,255,255        
        ' use the mygame class to display information
        DrawText mygame.gold+" gold in pocket",100,100
        If mygame.shieldequiped = False Then DrawText "press 'e' to equip shield",0,0
        If mygame.shieldequiped = True Then DrawText "Shield is equiped",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Sunday, December 18, 2016

Monkey-X - Midpoint Division Algorithm - code example


Import mojo

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

Class midpoint
    Field mw:Int,mh:Int
    Field tw:Float,th:Float
    Field map:Int[][]
    Method New(w:Int,h:Int)
        mw = w
        mh = h
        tw = Float(screenwidth)/Float(mw)
        th = Float(screenheight)/Float(mh)
        map = New Int[w][]
        For Local i = 0 Until mw
            map[i] = New Int[mh]
        Next        
         map[0][0] = 128
          map[mw-1][0] = 128
          map[mw-1][mh-1] = 128
          map[0][mh-1] = 128
          midpoint(0,0,mw-1,mh-1)
    End Method
    Method midpoint(x1:Int,y1:Int,x2:Int,y2:Int)
           If(x2-x1<2 And y2-y1<2) Return False
            Local dist:Int=(x2-x1+y2-y1)
            Local hdist:Int=dist / 2
                Local midx:Int=(x1+x2) / 2
            Local midy:Int=(y1+y2) / 2
                Local c1:Int=map[x1][y1]
            Local c2:Int=map[x2][y1]
            Local c3:Int=map[x2][y2]
            Local c4:Int=map[x1][y2]
            If(map[midx][y1]=0) Then map[midx][y1]=((c1+c2+Rnd(dist)-hdist) / 2)
            If(map[midx][y2]=0) Then map[midx][y2]=((c4+c3+Rnd(dist)-hdist) / 2)
            If(map[x1][midy]=0) Then map[x1][midy]=((c1+c4+Rnd(dist)-hdist) / 2)
            If(map[x2][midy]=0) Then map[x2][midy]=((c2+c3+Rnd(dist)-hdist) / 2)
                
                map[midx][midy] = ((c1+c2+c3+c4+Rnd(dist)-hdist) / 4)
               midpoint(x1,y1,midx,midy)
            midpoint(midx,y1,x2,midy)
            midpoint(x1,midy,midx,y2)
            midpoint(midx,midy,x2,y2)

    End Method 
    Method draw()
        For Local y:Int=0 Until mh
        For Local x:Int=0 Until mw
            Local c:Int=map[x][y]
            SetColor c,c,c
            DrawRect x*tw,y*th,tw+1,th+1
        Next
        Next
    End Method
End Class

Global mymidpoint:midpoint

Class MyGame Extends App
    field cnt:Int=0
    Method OnCreate()
        SetUpdateRate(1)
        mymidpoint = New midpoint(256,256)
    End Method
    Method OnUpdate() 
        cnt+=1
        If cnt>2 Then
            mymidpoint = New midpoint(256,256)
            cnt=0
        End If           
    End Method
    Method OnRender()
        'Cls 0,0,0 
        mymidpoint.draw
        'SetColor 255,255,255
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - 2d topdown shooter - Between Space - code example


' hold the left mouse button on the screen to draw particle flames on the screen.
'#Flash

Import mojo

Global screenwidth:Int=640
Global screenheight:Int=480
Global tilewidth:Int=32
Global tileheight:Int=32

Class trail
    Field x1:Float,y1:Float
    Field x2:Float,y2:Float
    Field timeout:Int
    Field maxtimeout:Float=70
    Field alpha:Float=1
    Field deleteme:Bool=False
    Method New(x1:Float,y1:Float,x2:Float,y2:Float)
        Self.x1 = x1
        Self.y1 = y1
        Self.x2 = x2
        Self.y2 = y2
        timeout = maxtimeout
    End Method
    Method update()
        timeout -= 1
        If timeout<0
            deleteme = True
        End If
        ' update the trail with position of ship
        x1 -= Cos(myplayer.ang)*myplayer.thrust
        y1 -= Sin(myplayer.ang)*myplayer.thrust  
        x2 -= Cos(myplayer.ang)*myplayer.thrust
        y2 -= Sin(myplayer.ang)*myplayer.thrust  
        
    End Method
    Method draw()
        alpha = (1.0/maxtimeout)*timeout
        SetAlpha alpha
        SetColor 255,255,255
        DrawLine x1,y1,x2,y2
        SetAlpha 1
    End Method
End Class

Class lineeffect
    Field x1:Int=screenwidth/2
    Field y1:Int=screenheight/2
    Field x2:Int=screenwidth/2
    Field y2:Int=screenheight/2    
    Field deleteme:Bool=False
    Method New()
    End Method
    Method update()
    x1=x1-15
    y1=y1-15
    x2=x2+15
    y2=y2+15
    If x1<-20 Then deleteme=True
    End Method
    Method draw()
        SetAlpha .3
        SetColor 255,255,255
        DrawRect x1,y1,x2-x1,10
        DrawRect x1,y1,10,y2-y1 
        DrawRect x1,y2,x2-x1,10
        DrawRect x2,y1,10,y2-y1
        SetAlpha .2
        SetColor 255,255,255
        If x1>300 Then DrawRect 0,0,screenwidth,screenheight
        SetAlpha 1
    End Method
End Class

Class pickups
    Field px:Float,py:Float
    Field pw:Int=tilewidth/1.5,ph:Int=tileheight/1.5
    Field type:String
    Field ang:Int
    Field deleteme:Bool=False
    Field timeout:Int
    Field timeoutmax:Int=700+Rnd(700)
    Method New(x:Float,y:Float)
        px = x    
        py = y
        type="points"
        If Rnd()<.7 Then
        Select Int(Rnd(0,5))
        Case 0
        type = "points"
        Case 1
        type = "circle"
        Case 2
        type = "backwardsfire"
        Case 3
        type = "tripplefire"
        Case 4
        type = "hull"
        End Select
        End If
    End Method
    Method update()
        ' remove is in to long
        timeout+=1
        If timeout > timeoutmax
            deleteme = True
        End If
        
        ' update the tilemap with the player movement
        px -= Cos(myplayer.ang)*myplayer.thrust
        py -= Sin(myplayer.ang)*myplayer.thrust 
        ang+=3
        If ang>359 Then ang=0
        
        ' collide with player (pickup)
        If rectsoverlap(px,py,pw,ph,screenwidth/2,screenheight/2,tilewidth,tileheight)
            deleteme = True
            mylineeffect.AddLast(New lineeffect())
            If type="points" Then myplayer.score+=15
            If type="circle"
                For Local i=0 To 360 Step 20
                    mybullet.AddLast(New bullet("player","doubledamage",px,py,i,3.3))
                Next
            End If
            If type="backwardsfire"
                myplayer.backwardsfire=True
                myplayer.backwardsfiretime=1000
            End If
            If type="tripplefire"
                myplayer.tripplefire=True
                myplayer.tripplefiretime=1000
            End If
            If type="hull"
                myplayer.hitpoint+=3
                If myplayer.hitpoint > myplayer.maxhitpoint Then  myplayer.hitpoint = myplayer.maxhitpoint
            End If
            Print "Pickup"
        End If
        '
    End Method
    Method draw()
        Select type
            Case "points"
                PushMatrix()
                Translate px,py
                Rotate(-ang)
                Translate -px,-py
                  SetColor 20,20,20
                DrawRect px-pw/2,py-ph/2,pw,ph
                SetColor 255,255,0
                DrawRect (px-pw/2+1),(py-ph/2)+1,pw-2,ph-2
                SetColor 255,255,255
                Scale(2,2)
                DrawText "P",px/2,py/2,.5,.5
                Scale(1,1)
                PopMatrix()
            Case "circle" ' a circle of lasers
                PushMatrix()
                Translate px,py
                Rotate(-ang)
                Translate -px,-py
                  SetColor 20,20,20
                DrawRect px-pw/2,py-ph/2,pw,ph
                SetColor 0,0,255
                DrawRect (px-pw/2+1),(py-ph/2)+1,pw-2,ph-2
                SetColor 255,255,255
                Scale(2,2)
                DrawText "C",px/2,py/2,.5,.5
                Scale(1,1)
                PopMatrix()    
            Case "backwardsfire" 'can fire backwards
                PushMatrix()
                Translate px,py
                Rotate(-ang)
                Translate -px,-py
                  SetColor 20,20,20
                DrawRect px-pw/2,py-ph/2,pw,ph
                SetColor 0,255,255
                DrawRect (px-pw/2+1),(py-ph/2)+1,pw-2,ph-2
                SetColor 255,255,255
                Scale(2,2)
                DrawText "B",px/2,py/2,.5,.5
                Scale(1,1)
                PopMatrix()    
            Case "tripplefire" 'can fire backwards
                PushMatrix()
                Translate px,py
                Rotate(-ang)
                Translate -px,-py
                  SetColor 20,20,20
                DrawRect px-pw/2,py-ph/2,pw,ph
                SetColor 250,155,55
                DrawRect (px-pw/2+1),(py-ph/2)+1,pw-2,ph-2
                SetColor 255,255,255
                Scale(2,2)
                DrawText "T",px/2,py/2,.5,.5
                Scale(1,1)
                PopMatrix() 
            Case "hull" 'can fire backwards
                PushMatrix()
                Translate px,py
                Rotate(-ang)
                Translate -px,-py
                  SetColor 20,20,20
                DrawRect px-pw/2,py-ph/2,pw,ph
                SetColor 250,35,10
                DrawCircle px+1,py,pw/1.6
                SetColor 250,35,10
                DrawRect (px-pw/2+1),(py-ph/2)+1,pw-2,ph-2
                SetColor 255,255,255
                Scale(2,2)
                DrawText "H",px/2,py/2,.5,.5
                Scale(1,1)
                PopMatrix() 
        End Select
    End Method
    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     
End Class

Class enemy
    Field type:String    
    Field ex:Float,ey:Float,er:Int
    Field thrust:Float,ang:Int
    Field deleteme:Bool=False
    Field targetx:Int,targety:Int
    Field targetset:Bool=False
    Field state:String
    Field ishome:Bool=False
    Field roaming:Bool=False
    Field homex:Int,homey:Int
    Field firedelay:Int=20,firetime:Int
    Field hitpoint:Int=3
    Field maxhitpoint = 3
    Field gothit:Bool=False
    Field gothittime:Int=20
    Field bombarding:Int=False
    Field maxthrust:Float=3.3
    Field dropfreq:Float=0.4 'lower is less
    Field ffhitpoint:Int=2 'force field hitpoints
    Method New(x:Int,y:Int)
        If Rnd()<.5 Then type="forcefield"
        ex=x
        ey=y
        er=16
        hitpoint=maxhitpoint
        homex = x
        homey = y
        thrust=maxthrust
        state="roam"
    End Method
    Method update()
        'collision with player bullets        
        If gothit = True Then gothittime-=1
        For Local i:=Eachin mybullet
            If i.owner = "player"
                If rectsoverlap(i.bx,i.by,i.bradius,i.bradius,
                                ex-3,ey-3,er+3,er+3)
                    If type="forcefield"
                        If i.type = "doubledamage" Then ffhitpoint-=2 Else ffhitpoint-=1
                        If ffhitpoint<=0 Then type=""
                    Else
                        If i.type = "doubledamage" Then hitpoint-=2 Else hitpoint-=1
                        gothit=True
                        gothittime=20
                        If hitpoint<1 Then 
                            Print "Exploded"
                            If Rnd()<dropfreq Then mypickup.AddLast(New pickups(ex+Cos(ang)*thrust,ey+Sin(ang)*thrust))
                            myp.AddLast(New particleeffect(ex+Cos(ang)*thrust,ey+Sin(ang)*thrust))
                            deleteme = True
                            state=""
                            myplayer.score+=10
                        End If
                        i.deleteme = True
                    End If
                End If
            End If
        Next
        ' states of the enemy
        Select state
            Case "attack"
                If Rnd() < .0005
                    state = "roam"
                    Print "done attacking"
                    ishome=False
                    roaming=False
                End If
                If Rnd()<.1 Then fireatplayer()
                settarget
                If Rnd() < .1 bombard()
                movein
                turn
            Case "roam"    
                If Rnd()<.002                    
                    state="attack"
                    Print "going to attack"
                End If
                roam
                movein
                turn
        End Select
    End Method
    Method fireatplayer()
        Local d:Int=distance(ex,ey,screenwidth/2,screenheight/2)        
        firetime+=1
        If d<250 And firetime > firedelay
            firetime = 0
            Local a:Int=getangle(ex,ey,screenwidth/2,screenheight/2)
            If myplayer.thrust > .5 Then a=ang
            mybullet.AddLast(New bullet("enemy","normal",ex,ey,a,4))
            If Rnd()<.1 Then ' sometimes after shooting head back
                state = "roam"
                Print "done attacking"
                thrust = maxthrust
                ishome=False
                roaming=False
            End If
        End If
    End Method
    Method bombard()
        Local d:Int = distance(ex,ey,screenwidth/2,screenheight/2)
        If bombarding = True And d >220 Then
            thrust = maxthrust
            bombarding = False
            state = "roam"
            ishome=False    
            roaming=False            
        End If
        If myplayer.thrust = 0 And d < 200 And d> 100 And bombarding = False
            thrust = 0
            fireatplayer()
            bombarding = True
        End If
        If bombarding = True
            Local ax:Int=screenwidth/2
            Local ay:Int=screenheight/2
            If Rnd()<.8 And linerectoverlap(ax,ay,ax+Cos(myplayer.ang)*350,ay+Sin(myplayer.ang)*350,ex,ey,er,er)
                Print "scared off"
                thrust = maxthrust
                bombarding = False
                state = "roam"
                ishome=False    
                roaming=False                            
            End If
            fireatplayer()
        End If
    End Method
    Method roam()
        Local dtohome = distance(ex,ey,homex,homey)
        Local dtotarget = distance(ex,ey,targetx,targety)
        If dtohome > 300 And ishome = False And roaming=False
            ishome=True            
            targetx = homex
            targety = homey                
        End If
        If dtohome < 50 And ishome = True And roaming = False
            roaming = True
            targetx = homex+Rnd(-100,100)
            targety = homey+Rnd(-100,100)
        End If
        If dtotarget < 50 And roaming = True
            targetx = homex+Rnd(-100,100)
            targety = homey+Rnd(-100,100)
        End If
        If dtotarget > 300 And roaming=True
            roaming=False
            ishome=False
        End If
    End Method
    Method turn()
        'turn
        Local pangle:Int = getangle(ex,ey,targetx,targety)
        If leftangle(ang,pangle) = True Then ang+=3 Else ang-=3
        If ang>180 Then ang=-180
        If ang<-180 Then ang=180
    End Method

    Method movein()
        'move in
        ex -= Cos(myplayer.ang)*myplayer.thrust
        ey -= Sin(myplayer.ang)*myplayer.thrust        
        ex += Cos(ang)*thrust
        ey += Sin(ang)*thrust
    End Method

    Method settarget()        
        'set target
        Local d:Int=distance(ex,ey,screenwidth/2,screenheight/2)
        If d > 550
            targetx = screenwidth/2
            targety = screenheight/2
            targetset = False
        Else
            If targetset = False
                targetx = (screenwidth/2)+Rnd(-90,90)
                targety = (screenheight/2)+Rnd(-90,90)                
                targetset = True
            End If
        End If
        If d<80 Then 
                targetx = (screenwidth/2)+Rnd(-190,190)
                targety = (screenheight/2)+Rnd(-190,190)                        
        End If
    End Method

    Method draw()
        SetColor 255,0,0
        If gothit = True        
            If gothittime<0 Then gothit=False
            SetColor 255,255,255
        End If
        DrawCircle ex,ey,er
        ' draw the powerbar
        Local x:Float=ex-er
        Local y:Float=ey-er
        Local w1:Float=(er*2)-2
        Local w2:Float=(er*2)
        Local s:Float = w1/maxhitpoint
        w1 = s*hitpoint
        SetColor 0,0,0
        DrawRect x,y,w2,5
        If hitpoint < 2
        SetColor 255,0,0
        Else
        SetColor 255,255,0
        End If
        DrawRect x+2,y+2,w1,3        
        ' draw forcefield
        If type="forcefield"
            SetColor 55,155,255
            SetAlpha .5
            DrawCircle ex-2,ey-2,er+12
            SetAlpha 1
        End If
    End Method
    Function leftangle:Bool(_angle:Int,_destinationangle:Int)
        Local cnt1 = 0    
        Local a1 = _angle
        While a1<>_destinationangle    
            a1+=1
            If a1>180 Then a1=-180
            cnt1+=1
        Wend
        If cnt1<180 Then Return True Else Return False
    End Function    
    Function linerectoverlap:Bool(x1:Int,y1:Int,x2:Int,y2:Int,x3:Int,y3:Int,w:Int,h:Int)
        Local a:Int=getangle(x1,y1,x2,y2)
        Local ax:Float=x1
        Local ay:Float=y1
'        Print x2
'        Print x1+","+ax+Cos(a)*300+","+x2
        Local ex:Bool=False
        While ex=False            
            ax+=Cos(a)*1
            ay+=Sin(a)*1
'            Print ax+","+ay+","+x2+","+y2
            If rectsoverlap(ax-8,ay-8,16,16,x2-8,y2-8,16,16) = True Then ex=True                        
            If rectsoverlap(x3,y3,w,h,ax-6,ay-6,12,12) Then 
                Return True
            End If
        Wend
        Return False
    End Function
    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    
    Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int)
        Return Abs(x2-x1)+Abs(y2-y1)
    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    
End Class

Class bullet
    Field deleteme:Bool=False
    Field bx:Float,by:Float,bradius:Float
    Field ang:Int,thrust:Float
    Field time:Int,timeout:Int=100
    Field alpha:Float
    Field owner:String
    Field type:String
    Method New(owner:String,type:String,x:Int,y:Int,angle:Int,thrust:Float)
        Self.type = type
        Self.owner = owner
        Self.ang = angle
        Self.bx = x
        Self.by = y
        Self.thrust = thrust
        bradius = 6
        thrust = 4
    End Method
    Method update()
        time+=1
        bx += Cos(ang)*thrust
        by += Sin(ang)*thrust
        If time > timeout Then deleteme = True
        alpha = 1-(.5/Float(timeout))*time
        ' update the tilemap with the player movement
        bx -= Cos(myplayer.ang)*myplayer.thrust
        by -= Sin(myplayer.ang)*myplayer.thrust         
    End Method
    Method draw()
        SetAlpha alpha
        SetColor 0,0,0
        DrawCircle bx-1,by,bradius+1
        Select owner
            Case "player"
            SetColor 255,0,255        
            Case "enemy"
            SetColor 255,255,0
        End Select
        DrawCircle bx,by,bradius
        Select owner
            Case "player"
            SetColor 255,190,255        
            Case "enemy"
            SetColor 255,255,190
        End Select

        DrawCircle (bx-bradius)+4,(by-bradius)+4,bradius/2
        SetAlpha 1
    End Method
End Class

Class player
    Field score:Int
    Field ang:Float
    Field thrust:Float
    Field turninc:Float
    Field turnincmax:Float=3
    Field turnincmin:Float=-3
    Field maxthrust:Float = 4
    Field firedelay:Int=5
    Field firetime:Int
    Field backwardsfire:Bool=False
    Field backwardsfiretime:Int
    Field tripplefire:Bool=False
    Field tripplefiretime:Int
    Field ship:Float[]=[    -5.0,-5.0,
                         5.0,0.0,
                         -5.0,5.0] 
    Field trailtime:Int=10
    Field hitpoint = 10
    Field maxhitpoint=10
    Method New()    
    End Method
    Method update()
        'shoot
        firetime+=1
        If KeyDown(KEY_SPACE) And firetime > firedelay
            firetime = 0
            mybullet.AddFirst(New bullet("player","Normal",screenwidth/2,screenheight/2,ang,6))
             'should we fire backwards to
            If backwardsfire = True
                Local a:Int=ang
                For Local i=0 Until 180
                a+=1
                If a>359 Then a=0
                Next
                mybullet.AddFirst(New bullet("player","Normal",screenwidth/2,screenheight/2,a,6))
            End If
            If tripplefire = True
                Local a:Int=ang
                For Local i=0 Until 25
                a+=1
                If a>359 Then a=0
                Next
                mybullet.AddFirst(New bullet("player","Normal",screenwidth/2,screenheight/2,a,6))            
                a=ang
                For Local i=0 Until 25
                a-=1
                If a<0 Then a=360
                Next
                mybullet.AddFirst(New bullet("player","Normal",screenwidth/2,screenheight/2,a,6))            

            End If
        End If
        'turn
        If KeyDown(KEY_LEFT) Then turninc-=.2
        If KeyDown(KEY_RIGHT) Then turninc+=.2
        turninc = Clamp(turninc,turnincmin,turnincmax)
        If turninc > .1 Then turninc -= .1
        If turninc < -.1 Then turninc += .1
        If turninc >-.1 And turninc <.1 Then turninc=0
        ang+=turninc
        If ang>359 Then ang=0
        If ang<0 Then ang=359
        'thrust
        If KeyDown(KEY_UP) Then thrust += .1
        If KeyDown(KEY_DOWN) Then thrust -= .1
        If thrust < 0 Then thrust = 0
        If thrust > maxthrust Then thrust = maxthrust
        ' Here the trail is created
        trailtime-=1
        If trailtime<0 Then
            Local x:Int=screenwidth/2
            Local y:Int=screenheight/2
            mytrail.AddLast(New trail(x,y,x+Cos(ang)*12,y+Sin(ang)*12))    
            trailtime=10
        End If

        ' count down backwards fire
        backwardsfiretime-=1
        If backwardsfiretime<0 Then
            backwardsfire=False
        End If
        ' count down trippe fire
        tripplefiretime-=1
        If tripplefiretime<0 Then
            tripplefire=False
        End If
        
        'collision detection with the bullets
        For Local i:=Eachin mybullet
            If i.owner="enemy"
            If rectsoverlap(i.bx,i.by,i.bradius,i.bradius,(screenwidth/2)-3,(screenheight/2)-3,tilewidth-6,tileheight-6)
                i.deleteme = True
                hitpoint -= 1
            End If
            End If
        Next
        
    End Method    
    Method draw()
        PushMatrix()
        Translate screenwidth/2,screenheight/2
        Rotate(-ang)
        Scale(4,4)
        SetColor 255,255,255
        DrawPoly(ship)        
        Translate 0,0
        PopMatrix()  
        SetColor 255,0,0
        DrawLine    screenwidth/2,
                    screenheight/2,
                    screenwidth/2+Cos(ang)*(tilewidth*2),
                    screenheight/2+Sin(ang)*(tileheight*2)
    
    End Method
    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      
End Class

Class map
    Field mapx:Float=0
    Field mapy:Float=0
    Field map:Int[][] = [    [0,0,0,1,0,1,0,1,0,1,0,1,0,0,0],
                            [0,0,0,0,1,0,0,0,0,0,1,0,0,0,0],
                            [0,1,0,1,0,1,0,0,0,1,0,1,0,1,0],
                            [0,1,0,0,0,0,1,1,1,0,0,0,0,1,0],
                            [0,1,0,1,0,0,1,0,1,0,0,1,0,1,0],
                            [0,1,0,0,0,0,1,1,1,0,0,0,0,1,0],
                            [0,1,0,1,0,1,0,0,0,1,0,1,0,1,0],
                            [0,1,0,0,1,0,0,0,0,0,1,0,0,1,0],
                            [0,0,0,1,0,1,0,1,0,1,0,1,0,0,0],
                            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]    
    Field starimage:Image 
    Field starimagew:Int=screenwidth*2
    Field starimageh:Int=screenheight*2
    Field starimagepixels:Int[]                                                                                                                                                                                                                            
    Method New()        
        ' create the background starfield
        starimagepixels = New Int[starimagew*starimageh]
        starimage = CreateImage(starimagew,starimageh)
        createstarimage()        
    End Method
    Method update() 
        ' update the tilemap with the player movement
        mymap.mapx -= Cos(myplayer.ang)*myplayer.thrust
        mymap.mapy -= Sin(myplayer.ang)*myplayer.thrust        
    End Method
    Method createstarimage()
        For Local i=0 Until starimagew*starimageh
            starimagepixels[i] = argb(0,0,0)
        Next
        Local s:Float=255.0/(starimageh/2)
        Local cnt:Float=0
        For Local y = starimageh To starimageh/2 Step -1            
            drawr(0,y,starimagew,1,argb(0,0,255-s*cnt))
            cnt+=1
        Next
        '
        For Local i=0 Until 1000
            Local c:Int=Rnd(10,255)
            Local pos:Int=Rnd(starimagew*starimageh)
            starimagepixels[pos] = argb(c,c,c)
            If Rnd()<.2 Then starimagepixels[pos-1] = argb(c,c,c)
        Next
        ' create the planet in the background
        Local x:Int=screenwidth-90
        Local y:Int=screenheight-90
        drawo(x,y,200,argb(40,20,20))
        drawo(x+10,y+10,195,argb(0,0,0))
    
        starimage.WritePixels(starimagepixels, 0, 0, starimagew, starimageh, 0)
    End Method
    Method draw()    
        SetAlpha 1
        DrawImage starimage,(-screenwidth/2)+(mapx/15),(-screenheight/2)+(mapy/15)        
        For Local y=0 Until 10
        For Local x=0 Until 15
            If map[y][x] = 1
                Local x2:Int=x*tilewidth+mapx
                Local y2:Int=y*tileheight+mapy
                SetColor 155,155,155
                DrawRect    x2,
                            y2,
                            tilewidth,
                            tileheight
                SetColor 255,255,255
                DrawLine x2+2,y2+2,x2+tilewidth-4,y2+2
                DrawLine x2+2,y2+2,x2+2,y2+tileheight-4
                SetColor 55,55,55
                DrawLine x2+4,y2+tileheight-4,x2+tilewidth-8,y2+tileheight-4
                DrawLine x2+tilewidth-4,y2+tileheight-4,x2+tilewidth-4,y2+4
            End If
        Next
        Next
        'drawminimap
        '
        Local s:Float=255/9
        For Local x=0 Until 9
            Local c:Float=Float(x)*s
            SetColor c,c,c
            DrawLine (screenwidth-109)+x,0,(screenwidth-109)+x,103+x
        Next       
        For Local y=0 To 9
            Local c:Float=Float(y)*s
            SetColor c,c,c
            DrawLine (screenwidth-109)+y,109-y,screenwidth,109-y
        Next
        '       
        SetColor 10,10,10
        DrawRect screenwidth-100,1,100,100
        'tilecenter
        SetColor 100,100,100
        Local x:Float = screenwidth-100
        Local y:Float = 1
        x += (100.0/5000)*mymap.mapx
        y += (100.0/5000)*mymap.mapy
        x+=55
        y+=55
'        Print x
        DrawRect x,y,10,10
        ' enemies/drones
        SetColor 255,255,0
        For Local i:=Eachin myenemy
            Local x:Float=screenwidth-100
            Local y:Float=1
            Local sx:Float=100.0/5000
            Local sy:Float=100.0/5000
            x+=(sx*i.ex)+50
            y+=(sy*i.ey)+50
            DrawRect x,y,2,2
        Next
        'player position
        SetColor 255,255,50
        SetAlpha .4
        DrawCircle screenwidth-50+10,50+10,20
        SetAlpha 1
    End Method
    ' makes a noisy oval
    Method drawo(x1,y1,radius,col)        
        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
                Local pc = y3*starimagew+x3
                If pc>=0 And pc < starimagew*starimageh
                    Local r:Int=getred(col)
                    Local g:Int=getgreen(col)
                    Local b:Int=getblue(col)
                    Local rs:Float=Float(255)/9
                    Local gs:Float=Float(255)/9
                    Local bs:Float=Float(255)/9                                        
                    Local r2:Int = r+Rnd(-rs,rs)
                    Local g2:Int = r+Rnd(-gs,gs)                
                    Local b2:Int = r+Rnd(-bs,bs)
                    r2 = Clamp(r2,0,255)
                    g2 = Clamp(g2,0,255)
                    b2 = Clamp(b2,0,255)
                    Local mc:Int=(r2+g2+b2)/3
                    r2=(r2/2)+r/2
                    g2=(g2/2)+g/2
                    b2=(b2/2)+b/2
                    Local col2:Int=argb(r2,g2,b2)
                    starimagepixels[pc] = col2
                End If
            End If
        Next
        Next    
    End Method
    Method drawr(x1,y1,w1,h1,col)
        For Local y2=y1 Until y1+h1
        For Local x2=x1 Until x1+w1
            Local pc = y2*starimagew+x2
            If pc >= 0 And pc < starimagew*starimageh
                starimagepixels[pc] = col
            End If
        Next
        Next 
       End Method
    Function argb:Int(r:Int, g:Int, b:Int ,alpha:Int=255)
       Return (alpha Shl 24) | (r Shl 16) | (g Shl 8) | b          
    End Function
    Function getred:Int(rgba:Int)    
        Return((rgba Shr 16) & $FF)    
    End Function              
    Function getgreen:Int(rgba:Int)    
        Return((rgba Shr 8) & $FF)    
    End Function    
    Function getblue:Int(rgba:Int)    
        Return(rgba & $FF)    
    End Function    
    Function getalpha:Int(rgba:Int)    
        Return ((rgba Shr 24) & $FF)    
    End Function        
End Class

Class particle
    Field x:Float
    Field y:Float
    Field incx:Float
    Field incy:Float
    Field modincx:Float
    Field modincy:Float
    Field sx:Float
    Field sy:Float
    Field sxinc:Float
    Field syinc:Float
    Field timeout:Float
    Field time:Float
    Field alpha:Float
    Field deleteme:Bool=False    
    Method New(x:Int,y:Int,angle:Int)
        Self.x = x
        Self.y = y
        incx = Cos(angle+Rnd(-5,5))
        incy = Sin(angle+Rnd(-5,5))
        timeout = 50+Rnd(20)
        alpha = 1
        modincx = (Cos(angle+Rnd(-5,5)))/100
        modincy = (Sin(angle+Rnd(-5,5)))/100
        Local sc:Float=Rnd(0.5,1)
        sx = sc
        sy = sc
        sxinc = Rnd()/timeout
        syinc = Rnd()/timeout
    End Method
    Method update()
           x -= Cos(myplayer.ang)*myplayer.thrust
        y -= Sin(myplayer.ang)*myplayer.thrust     
    End Method
End Class

Class particleeffect
    Field sw:Int,sh:Int
    Field p:List<particle> = New List<particle>
    Field image:Image
    Field iw:Int=32
    Field ih:Int=32
    Field pixels:Int[]
    Field angle:Int
    Field x:Float,y:Float
    Field deleteme:Bool=False
    Field timeout:Int=50
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
        Self.sw = screenwidth
        Self.sh = screenheight
        pixels = New Int[iw*ih]
        image = CreateImage(iw,ih,image.MidHandle)
        makeimage()
        p.AddFirst(New particle(x,y,Rnd(360)))
    End Method
    Method update()
        timeout-=1
        If timeout < 0 Then deleteme = True        
        If Rnd() < 0.4
            p.AddFirst(New particle(x,y,Rnd(360)))
        End If
        'update the particles with the map movement(player)
          x -= Cos(myplayer.ang)*myplayer.thrust
           y -= Sin(myplayer.ang)*myplayer.thrust             
        For Local i:=Eachin p
            'update the particles with the map movement(player)
              i.x -= Cos(myplayer.ang)*myplayer.thrust
            i.y -= Sin(myplayer.ang)*myplayer.thrust        
            i.x += i.incx
            i.y += i.incy
            i.incx += i.modincx
            i.incy += i.modincy
            i.alpha -= 1/i.timeout
            i.time += 1
            i.sx += i.sxinc
            i.sy += i.syinc
            If i.time > i.timeout Then i.deleteme = True
        Next
        For Local i:=Eachin p
            If i.deleteme = True Then p.Remove(i)
        Next
    End Method
    Method makeimage()
        For Local i=0 To iw        
            Local c:Int = 0+((255/iw)*i)
            drawo(iw/2,ih/2,(iw/2)-(i),argb(c,c,c,255))
        Next
        image.WritePixels(pixels, 0, 0, iw, ih, 0)
    End Method
    Method drawo(x1,y1,radius:Float,col)
        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
                Local pc = y3*iw+x3
                If pc>=0 And pc < iw*ih
                    pixels[pc] = col
                End If
            End If
        Next
        Next    

    End Method

    Method draw()
        SetBlend AdditiveBlend
        SetColor 255,50,0
        For Local i:=Eachin p
            SetAlpha i.alpha
            Local sc:Float=(1/i.timeout)*i.time
            DrawImage(image,i.x,i.y,1,i.sx,i.sy)
        Next
        SetAlpha 1
        SetBlend AlphaBlend
    End Method
    Function argb:Int(r:Int, g:Int, b:Int ,alpha:Int=255)
       Return (alpha Shl 24) | (r Shl 16) | (g Shl 8) | b          
    End Function
    Function getred:Int(rgba:Int)    
        Return((rgba Shr 16) & $FF)    
    End Function              
    Function getgreen:Int(rgba:Int)    
        Return((rgba Shr 8) & $FF)    
    End Function    
    Function getblue:Int(rgba:Int)    
        Return(rgba & $FF)    
    End Function    
    Function getalpha:Int(rgba:Int)    
        Return ((rgba Shr 24) & $FF)    
    End Function    
End Class

Global myplayer:player
Global mymap:map
Global mybullet:List<bullet> = New List<bullet>
Global myenemy:List<enemy> = New List<enemy>
Global myp:List<particleeffect> = New List<particleeffect>
Global mypickup:List<pickups> = New List<pickups>
Global mylineeffect:List<lineeffect> = New List<lineeffect>
Global mytrail:List<trail> = New List<trail>

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
        myplayer = New player()
        mymap = New map()        
        For Local i=0 Until 5    
            myenemy.AddLast(New enemy(Rnd(-screenwidth*2,screenwidth*2),Rnd(-screenheight*2,screenheight*2)))
        Next
        For Local i=0 Until 3
        mypickup.AddLast(New pickups(Rnd(300),Rnd(300)))
        Next
        For Local i=0 Until 10
        mypickup.AddLast(New pickups(screenwidth/2+Rnd(-50,50),screenheight/2+Rnd(-50,50)))
        Next
    End Method
    Method OnUpdate() 
        myplayer.update()
        mymap.update()
        
        If MouseDown(MOUSE_LEFT)
            myp.AddLast(New particleeffect(MouseX(),MouseY()))
        End If
        
        'update the trail
        For Local i:=Eachin mytrail
            i.update
        Next
        'update the trail
        For Local i:=Eachin mytrail
            If i.deleteme = True Then mytrail.Remove(i)
        Next
                
        'update the line effects
        For Local i:=Eachin mylineeffect
            i.update
        Next
        For Local i:=Eachin mylineeffect
            If i.deleteme = True Then mylineeffect.Remove(i)
        Next
        
        ' update the pickpups
        For Local i:=Eachin mypickup
            i.update()
        Next        
        For Local i:=Eachin mypickup
            If i.deleteme = True Then mypickup.Remove(i)
        Next 
        ' update the particles
        For Local i:=Eachin myp
            i.update()
        Next        
        For Local i:=Eachin myp
            If i.deleteme = True Then myp.Remove(i)
        Next                 
        For Local i:=Eachin mybullet
            i.update
        Next
        For Local i:=Eachin mybullet
            If i.deleteme = True Then mybullet.Remove(i)
        Next
        For Local i:=Eachin myenemy
            i.update
        Next
        For Local i:=Eachin myenemy
            If i.deleteme = True Then myenemy.Remove(i)
        Next
        ' temp add new enemies if all have died
        Local cnt:Int=0
        For Local i:=Eachin myenemy
            cnt+=1
        Next
        If cnt=0 Then 
            For Local i=0 Until Rnd(5,8)
                myenemy.AddLast(New enemy(Rnd(-screenwidth*2,screenwidth*2),Rnd(-screenheight*2,screenheight*2)))
            Next
            For Local i=0 Until 10
                mypickup.AddLast(New pickups(mymap.mapx+Rnd(300),mymap.mapy+Rnd(300)))
            Next
            
            Print "Added new wave of enemies"
        End If
    End Method
    Method OnRender()
        'Cls 0,0,0  
        mymap.draw()
        'draw the pickups
        For Local i:=Eachin mypickup
            i.draw
        Next           

        For Local i:=Eachin myenemy
            i.draw
        Next           
        For Local i:=Eachin mybullet
            i.draw
        Next           
        'update the particles
        For Local i:=Eachin myp
            i.draw()
        Next        

        'draw the trail
        For Local i:=Eachin mytrail
            i.draw
        Next

        myplayer.draw()
        
        'draw the line effects
        For Local i:=Eachin mylineeffect
            i.draw
        Next

        
        SetColor 255,255,255
        DrawText "Cursor Left/Right/Up/Down/Space",0,0
        DrawText "Score : "+myplayer.score,0,screenheight-15
        DrawText "Hull : "+myplayer.hitpoint,200,screenheight-15        
    End Method
End Class


Function Main()
    New MyGame()
End Function

Saturday, December 17, 2016

Monkey-X - Example - Additive Particle Flames - code example


Import mojo

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

Class particle
    Field x:Float
    Field y:Float
    Field incx:Float
    Field incy:Float
    Field modincx:Float
    Field modincy:Float
    Field sx:Float
    Field sy:Float
    Field sxinc:Float
    Field syinc:Float
    Field timeout:Float
    Field time:Float
    Field alpha:Float
    Field deleteme:Bool=False    
    Method New(x:Int,y:Int,angle:Int)
        Self.x = x
        Self.y = y
        incx = Cos(angle+Rnd(-5,5))
        incy = Sin(angle+Rnd(-5,5))
        timeout = 50+Rnd(20)
        alpha = 1
        modincx = (Cos(angle+Rnd(-5,5)))/100
        modincy = (Sin(angle+Rnd(-5,5)))/100
        Local sc:Float=Rnd(0.5,1)
        sx = sc
        sy = sc
        sxinc = Rnd()/timeout
        syinc = Rnd()/timeout
    End Method
End Class

Class particleeffect
    Field sw:Int,sh:Int
    Field p:List<particle> = New List<particle>
    Field image:Image
    Field iw:Int=32
    Field ih:Int=32
    Field pixels:Int[]
    Field angle:Int
    Field x:Int,y:Int
    Method New(x:Int,y:Int,angle:Int)
        Self.x = x
        Self.y = y
        Self.sw = screenwidth
        Self.sh = screenheight
        Self.angle = angle
        pixels = New Int[iw*ih]
        image = CreateImage(iw,ih,image.MidHandle)
        makeimage()
        p.AddFirst(New particle(x,y,angle))
    End Method
    Method update()
        If Rnd() < 0.4
            p.AddFirst(New particle(x,y,angle))
        End If
        For Local i:=Eachin p
            i.x += i.incx
            i.y += i.incy
            i.incx += i.modincx
            i.incy += i.modincy
            i.alpha -= 1/i.timeout
            i.time += 1
            i.sx += i.sxinc
            i.sy += i.syinc
            If i.time > i.timeout Then i.deleteme = True
        Next
        For Local i:=Eachin p
            If i.deleteme = True Then p.Remove(i)
        Next
    End Method
    Method makeimage()
        For Local i=0 To iw        
            Local c:Int = 0+((255/iw)*i)
            drawo(iw/2,ih/2,(iw/2)-(i),argb(c,c,c,255))
        Next
        image.WritePixels(pixels, 0, 0, iw, ih, 0)
    End Method
    Method drawo(x1,y1,radius:Float,col)
        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
                Local pc = y3*iw+x3
                If pc>=0 And pc < iw*ih
                    pixels[pc] = col
                End If
            End If
        Next
        Next    

    End Method

    Method draw()
        SetBlend AdditiveBlend
        For Local i:=Eachin p
            SetAlpha i.alpha
            Local sc:Float=(1/i.timeout)*i.time
            DrawImage(image,i.x,i.y,1,i.sx,i.sy)
        Next
        SetAlpha 1
    End Method
    Function argb:Int(r:Int, g:Int, b:Int ,alpha:Int=255)
       Return (alpha Shl 24) | (r Shl 16) | (g Shl 8) | b          
    End Function
    Function getred:Int(rgba:Int)    
        Return((rgba Shr 16) & $FF)    
    End Function              
    Function getgreen:Int(rgba:Int)    
        Return((rgba Shr 8) & $FF)    
    End Function    
    Function getblue:Int(rgba:Int)    
        Return(rgba & $FF)    
    End Function    
    Function getalpha:Int(rgba:Int)    
        Return ((rgba Shr 24) & $FF)    
    End Function    
End Class

Global m:List<particleeffect> = New List<particleeffect>

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
        For Local i=0 Until 5
            m.AddLast(New particleeffect(i*(640/5)+30,200,Rnd(250,260)))
        Next
    End Method
    Method OnUpdate()
        For Local i:=Eachin m
            i.update()
        Next
    End Method
    Method OnRender()
        Cls 50,50,50
        For Local i:=Eachin m
            i.draw()
        Next
    End Method
End Class


Function Main()
    New MyGame()
End Function