Friday, July 31, 2015

Monkey-X - RPG - Battle screen (4x*4x) - code example


Here a rather longer then usual codefile. Here a never ending automated battle takes place between 1 to 4 players against 1 to 4 enemies(right). 

' RPG Battle screen example.

Import mojo

Class battlescreen
    Field numenemies:Int
    Field numplayers:Int
    Field enemyx:Float[4]
    Field enemyy:Float[4]
    Field enemyh:Int[4]
    Field enemya:Int[4]
    Field enemyd:Int[4]
    Field temppx:Int     'holds the start location 
                        'of the currently
                        'moving agent.
    Field temppy:Int
    Field enemyattackx:Int=320+64
    Field enemyattacky:Int=480/2
    Field currentenemy:Int=0
    Field playerx:Float[4]
    Field playery:Float[4]
    Field playerh:Int[4]
    Field playera:Int[4]
    Field playerd:Int[4]
    Field playerattackx:Int=320-128
    Field playerattacky:Int=480/2
    Field currentplayer:Int=0
    Field state:String="startmoveenemyin"

    Method update()
        If state="startmoveplayerin"
            temppx = playerx[currentplayer]
            temppy = playery[currentplayer]
            state = "moveplayerin"             
        End If
        If state="moveplayerin"
            For Local i=0 Until 3
                Local an:Int=getangle(    playerattackx,playerattacky,
                                        playerx[currentplayer],
                                        playery[currentplayer])
                playerx[currentplayer] += Cos(an)
                playery[currentplayer] += Sin(an)
                If rectsoverlap(    playerx[currentplayer]-3,
                                    playery[currentplayer]-3,
                                    6,6,
                                    playerattackx-3,
                                    playerattacky-3,
                                    6,6)=True                                                                    
                    playerx[currentplayer] = playerattackx
                    playery[currentplayer] = playerattacky
                    state="playerdobattle"
                End If
            Next
        End If
        If state="moveplayerback"
            For Local i=0 Until 3
                Local an:Int=getangle(    temppx,temppy,
                                        playerx[currentplayer],
                                        playery[currentplayer])
                playerx[currentplayer] += Cos(an)
                playery[currentplayer] += Sin(an)
                If rectsoverlap(    playerx[currentplayer]-3,
                                    playery[currentplayer]-3,
                                    6,6,
                                    temppx-3,temppy-3,
                                    6,6)=True
                    playerx[currentplayer] = temppx
                    playery[currentplayer] = temppy
                    state="nextplayermove"
                End If
            Next            
        End If

        If state="startmoveenemyin"
            temppx = enemyx[currentenemy]
            temppy = enemyy[currentenemy]
            state = "moveenemyin"             
        End If
        If state="moveenemyin"
            For Local i=0 Until 3
                Local an:Int=getangle(    enemyattackx,enemyattacky,
                                        enemyx[currentenemy],
                                        enemyy[currentenemy])
                enemyx[currentenemy] += Cos(an)
                enemyy[currentenemy] += Sin(an)
                If rectsoverlap(    enemyx[currentenemy]-3,
                                    enemyy[currentenemy]-3,
                                    6,6,
                                    enemyattackx-3,
                                    enemyattacky-3,
                                    6,6)=True                                                                    
                    enemyx[currentenemy] = enemyattackx
                    enemyy[currentenemy] = enemyattacky
                    state="enemydobattle"
                End If
            Next
        End If
        If state="moveenemyback"
            For Local i=0 Until 3
                Local an:Int=getangle(    temppx,temppy,
                                        enemyx[currentenemy],
                                        enemyy[currentenemy])
                enemyx[currentenemy] += Cos(an)
                enemyy[currentenemy] += Sin(an)
                If rectsoverlap(    enemyx[currentenemy]-3,
                                    enemyy[currentenemy]-3,
                                    6,6,
                                    temppx-3,temppy-3,
                                    6,6)=True
                    enemyx[currentenemy] = temppx
                    enemyy[currentenemy] = temppy
                    state="nextenemymove"
                End If
            Next            
        End If
        If state="enemydobattle"
            ' find target
            Local exitloop:Bool=False
            Local target:Int=0
            While exitloop=False
                target=Rnd(numplayers)
                If playerh[target] > 0
                    exitloop = True
                End If
            Wend
            'do the hit
            Local points:Int
            points = enemya[currentenemy]-playerd[target]
            If points<=0 Then points = Rnd(1,3)
            playerh[target]-=points
            myeffect.AddLast(New effect(    points+" Hit",
                                            playerx[target],
                                            playery[target]))
            ' see if all players are dead
            Local playeralive:Bool=False
            For Local i=0 Until numplayers
                If playerh[i] >0 Then playeralive=True
            Next
            state="moveenemyback"
            If playeralive=False
                state="nothing"
                Return
            End If
        End If
        If state="playerdobattle"
            ' find target
            Local exitloop:Bool=False
            Local target:Int=0
            While exitloop=False
                target=Rnd(numenemies)
                If enemyh[target] > 0
                    exitloop = True
                End If
            Wend
            'do the hit
            Local points:Int
            points = playera[currentplayer]-enemyd[target]
            If points<=0 Then points = Rnd(1,3)
            enemyh[target]-=points
            myeffect.AddLast(New effect(    points+" Hit",
                                            enemyx[target],
                                            enemyy[target]))            
            ' see if all players are dead
            Local enemyalive:Bool=False
            For Local i=0 Until numenemies
                If enemyh[i] >0 Then enemyalive=True
            Next
            state="moveplayerback"
            If enemyalive=False
                state="nothing"
                Return
            End If
        End If
        
        If state="nextenemymove"            
            Local exitloop:Bool=False
            While exitloop = False
                currentenemy+=1
                If currentenemy>=numenemies
                    state="nextplayermove"
                    currentplayer=-1
                    currentenemy=0
                    Return
                Else
                    If enemyh[currentenemy]>0
                        exitloop=True
                    End If
                End If                
            Wend

            state="startmoveenemyin"
        End If

        If state="nextplayermove"
            Local exitloop:Bool=False
            While exitloop = False
                currentplayer+=1
                If currentplayer>=numplayers
                    state="nextenemymove"
                    currentplayer=0
                    currentenemy=-1
                    Return
                Else
                    If playerh[currentplayer]>0
                        exitloop = True
                    End If
                End If
            Wend                
            state="startmoveplayerin"
        End If
    End Method
    Method draw()
        SetColor 255,255,255
        drawplayers()
        drawenemies()
    End Method
    Method drawplayers()
        For Local i:Int = 0 Until numplayers
            If playerh[i] > 0
                DrawRect playerx[i],playery[i],32,32
            End If
        Next
    End Method    
    Method drawenemies()
        For Local i:Int = 0 Until numenemies
            If enemyh[i] > 0
                DrawRect enemyx[i],enemyy[i],32,32
            End If
        Next
    End Method    
    Method setstats()
        ' here you need to put the stats in
        For Local i=0 Until numplayers
            playerh[i] = Rnd(15,30)
            playera[i] = Rnd(10,30)
            playerd[i] = Rnd(5,15)
        Next
        For Local i=0 Until numenemies
            enemyh[i] = Rnd(10,20)
            enemya[i] = Rnd(10,20)
            enemyd[i] = Rnd(5,15)
        Next
    End Method
    Method setpositions()
        If numplayers = 1
            playerx[0] = 80
            playery[0] = 220-16
        End If
        If numplayers = 2
            playerx[0] = 80
            playery[0] = 220-64
            playerx[1] = 80
            playery[1] = 220+64
        End If
        If numplayers = 3
            playerx[0] = 80
            playery[0] = 220-128
            playerx[1] = 80
            playery[1] = 220
            playerx[2] = 80
            playery[2] = 220+128
        End If
        If numplayers = 4
            playerx[0] = 80
            playery[0] = 220-128
            playerx[1] = 80
            playery[1] = 220-32
            playerx[2] = 80
            playery[2] = 220+64
            playerx[3] = 80
            playery[3] = 220+164
        End If        

        If numenemies = 1
            enemyx[0] = 480
            enemyy[0] = 220-16
        End If
        If numenemies = 2
            enemyx[0] = 480
            enemyy[0] = 220-64
            enemyx[1] = 480
            enemyy[1] = 220+64
        End If
        If numenemies = 3
            enemyx[0] = 480
            enemyy[0] = 220-128
            enemyx[1] = 480
            enemyy[1] = 220
            enemyx[2] = 480
            enemyy[2] = 220+128
        End If
        If numenemies = 4
            enemyx[0] = 480
            enemyy[0] = 220-128
            enemyx[1] = 480
            enemyy[1] = 220-32
            enemyx[2] = 480
            enemyy[2] = 220+64
            enemyx[3] = 480
            enemyy[3] = 220+164
        End If                
    End Method    
    Method getangle:Int(x1:Int,y1:Int,x2:Int,y2:Int)
        Return ATan2(y1-y2, x1-x2)
    End Method
    Method rectsoverlap:Bool(    x1:Int, y1:Int, w1:Int, 
                                h1:Int, x2:Int, y2:Int, 
                                w2:Int, h2:Int)
        If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
        If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
        Return True
    End Method
