Author Topic: Tilemap Based Movement Engine  (Read 5571 times)

Offline PeeJay

  • Mr. Polyvector
  • ***
  • Posts: 244
    • View Profile
    • PeeJays Remakes
Tilemap Based Movement Engine
« on: 2007-Dec-27 »
Another "useful" chunk of code from my BlitzBasic days - this demonstrates how to move a player around a scrolling tilemap, and how to move the player to the edge of the tilemap at the periphery.

Code: GLBasic [Select]
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
//                                                                      //
// Project: Tile Based Movement Engine Example for GLBasic              //
//                                                                      //
// (C)opyright PeeJay December 13th 2007      www.peejays-remakes.co.uk //
//                                                                      //
// Code is free to use for FREEWARE projects only, though credit would  //
// still be welcomed if you decide to use it                            //
//                                                                      //
// Please contact me through my website for conditions on using this    //
// code in shareware, commercial, or other revenue generating projects  //
//                                                                      //
// This code shows an example of how a player can move around a         //
// scrolling tilemap, and how the player will move towards the edges of //
// the screen when approaching the edge of the map                      //
//                                                                      //
// Use keyboard cursor keys to move - Esc quits                         //
//                                                                      //
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//

SETSCREEN 640,480,0 // 640x480 Window
LIMITFPS 60 // at 60 frames per second

GLOBAL mapx,mapy
GLOBAL px,py
GLOBAL xdir,ydir
GLOBAL tilesize=32
GLOBAL speed=4

DIM level[50][50]

LOCAL loop

FOR loop=0 TO 49
        level[0][loop]=1
        level[49][loop]=1
        level[loop][0]=1
        level[loop][49]=1
        level[RND(49)][RND(49)]=1
NEXT

mapx=10
mapy=10
px=mapx*tilesize
py=mapy*tilesize

WHILE TRUE

        FOR loop=1 TO speed

                CheckPlayer()

        NEXT

        DrawScreen()

WEND

END


FUNCTION CheckPlayer:

        LOCAL xdir,ydir

        xdir=KEY(205)-KEY(203)
        ydir=KEY(208)-KEY(200)

        IF WallDetect(px+xdir,py+ydir)=0
                px=px+xdir
                py=py+ydir
                mapx=INTEGER(px/tilesize)
                mapy=INTEGER(py/tilesize)
        ENDIF

ENDFUNCTION

FUNCTION WallDetect: x,y

        LOCAL mx,my,nomove

        mx=INTEGER(x/tilesize)
        my=INTEGER(y/tilesize)
        nomove=0

        IF level[mx][my]=1 THEN nomove=1

        IF MOD(x,tilesize)>0
                IF level[mx+1][my]=1 THEN nomove=1
        ENDIF

        IF MOD(y,tilesize)>0
                IF level[mx][my+1]=1 THEN nomove=1
                IF MOD(x,tilesize)>0
                        IF level[mx+1][my+1]=1 THEN nomove=1
                ENDIF
        ENDIF

        RETURN nomove

ENDFUNCTION

FUNCTION DrawScreen:

        startx=mapx-12
        endx=startx+25

        IF startx<0
                startx=0
                endx=25
        ENDIF

        IF endx>49
                startx=24
                endx=49
        ENDIF

        starty=mapy-12
        endy=starty+25

        IF starty<0
                starty=0
                endy=25
        ENDIF

        IF endy>49
                starty=24
                endy=49
        ENDIF

        IF px<304
                scrx=px
        ELSEIF px>((49*tilesize)-304)
                scrx=304+304-(49*tilesize-px)
        ELSE
                scrx=304
        ENDIF

        IF py<224
                scry=py
        ELSEIF py>((49*tilesize)-224)
                scry=224+224-(49*tilesize-py)
        ELSE
                scry=224
        ENDIF

        FOR loopy=starty TO endy
                FOR loopx=startx TO endx
                        rectx=scrx-px+(loopx*tilesize)
                        recty=scry-py+(loopy*tilesize)
                        IF level[loopx][loopy]=0
                                DRAWRECT rectx,recty,tilesize,tilesize,RGB(0,0,64)
                                DRAWRECT rectx+2,recty+2,tilesize-4,tilesize-4,RGB(0,0,128)
                        ENDIF
                        IF level[loopx][loopy]=1
                                DRAWRECT rectx,recty,tilesize,tilesize,RGB(128,0,0)
                        ENDIF
                NEXT
        NEXT

        DRAWRECT scrx,scry,tilesize,tilesize,RGB(0,128,0)

        SHOWSCREEN

ENDFUNCTION
www.peejays-remakes.co.uk
For games, remakes, and GL Basic Tutorials
Artificial Intelligence is no match for Natural Stupidity

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4144
  • On the shoulders of giants.
    • View Profile
    • My Apps
Tilemap Based Movement Engine
« Reply #1 on: 2007-Dec-28 »
Nice one PeJay :)
I came. I saw. I played.

Offline Quentin

  • Prof. Inline
  • *****
  • Posts: 915
    • View Profile
Tilemap Based Movement Engine
« Reply #2 on: 2007-Dec-28 »
very nice, and easy to understand I think.
Thanks for sharing.

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10695
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Tilemap Based Movement Engine
« Reply #3 on: 2007-Dec-29 »
Oh! This new kid on the block starts to get a valuable resource.

