Tilemap Based Movement Engine

Previous topic - Next topic

PeeJay

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

Ian Price

I came. I saw. I played.

Quentin

very nice, and easy to understand I think.
Thanks for sharing.

Kitty Hello

Oh! This new kid on the block starts to get a valuable resource.

PeeJay

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

Ian Price

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.

PeeJay

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

Ian Price

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.

PeeJay

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

Ian Price

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.

PeeJay

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