End Class

Class effect
    Field x:Float
    Field y:Float
    Field incy:Float
    Field t:String
    Field delete:Bool=False
    Method New(t:String,x:Int,y:Int)
        Self.t = t
        Self.x = x
        Self.y = y
    End Method
    Method update()
        incy+=0.05
        y-=incy
        If incy>3 Then delete = True
    End Method
    Method draw()
        SetColor 255,0,0
        DrawText t,x,y
    End Method
End Class

Global mybs:battlescreen = New battlescreen()
Global myeffect:List<effect> = New List<effect>

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
        mybs.numenemies = Rnd(1,5) 
        mybs.numplayers = Rnd(1,5)
        mybs.setpositions
        mybs.setstats
    End Method
    Method OnUpdate()
        mybs.update
        If mybs.state="nothing"
            mybs.numenemies = Rnd(1,5)
            mybs.numplayers = Rnd(1,5)
            mybs.setpositions
            mybs.setstats
            mybs.currentenemy = 0
            mybs.currentplayer=0
            mybs.state="startmoveenemyin"
        End If
        For Local i:=Eachin myeffect
            i.update
        Next
        For Local i:=Eachin myeffect
            If i.delete = True Then myeffect.Remove i
        Next
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "RPG Battle screen.",0,0
        mybs.draw
        For Local i:=Eachin myeffect
            i.draw
        Next
    End Method