Offline PeeJay

  • Mr. Polyvector
  • ***
  • Posts: 244
    • View Profile
    • PeeJays Remakes
Tilemap Based Movement Engine
« Reply #4 on: 2007-Dec-30 »
I've been coding for a while now, Gernot! ;)

I'm writing loads more useful routines while coding for the compo - I'll post some more snippets soon, including a function to draw bitmapped fonts (it's more useful than it sounds!)
www.peejays-remakes.co.uk
For games, remakes, and GL Basic Tutorials
Artificial Intelligence is no match for Natural Stupidity

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4144
  • On the shoulders of giants.
    • View Profile
    • My Apps
Tilemap Based Movement Engine
« Reply #5 on: 2007-Dec-30 »
I've got a bitmap font running too - uses pretty much the same code I used in my Blitz (inc Max) and PlayBasic games. The basic core of the language is very similar to pretty much all Basic languages really, only the names of the commands have been changed to protect the innocent :P

I just wish there was a proper LoadSpriteAnim command that allowed easy and quick loading of tilemaps/multiple images to put into sprites. :( Gernot...
I came. I saw. I played.

Offline PeeJay

  • Mr. Polyvector
  • ***
  • Posts: 244
    • View Profile
    • PeeJays Remakes
Tilemap Based Movement Engine
« Reply #6 on: 2007-Dec-30 »
There is an easy and quick way, Ian - wait until I publish my bitmapped font routine (where the whole font is in one graphic) and you'll see how easily it can be done ;)
www.peejays-remakes.co.uk
For games, remakes, and GL Basic Tutorials
Artificial Intelligence is no match for Natural Stupidity

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4144
  • On the shoulders of giants.
    • View Profile
    • My Apps
Tilemap Based Movement Engine
« Reply #7 on: 2007-Dec-30 »
I originally tried a GrabSprite routine, but the masking didn't appear to work properly - neither of the mask colours came through. Admittedly I didn't spend a lot of time playing with it - I've been busy with other routines and doing the level editor and getting the game working properly :)

What I actually meant (about LoadSpriteAnim) though is that it should be an automated and included command and not just a function.

[EDIT] Sorted :D

Here's my Bitmap Font function (for fonts 6x9)

Code: GLBasic [Select]
GLOBAL width=6, height=9

LOADSPRITE "gfx/font.png",1000

DRAWRECT 0,0,640,480,RGB(255,0,128)

DRAWSPRITE 1000,0,0

n=1
x=0
y=0

WHILE n<97

GRABSPRITE n,x,y,width,height

n=n+1

x=x+width

IF x>186
 x=0
 y=y+9
ENDIF

WEND


WHILE TRUE

DRAWRECT 0,0,640,480,RGB(255,255,255)

txt(100,100,"Ian Price was here!")

SHOWSCREEN

WEND


// Display bitmap Text
FUNCTION txt: x, y, ss$
 xpos=0

  FOR i=0 TO LEN(ss$)-1
   cr=(ASC(MID$(ss$,i,1))-31)

    DRAWSPRITE cr,x+(xpos*width),y

    // Kern text
    IF cr=42 OR cr=74 THEN x=x-4
    IF cr=9 OR cr=10 OR cr=77 THEN x=x-3
    IF cr=1 OR cr=18 OR cr=75 THEN x=x-2
    IF cr=85 THEN x=x-1

     xpos=xpos+1
  NEXT
ENDFUNCTION
Values relate to sprite image number of individual letters, with a full 96 character font (as seen below).



**** Incidently, this could be used for animated sprites too :D
I came. I saw. I played.

Offline PeeJay

  • Mr. Polyvector
  • ***
  • Posts: 244
    • View Profile
    • PeeJays Remakes
Tilemap Based Movement Engine
« Reply #8 on: 2007-Dec-30 »
Ooooh, that works - mind you, I did it a totally different way, as I couldn't be bothered with all that GrabSprite malarky :) Now posting my code (and I've added a wordwrap facility too - pretty handy for the game I'm working on!)
www.peejays-remakes.co.uk
For games, remakes, and GL Basic Tutorials
Artificial Intelligence is no match for Natural Stupidity

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4144
  • On the shoulders of giants.
    • View Profile
    • My Apps
Tilemap Based Movement Engine
« Reply #9 on: 2007-Dec-30 »
It doesn't matter how you get things to work, as long as they do! :D

I don't suppose for a second that my version is cleaner or greener than anyone elses, but it's mine and it works, so the job's a good one :)
I came. I saw. I played.

Offline PeeJay

  • Mr. Polyvector
  • ***
  • Posts: 244
    • View Profile
    • PeeJays Remakes
Tilemap Based Movement Engine
« Reply #10 on: 2007-Dec-30 »
I couldn't agree more - yours does something mine doesn't - kerning (which is pretty nifty, I must admit!) At some point I might revisit my system, and when I really fancy a headache, tackle word wrap with kerning (as if this game isn't giving me enough headaches :D)
www.peejays-remakes.co.uk
For games, remakes, and GL Basic Tutorials
Artificial Intelligence is no match for Natural Stupidity