Monday, January 19, 2015

Monkey-X - 2d Scrolling platformer with player and springy's - code example


I was watching a playthrough video of Superfrog and wanted to program a little bit of the game for myself. The part I made was where you can fall down in the map and hit a highjump block and be launched back up.

The code had a big set of characters where the map is stored. The size is 40 by 30 which is also set in the code by constant variables. 1 values are walls and 2 values are jump blocks.

Code below :

Import mojo

Global map:Int[][] = [      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,0,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
                            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ]

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

Class player    
    Field x:Float=32*3
    Field y:Float=32*6
    Field w:Int=32
    Field h:Int=32
    Field incy:Float=0
    Field isjumping:Bool = False
    Method update()
        ' Here the springy is handled
        If isjumping = True
            If incy>0
                If psc(0,1) = True
                    incy=-10
                End If
            End If
        End If
        'Left and Right movement
        If KeyDown(KEY_RIGHT)
            For Local i=0 Until 4 ' move with 4 pixels at a time
                If ptc(1,0) = False
                    x+=1
                End If
            Next
        End If
        If KeyDown(KEY_LEFT)
            For Local i=0 Until 4
                If ptc(-1,0) = False
                    x-=1
                End If
            Next
        End If
        'player gravity part
        'if in the air and not in jump
        If isjumping = False
            If ptc(0,1) = False
                isjumping=True
                incy=0
            End If
        End If
        ' jump
        If KeyDown(KEY_SPACE)
            If isjumping = False
                isjumping = True
                incy=-4
            End If
        End If
        ' if we are in a jump/falling down
        If isjumping=True
            If incy>=0 'if we are going down
                If incy<4 Then incy+=.1
                For Local i=0 Until(incy)
                    If ptc(0,1) = False
                        y+=1
                    Else
                        isjumping = False
                    End If
                Next
            End If
            If incy<0 'if we are going up
                incy+=.1
                For Local i=0 Until Abs(incy)
                    If ptc(0,-1) = False
                        y-=1
                    Else
                        incy=0
                    End If
                Next
            End If
        End If
    End Method
    Method draw()
        SetColor 255,255,0
        DrawRect x,y,w,h
    End Method
End Class

Global p:player = New player

Class MyGame Extends App

    Method OnCreate()
        SetUpdateRate(60)
    End Method
    Method OnUpdate()    
        p.update    
        alignmap
    End Method
    Method OnRender()
        Cls 0,0,0 
        drawmap
        p.draw
        SetColor 0,0,0
        DrawRect 0,0,DeviceWidth(),32
        SetColor 255,255,255
        DrawText "Use Cursor left/right to move, space to jump",0,0
        DrawText "Fall on a red springy to jump higher",0,16
    End Method
End Class

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

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

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

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


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


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

Function Main()
    New MyGame()
End Function

2 comments:

  1. How do I change the square to an image?

    ReplyDelete
  2. Sorry for the late reply. I noticed (you?) asked on the monkeyx forum also and got answered there but the site is going down this month.

    To change from rectangle to image you only need to change the drawrect command to the drawimage command. Be sure to load an image too. I have no loadimage commands on this blog since I could not host data on the google sites.

    ReplyDelete