End Class


Function Main()
    New MyGame()
End Function

Wednesday, July 29, 2015

Monkey-X - RPG - Simple Inventory screen like diablo - code example


Here a short example of how to do a inventory screen. Items can be picked up and moved around. press i or press on the inventory button for the screen. Escape exits the inventory screen.

Import mojo

Class player
    Field x:Int=50,y:Int=50
    Field w:Int=48,h:Int=48
    Field level:Int=1
    Field currentlevel:Int=0
    Field nextlevel:Int=100
    Field inventory:Int[9][]
    Method New()
         For Local i = 0 Until 9
            inventory[i] = New Int[7]
        Next
        ' sword 1 (takes 3 inventory slots
        ' 3 vertical
        inventory[0][0] = 1
        inventory[0][1] = 1
        inventory[0][2] = 1
        ' healing potion 2
        ' takes one inventory slot
        inventory[1][0] = 2
        ' add more items here (every item 1 
        ' unique number. 
    End Method
    Method update()
        ' movement by input
        Local nx:Int=x,ny:Int=y
        For Local i:Int = 0 Until 4
            If KeyDown(KEY_LEFT)
                nx-=1
            End If
            If KeyDown(KEY_RIGHT)
                nx+=1
            End If
            If KeyDown(KEY_UP)
                ny-=1
            End If
            If KeyDown(KEY_DOWN)
                ny+=1
            End If
            If nx > 0 And nx < 640-w Then x = nx
            If ny > 16 And ny <(480-48)-16 Then y = ny
        Next
    End Method
    Method draw()
        SetColor 255,0,0
        DrawRect x,y,w,h
    End Method
    Method rectsoverlap:Bool(    x1:Int, y1:Int, w1:Int, 
                                h1:Int, x2:Int, y2:Int, 
                                w2:Int, h2:Int)
        If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
        If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
        Return True
    End Method     
End Class

Class inventory
    Field minimized:Bool=True
    Field itemmouse:Int=0
    ' button that says inventory
    Field invbuttonx:Int=10
    Field invbuttony:Int=480-32
    Field invbuttonw:Int=96
    Field invbuttonh:Int=16
    Field invbuttont:String="Inventory"
    ' inventory things
    Field invwindowx:Int=0
    Field invwindowy:Int=16
    Field invwindowh:Int=480-32
    Field invwindoww:Int=320
    Field invwindowt:String="Player Inventory"
    Method update()
        ' Minimized button <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        If minimized = True Then
            If rectsoverlap(    MouseX(),MouseY(),
                                1,1,
                                invbuttonx,
                                invbuttony,
                                invbuttonw,
                                invbuttonh) = True And
                                MouseDown(MOUSE_LEFT) = True
                minimized = False
                Return
            End If
            If KeyHit(KEY_I) = True
                minimized = False
                Return
            End If
        End If
        ' Inventory screen <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        If minimized = False
            If KeyDown(KEY_ESCAPE) = True Or
                            KeyHit(KEY_I) = True
                minimized = True
                Return
            End If
            If MouseDown(MOUSE_LEFT) = True
                If itemmouse=0
                    If itemundermouse() > 0
                        itemmouse=itemundermouse()
                        Return
                    End If
                End If
            End If
        End If
        ' here you drop the item
        'in the inventory screen (manage)
        If MouseDown(MOUSE_LEFT) = False
            If itemmouse > 0
                moveiteminventory()
                itemmouse = 0
            End If
        End If
    End Method
    Method moveiteminventory()
        Local x:Int=(MouseX()-16)/32
        Local y:Int=(MouseY()-32)/32
        If x<0 Or x>8 Then Return
        If y<0 Or y>6 Then Return
        
        Select itemmouse
            Case 1 ' do not drop outside window
                    ' and can drop on same sword
                    '                      
                If y>7-3 Then Return
                For Local i:Int=0 Until 3
                    If myplayer.inventory[x][y+i]>0 And
                        myplayer.inventory[x][y+i] <> itemmouse Then 
                        Return
                    End If
                Next
            Case 2 ' drop on a free slot
                If myplayer.inventory[x][y]<>0 Then Return
        End Select
        ' erase all of this item
        For Local y:Int=0 Until 7
        For Local x:Int=0 Until 9
            If myplayer.inventory[x][y] = itemmouse
                myplayer.inventory[x][y] = 0
            End If
        Next
        Next
        ' drop the item here
        Select itemmouse
            Case 1 ' sword 3 vertical
                myplayer.inventory[x][y] = itemmouse
                myplayer.inventory[x][y+1] = itemmouse
                myplayer.inventory[x][y+2] = itemmouse
            Case 2 ' potion 1 slot
                myplayer.inventory[x][y] = itemmouse
        End Select
    End Method
    Method itemundermouse:Int()
        For Local y:Int = 0 Until 7
        For Local x:Int = 0 Until 9
            If rectsoverlap(MouseX(),MouseY(),
                            1,1,
                            x*32+16,
                            y*32+32,
                            32,32) = True
                If myplayer.inventory[x][y] > 0
                    Return myplayer.inventory[x][y]
                End If
            End If
        Next
        Next
        Return 0
    End Method
    Method draw()
        If minimized = True Then
            drawbutton(    invbuttont,
                        invbuttonx,
                        invbuttony,
                        invbuttonw,
                        invbuttonh)
        End If
        If minimized = False
            drawwindow(    invwindowt,
                        invwindowx,
                        invwindowy,
                        invwindoww,
                        invwindowh)
            ' draw the intemscreen
            drawitems    
            If itemmouse>0
                Select itemmouse
                    Case 1
                        SetColor 150,150,150
                        DrawRect     MouseX(),MouseY(),
                                    32,32*3
                    Case 2
                        SetColor 255,0,0
                        DrawRect    MouseX(),MouseY(),
                                    32,32
                End Select
            End If                        
        End If
    End Method
    Method drawitems()        
        For Local y:Int = 0 Until 7
        For Local x:Int = 0 Until 9
            If myplayer.inventory[x][y] = 0            
            SetColor 0,0,0
            DrawRect x*32+16,y*32+32,31,31            
            Else
            Select myplayer.inventory[x][y]            
                Case 1;SetColor 55,55,55
                Case 2;SetColor 255,0,0
            End Select
            DrawRect x*32+16,y*32+32,32,32
            End If            
        Next
        Next
    End Method
    Method drawbutton(t:String,x:Int,y:Int,w:Int,h:Int)
        SetColor 150,150,150
        DrawRect x,y,w,h
        SetColor 255,255,255
        DrawLine x,y,x+w,y
        DrawLine x,y,x,y+h
        SetColor 20,20,20
        DrawLine x+1,y+h,x+w,y+h
        DrawLine x+w,y+1,x+w,y+h
        SetColor 255,255,255
        DrawText t,x+w/2,y+h/2,.5,.5
    End Method
    Method drawwindow(t:String,x:Int,y:Int,w:Int,h:Int)
        SetColor 150,150,150
        DrawRect x,y,w,h
        SetColor 255,255,255
        DrawLine x,y,x+w,y
        DrawLine x,y,x,y+h
        SetColor 20,20,20
        DrawLine x+1,y+h,x+w,y+h
        DrawLine x+w,y+1,x+w,y+h
        SetColor 255,255,255
        DrawText t,x+w/2,y+2,.5,0
    End Method
    Method rectsoverlap:Bool(      x1:Int, y1:Int, w1:Int, 
                                h1:Int, x2:Int, y2:Int, 
                                w2:Int, h2:Int)
        If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
        If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
        Return True
    End Method
End Class

Global myplayer:player = New player()
Global myinventory:inventory = New inventory()

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        myplayer.update
        myinventory.update
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Rpg Inventory - Use Mouse to move items around..",0,0
        DrawText "Press i and esc for inventory screen on/off",320,480-16
        myplayer.draw
        myinventory.draw
    End Method
End Class


Function Main()
    New MyGame()
End Function

Sunday, July 26, 2015

Monkey-X - Rpg - Leveling with XP - code example.


Here a example of how to level up a player/character by adding xp. The required level is increased every level increase.

Import mojo

Class player
    Field x:Int=50,y:Int=50
    Field w:Int=48,h:Int=48
    Field level:Int=1
    Field currentlevel:Int=0
    Field nextlevel:Int=100
    Method update()
        ' movement by input
        Local nx:Int=x,ny:Int=y
        For Local i:Int = 0 Until 4
            If KeyDown(KEY_LEFT)
                nx-=1
            End If
            If KeyDown(KEY_RIGHT)
                nx+=1
            End If
            If KeyDown(KEY_UP)
                ny-=1
            End If
            If KeyDown(KEY_DOWN)
                ny+=1
            End If
            If nx > 0 And nx < 640-w Then x = nx
            If ny > 16 And ny <(480-48)-16 Then y = ny
        Next
        ' collision with enemies
        For Local i:=Eachin myenemies
            If rectsoverlap(x,y,w,h,i.x,i.y,i.w,i.h)
                i.delete = True
                Local p:Int=Rnd(5,15)
                myeffect.AddLast(New effect(p+"XP",i.x,i.y))
                currentlevel+=p
            End If
        Next
        ' leveling up
        If currentlevel > nextlevel
            currentlevel=currentlevel-nextlevel
            level+=1            
            nextlevel=(nextlevel*1.5)
        End If
    End Method
    Method draw()
        SetColor 255,0,0
        DrawRect x,y,w,h
    End Method
    Method rectsoverlap:Bool(    x1:Int, y1:Int, w1:Int, 
                                h1:Int, x2:Int, y2:Int, 
                                w2:Int, h2:Int)
        If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
        If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
        Return True
    End Method     
End Class

Class enemy
    Field x:Int,y:Int
    Field w:Int=32,h:Int=32
    Field delete:Bool=False
    Method New()
        Local exitloop:Bool=False
        Local x1:Int,y1:Int
        While exitloop = False
            x1 = Rnd(50,500)
            y1 = Rnd(32,400)
            exitloop = True
            For Local i:=Eachin myenemies
                If rectsoverlap(x1,y1,50,50,i.x-10,
                                i.y-10,50,50)
                    exitloop = False
                End If
            Next
        Wend
        x = x1
        y = y1
    End Method
    Method update()
    End Method
    Method draw()
        SetColor 255,255,0
        DrawRect x,y,w,h
    End Method
    Method rectsoverlap:Bool(    x1:Int, y1:Int, w1:Int, 
                                h1:Int, x2:Int, y2:Int, 
                                w2:Int, h2:Int)
        If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False
        If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False
        Return True
    End Method     
End Class


Class effect
    Field x:Int,y:float
    Field t:String,incy:Float
    Field delete:Bool=False
    Method New(t:String,x:Int,y:Int)
        Self.x = x
        Self.y = y
        Self.t = t
    End Method
    Method update()
        incy+=0.05
        y-=incy
        If incy>3 Then delete = True
    End Method
    Method draw()
        SetColor 255,255,255
        DrawText t,x,y
    End Method
End Class

Global myplayer:player = New player()
Global myenemies:List<enemy> = New List<enemy>
Global myeffect:List<effect> = New List<effect>

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
        For Local i=0 Until 10
            myenemies.AddLast(New enemy())
        Next
    End Method
    Method OnUpdate()
        myplayer.update
        ' update the enemies remove/count/repopulate
        For Local i:=Eachin myenemies
            If i.delete = True Then myenemies.Remove i
        Next
        Local enemiesgone:Bool=True
        For Local i:=Eachin myenemies
            enemiesgone = False
        Next
        If enemiesgone = True Then
            For Local i=0 Until 10
                myenemies.AddLast(New enemy())
            Next
        End If
        ' the xp text effect
        For Local i:=Eachin myeffect
            i.update
        Next
        'remove if needed
        For Local i:=Eachin myeffect
            If i.delete = True Then myeffect.Remove i
        Next
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Rpg player leveling/xp. Cursors to move.",0,0
        DrawText "Level : "+myplayer.level+" | Next level : " +
                 myplayer.currentlevel + " of "+myplayer.nextlevel,
                 100,460 
        For Local i:=Eachin myenemies
            i.draw
        Next
        myplayer.draw
        'draw the texteffect
        For Local i:=Eachin myeffect
            i.draw
        Next
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Rpg - Player fighting a enemy - code example


Here code that shows a player fighting a enemy. You and he keep respawning but with different stats.

Import mojo

Class battle
    Field state:String="playerturn"
    Field nextstate:String
    Field timeout:Int
    Method update()
        If state="playerturn"
            timeout = Millisecs()+3000
            Local hitval:Int
            hitval=myplayer.attack-myenemy.defence
            If hitval<1 Then hitval = Rnd(1,3)
            myenemy.health-=hitval
            myeffect.AddLast(New effect(hitval,myenemy.x+48/2-4,myenemy.y))
            If myenemy.health < 1
                mybattleinfo.scrollloc = 1
                mybattleinfo.message = "Player killed the enemy. New enemy appears.."
                mybattleinfo.showmessage = ""
                myenemy.attack = Rnd(5,15)
                myenemy.defence = Rnd(5,15)
                myenemy.health = Rnd(5,25)
                state = "wait"
                nextstate = "playerturn"
            Else
                mybattleinfo.scrollloc = 1
                mybattleinfo.message = "Player hit enemy causing "+hitval+" damage to health."
                mybattleinfo.showmessage=""
                state="wait"
                nextstate = "enemyturn"
            End If
        End If
        If state="enemyturn"
            timeout=Millisecs()+3000
            Local hitval:Int
            hitval=myenemy.attack-myplayer.defence
            If hitval<1 Then hitval = Rnd(1,3)
            myplayer.health-=hitval
            myeffect.AddLast(New effect(hitval,myplayer.x+48/2-4,myplayer.y))            
            If myplayer.health < 1
                mybattleinfo.scrollloc = 1
                mybattleinfo.message = "You have been killed in battle. You reappear."
                mybattleinfo.showmessage=""
                myplayer.attack = Rnd(10,25)
                myplayer.defence = Rnd(5,15)
                myplayer.health = Rnd(10,50)
                state="wait"
                nextstate="playerturn"
                Else
                mybattleinfo.scrollloc = 1
                mybattleinfo.message = "Enemy hit player causing "+hitval+" damage to health."
                mybattleinfo.showmessage=""
                state="wait"
                nextstate = "playerturn"
            End If
        End If
        If state="wait"
            If Millisecs() > timeout Then
                state=nextstate
            End If
        End If
    End Method
    Method draw()
    End Method
End Class

Class battleinfo
    Field x:Int=32,y:Int=32
    Field message:String
    Field showmessage:String
    Field scrolldelay:Int
    Field scrollloc:Int
    Method update()
        If Millisecs() > scrolldelay
            scrolldelay = Millisecs()+50
            If showmessage.Length < message.Length
                scrollloc+=1
                    Local dt:String=""
                Local sp:Int=0
                For Local i=0 Until scrollloc
                       dt+=String.FromChar(message[sp])            
                      sp+=1
'                    If sp>=stext.Length Then sp=0
                Next            
                showmessage=dt
            End If
        End If
    End Method
    Method draw()
        SetColor 255,255,255
        DrawText showmessage,x,y
    End Method
End Class

Class player
    Field x:Int=200,y:Int=200
    Field w:Int=48,h:Int=48
    Field attack:Int=10,defence:Int=5,health:Int=42
    Method update()
    End Method
    Method draw()
        SetColor 200,0,0
        DrawRect x,y,w,h
        SetColor 255,255,255
        DrawText "A:"+attack,x+2,y+2
        DrawText "D:"+defence,x+2,y+12
        DrawText "H:"+health,x+2,y+22                
    End Method
End Class

Class enemy
    Field x:Int=320,y:Int=200
    Field w:Int=48,h:Int=48
    Field attack:Int=6,defence:Int=4,health:Int=12
    Method update()
    End Method
    Method draw()
        SetColor 200,200,0
        DrawRect x,y,w,h
        SetColor 255,255,255
        DrawText "A:"+attack,x+2,y+2
        DrawText "D:"+defence,x+2,y+12
        DrawText "H:"+health,x+2,y+22                    
    End Method
End Class

Class effect
    Field x:Int,y:Float,incy:Float
    Field m:String,delete:Bool=False
    Method New(m:String,x:Int,y:Int)
        Self.m = m
        Self.x = x
        Self.y = y
        incy = 0
    End Method
    Method update()
        y-=incy
        incy+=.05
        If incy > 3 Then delete = True
    End Method
    Method draw()
        SetColor 255,255,255
        DrawText m,x,y
    End Method
End Class

Global myplayer:player = New player()
Global myenemy:enemy = New enemy()
Global mybattle:battle = New battle()
Global mybattleinfo:battleinfo = New battleinfo()
Global myeffect:List<effect> = New List<effect>

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        myplayer.update
        myenemy.update
        mybattle.update
        mybattleinfo.update
        For Local i:=Eachin myeffect
            i.update
        Next
        For Local i:=Eachin myeffect
            If i.delete = True Then myeffect.Remove i
        Next
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Rpg player and ai fighting.",0,0
        myplayer.draw
        myenemy.draw
        mybattle.draw
        mybattleinfo.draw
        For Local i:=Eachin myeffect
            i.draw
        Next
    End Method
End Class


Function Main()
    New MyGame()
End Function

Monkey-X - Error command example


Here a example of how to stop the Monkey program and show a notify window that can show  some information if needed.


Import mojo


Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        Error "Program stopped here...."
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255
        DrawText "Error Message example.",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Wednesday, July 22, 2015

Monkey-X - RPG Attack/Defence code example



Here you can move the red cube with the cursors and move into the yellow blocks. You then attack them and you see the damage done to their health. The attack defence and health is drawn in each block.

' Example of rpg attack/defence'
' Hit value made on line 117

Import mojo

Class texteffect
    Field x:Float,y:Float
    Field txt:String
    Field incy:Float=0
    Field delete:Bool=False
    Method New(txt:String,x:Int,y:Int)
        Self.x = x
        Self.y = y
        Self.txt = txt
    End Method
    Method update()
        incy+=.1
        y-=incy
        If y<0 Then delete=True
        For Local i:=Eachin tef
            If i.delete = True Then tef.Remove i
        Next
    End Method
    Method draw()
        SetColor 255,255,255
        DrawText txt,x,y
    End Method
End Class

Class bubba
    Field x:Int,y:Int
    Field tilewidth:Int=32
    Field tileheight:Int=32
    Field attack:Int
    Field defence:Int
    Field health:Int
    Field delete:Bool=False
    Method New(x:Int,y:Int)
        ' first see if the place is already taken
        Local exitloop:Bool = False
        While exitloop = False
            exitloop = True
            For Local i:=Eachin bub            
                If i.x = x
                If i.y = y
                    exitloop = False
                End If
                End If
            Next
            If exitloop = False
                x = Rnd(4,16)
                y = Rnd(4,10)
            End If
        Wend
        ' set the thing up
        Self.x = x
        Self.y = y
        defence = Rnd(1,7)
        attack = Rnd(1,5)
        health = Rnd(10,30)
    End Method
    Method update()
    End Method
    Method draw()
        SetColor 255,255,0
        DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight
        SetColor 255,255,255
        DrawText "A:"+attack,x*tilewidth+2,y*tileheight+1
        DrawText "D:"+defence,x*tilewidth+2,y*tileheight+9
        DrawText "H:"+health,x*tilewidth+2,y*tileheight+17
    End Method
End Class

Class player
    Field x:Int,y:Int
    Field tilewidth:Int=32
    Field tileheight:Int=32
    Field keydelay:Int
    Field attack:Int = 10
    Field defence:Int = 5
    Field health:Int=99
    Method New(x:Int,y:Int)
        Self.x = x
        Self.y = y
    End Method
    Method update()
        Local nx:Int=x
        Local ny:Int=y
        If KeyDown(KEY_RIGHT)
            If keydelay< Millisecs()
                nx+=1
                keydelay=Millisecs()+300
            End If
        End If
        If KeyDown(KEY_LEFT)
            If keydelay< Millisecs()
                nx-=1
                keydelay=Millisecs()+300
            End If
        End If
        If KeyDown(KEY_UP)
            If keydelay< Millisecs()
                ny-=1
                keydelay=Millisecs()+300
            End If
        End If
        If KeyDown(KEY_DOWN)
            If keydelay< Millisecs()
                ny+=1
                keydelay=Millisecs()+300
            End If
        End If    
        If bubbahere(nx,ny) = True
            Local hit:Int=0
            For Local i:=Eachin bub
                If i.x = nx And i.y = ny
                    hit = Rnd(attack)-Rnd(i.defence)
                    If hit<1 Then hit = Rnd(1,3)                    
                    i.health -= hit
                    tef.AddLast(New texteffect(hit,i.x*32,i.y*32))
                    If i.health < 0 Then i.delete=True
                End If
            Next
            For Local i:=Eachin bub
                If i.delete = True Then bub.Remove i
            Next
        End If
        If mymap.map[nx][ny] = 0            
        If bubbahere(nx,ny) = False
            x = nx
            y = ny
        End If
        End If
    End Method
    Method bubbahere(x:Int,y:Int)
        For Local i:= Eachin bub
            If i.x = x And i.y = y Then Return True
        Next
    End Method
    Method drawplayer()
        SetColor 255,0,0
        DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight
        SetColor 255,255,255
        DrawText "A:"+attack,x*tilewidth+2,y*tileheight+1
        DrawText "D:"+defence,x*tilewidth+2,y*tileheight+9
        DrawText "H:"+health,x*tilewidth+2,y*tileheight+17
    End Method
End Class

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
        For Local i=0 Until mapwidth
            map[i][0] = 1
            map[i][14] = 1
        Next
        For Local i=0 Until mapheight
            map[0][i] = 1
            map[mapwidth-1][i] = 1
        Next
    End Method
    Method update()
        Local x1 = MouseX() / tilewidth
        Local y1 = MouseY() / tileheight
    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,22,32,32)
Global myplayer:player = New player(1,10)
Global bub:List<bubba> = New List<bubba>
Global tef:List<texteffect> = New List<texteffect>

Class MyGame Extends App
    Method OnCreate()
        SetUpdateRate(60)
        For Local i=0 Until 10
            bub.AddLast(New bubba(Rnd(4,16),Rnd(4,10)))
        Next
    End Method
    Method OnUpdate()
        For Local i:=Eachin tef
            i.update
        Next
        For Local i:=Eachin bub
            i.update
        Next            
        mymap.update        
        myplayer.update  
    End Method
    Method OnRender()
        Cls 0,0,0 
        mymap.drawmap
        For Local i:=Eachin bub
            i.draw
        Next                    
        myplayer.drawplayer
        For Local i:=Eachin tef
            i.draw
        Next
        SetColor 255,255,255
        DrawText "Cursors to move the red block. RPG attack/defence example",0,0
    End Method
End Class


Function Main()
    New MyGame()
End Function

Part of RPG (Earth bound) battle screen - code example


Here a short example of how to do a rpg battlescreen. You can only bash and the enemy does not fight back.


Import mojo

Class monster1
    Field name:String="Bubba"
    Field hp:Int=5
    Field pp:Int=7
    Field welcomemessage:String="Here I am to kick your ass.."
End Class

Class player
    Field name:String="Player"
    Field hp:Int=20
    Field pp:Int=10
End Class

Class battlescreen
    Field state:String="preparemonsterintro"
    Field nextstate:String
    Field selectindex:Int=0
    Field selecttext:String[]=["Bash","PSI","Goods","Defend","Auto Fight","Run Away"]
    Field keydowndelay:Int=0
    Field messagedelay:Int
    Field message:String
    Field damage:Int
    Method update()
        If state="selectaction"
            updateselect()
        End If
        If state="afterbash"
            If m1.hp<0
                messagedelay=100
                message="You wasted the monster."
                state="wait"
                nextstate="preparemonsterintro"
            End If
            If m1.hp>0
                state="selectaction"
            End If
        End If
        If state="wait"
            messagedelay-=1
            If messagedelay<0
                state=nextstate
            End If
        End If
        If state="bash"
            damage=Rnd(3)+2
            message="You hit the monster with "+damage+" damage."
            m1.hp-=damage
            messagedelay=50
            state="wait"
            nextstate="afterbash"
        End If
        If state="preparemonsterintro"
            state="monsterintro"
            messagedelay=100            
            m1.hp=Rnd(10)+5
            m1.pp=Rnd(10)+5
        End If
        If state="monsterintro"
            messagedelay-=1
            If messagedelay<0
                state="selectaction"
            End If
        End If
    End Method
    Method draw()
        If state="wait"
            drawmessage(message)            
            drawplayerinfo()            
        End If
        If state="monsterintro"
            drawmessage(m1.welcomemessage)            
            drawplayerinfo()
        End If
        If state="selectaction"
            drawselect()
            drawplayerinfo()
        End If
    End Method
    Method drawmessage(m:String)
        SetColor 255,255,255
        DrawLine 10,10,500,10
        DrawLine 10,10,10,100
        DrawLine 10,100,500,100
        DrawLine 500,10,500,100
        PushMatrix
        Scale 2.2,2.2
        DrawText m,15/2.2,15/2.2
        PopMatrix
    End Method
    Method drawselect()
        SetColor 255,255,255
        DrawLine 10,10,500,10
        DrawLine 10,10,10,100
        DrawLine 10,100,500,100
        DrawLine 500,10,500,100
        SetColor 0,0,0
        DrawRect 32,5,96,15
        SetColor 255,255,255
        DrawText p.name,32,0
        Local in:Int=0
        For Local x=0 To 2
        For Local y=0 To 1
            PushMatrix()
            Scale 2.2,2.2
            DrawText selecttext[in],(x*150+32)/2.2,(y*50+15)/2.2
            PopMatrix()
            If selectindex = in
                DrawRect x*150+20,y*50+25,10,10
            End If
            in+=1
        Next
        Next
    End Method
    Method drawplayerinfo()
        ' Here the player info is drawn
        SetColor 255,255,255
        DrawLine 320-50,300,320+50,300
        DrawLine 320-50,300,320-50,425
        DrawLine 320-50,425,320+50,425
        DrawLine 320+50,300,320+50,425
        PushMatrix()
        Scale 2.2,2.2
        DrawText p.name,320/2.2,320/2.2,0.5
        DrawText "HP",(320-40)/2.2,360/2.2
        DrawText p.hp,320/2.2,360/2.2
        DrawText "PP",(320-40)/2.2,390/2.2
        DrawText p.pp,320/2.2,390/2.2
        PopMatrix()        
    End Method
    Method updateselect()
        ' Here the selection for the player is updated
        If keydowndelay>0 Then keydowndelay-=1
        If keydowndelay>0 Then Return
        If KeyDown(KEY_RIGHT)
            If selectindex+2 < 6
                selectindex+=2
                keydowndelay=10                
            End If
        End If
        If KeyDown(KEY_LEFT)
            If selectindex-2>=0
                selectindex-=2
                keydowndelay=10
            End If
        End If
        If KeyDown(KEY_DOWN)
            If selectindex<5
                selectindex+=1
                keydowndelay=10
            End If
        End If
        If KeyDown(KEY_UP)
            If selectindex>0
                selectindex-=1
                keydowndelay=10
            End If
        End If
        If KeyDown(KEY_ENTER)
            ' If bash option selected
            If selectindex = 0
                state="bash"
            End If
        End If
    End Method
End Class

Global p:player = New player
Global bs:battlescreen = New battlescreen
Global m1:monster1 = New monster1

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()
        bs.update
    End Method
    Method OnRender()
        Cls 0,0,0 
        SetColor 255,255,255        
        bs.draw
        SetColor 255,255,255
        DrawText "Use cursors and return key...",320,480-32
    End Method
End Class

Function Main()
    New MyGame()
End Function