Hey everyone!
I'm working on a single-screen platformer (ala donkey kong, snow bros., mario bros., etc.) and I was wondering, what is the easiest way to map tiles? I've been trying to do it with arrays, but try as I may, I can't quite wrap my head around it. Since each screen will probably only have around 40 tiles (or less), an external tile-mapping program seems excessive (plus I already tried that and it blew my mind). And if doing tiles with arrays IS the easiest way, is there a tutorial someone could point me to? This stuff is KILLING me!!
Thanks a lot!!
you can try to define a type per tile. Something like
type tile
x
y
image
endtype
and if each level has a max of 40 tiles, and you have... 10 level, try to define omething like
global map[][] as tile
dim map[10][40]
lev=1
for til=0 to 39
drawsprite map[lev][til].image,map[lev][til].x,map[lev][til].y
next
more or less.
Thanks for the quick answer!
I understand it all up to that point. I guess what I don't get is how to define each tile's x,y,image. I'm guessing that you would somehow use dimdata?
Or would you have to do it on an individual basis? i.e.:
map[lev][0].x=100
map[lev][0].y=100
map[lev][0].image=6
map[lev][1].x=132 ..............
Thanks again!
A tile is part of a bitmap, so draw the image portion according to a tile-set value which can be used to select a tile from a set from LOADANIM. 8)
// --------------------------------- //
// Project: tile
// Start: Wednesday, October 13, 2010
// IDE Version: 8.125
// tile scroll demo - matchy's pixel mario
// arrows/spacebar, no collision
TYPE tiles
x
y
width
height
num
ENDTYPE
GLOBAL tile[] AS tiles
GLOBAL map$[],map_color[]
GLOBAL screen_width,screen_height,map_width,map_height,sprite_tile,anim_tile,tile_width,tile_height
GLOBAL player_x,player_y,player_jump,player_x_last,player_y_last
CONSTANT TILE_AIR=0
CONSTANT TILE_GROUND=1
CONSTANT TILE_SHELF=2
CONSTANT TILE_COIN=3
CONSTANT TILE_PLAYER=4
CONSTANT TILE_MONSTER=5
CONSTANT TILE_COUNT=6
CONSTANT KEY_LEFT=203
CONSTANT KEY_RIGHT=205
CONSTANT KEY_SPACE=57
init()
FUNCTION mapinit:
DIM map$[1][1]
map$[0]=".................................................................."
map_width=LEN(map$[0])
map_height=10
REDIM map$[map_width][map_height]
map$[0]=".................................................................."
map$[1]=".................................................................."
map$[2]=".................................................................."
map$[3]=".................................................................."
map$[4]=".................................................................."
map$[5]="....................................................*.*..........."
map$[6]="...................................................-----....===..."
map$[7]=".............................................................=...."
map$[8]="=========.............!..................=======............===..."
map$[9]="=================================================================="
ENDFUNCTION
FUNCTION tilemap: cell$
LOCAL mapcell
SELECT cell$
CASE "."
mapcell=TILE_AIR
CASE "="
mapcell=TILE_GROUND
CASE "-"
mapcell=TILE_SHELF
CASE "*"
mapcell=TILE_COIN
CASE "!"
mapcell=TILE_PLAYER
CASE "#"
mapcell=TILE_MONSTER
DEFAULT
mapcell=TILE_AIR
ENDSELECT
RETURN mapcell
ENDFUNCTION
FUNCTION init:
// SETSCREEN 480,320
GETSCREENSIZE screen_width,screen_height
mapinit() // get the map
tile_width=32
tile_height=32
tileinit() // map the tiles
colorinit()
sprite_tile=spriteinit(TILE_COUNT,tile_width,tile_height)
anim_tile=animinit() // create tileset bitmap
animate()
ENDFUNCTION
FUNCTION animinit:
LOCAL file$,anim
file$=PLATFORMINFO$("DOCUMENTS")+"/temp.png"
SAVESPRITE file$,sprite_tile
anim=GENSPRITE()
LOADANIM file$,anim,tile_width,tile_height
KILLFILE file$
RETURN anim
ENDFUNCTION
FUNCTION tileinit:
LOCAL map_x,map_y,num,cell$
FOR map_y=0 TO map_height-1
FOR map_x=0 TO map_width-1
cell$=MID$(map$[map_y],map_x,1)
num=tilemap(cell$)
IF num=TILE_PLAYER
player_x=map_x*tile_width
player_y=map_y*tile_height
tileadd(map_x*tile_width,map_y*tile_height,TILE_AIR)
ELSE
tileadd(map_x*tile_width,map_y*tile_height,num)
ENDIF
NEXT
NEXT
ENDFUNCTION
FUNCTION tileadd: tile_x,tile_y,num
LOCAL tilecount
tilecount=BOUNDS(tile[],0)
REDIM tile[tilecount+1]
tile[tilecount].x=tile_x
tile[tilecount].y=tile_y
tile[tilecount].width=tile_width
tile[tilecount].height=tile_height
tile[tilecount].num=num
// DEBUG "tile add: "+num+" "+tile_x+","+tile_y+" "+"\n"
ENDFUNCTION
FUNCTION colorinit:
DIM map_color[TILE_COUNT]
map_color[TILE_AIR]= RGB(255,255,255)
map_color[TILE_GROUND]= RGB( 0,128, 0)
map_color[TILE_SHELF]= RGB(128, 64, 0)
map_color[TILE_COIN]= RGB(255,255, 0)
map_color[TILE_PLAYER]= RGB( 16, 0,196)
map_color[TILE_MONSTER]= RGB(196, 0, 64)
ENDFUNCTION
FUNCTION spriteinit: tilecount,tile_width,tile_height
LOCAL sprite,num,spots
sprite=GENSPRITE()
CREATESCREEN 0,sprite,tile_width*tilecount,tile_height
USESCREEN 0
CLEARSCREEN
FOR num=0 TO TILE_COUNT-1
DRAWRECT tile_width*num,0,tile_width,tile_height,map_color[num]
NEXT
spots=RND(300)
ALPHAMODE -0.2
FOR spot=0 TO spots
DRAWRECT RND(tile_width*tilecount),RND(tile_height),RND(tile_width/4),RND(tile_height/4),RGB(255,255,255)
NEXT
ALPHAMODE 0
FOR num=0 TO TILE_COUNT-1
IF num=TILE_AIR OR num=TILE_PLAYER OR num=TILE_COIN
DRAWRECT tile_width*num,0,tile_width,tile_height,map_color[num]
ENDIF
NEXT
USESCREEN -1
RETURN sprite
ENDFUNCTION
FUNCTION animate:
WHILE TRUE
key_input()
tile_draw()
player_draw()
SHOWSCREEN
WEND
ENDFUNCTION
FUNCTION key_input:
player_x_last=player_x
player_y_last=player_y
IF KEY(KEY_LEFT)
DEC player_x,tile_width/8
ENDIF
IF KEY(KEY_RIGHT)
INC player_x,tile_width/8
ENDIF
IF KEY(KEY_SPACE)
IF player_jump=0
player_jump=180
ENDIF
ENDIF
IF player_jump<>0
DEC player_jump,4
INC player_y,SIN(player_jump*2)*tile_height/4
ENDIF
ENDFUNCTION
FUNCTION tile_draw:
FOREACH cell IN tile[]
DRAWANIM anim_tile,cell.num, cell.x-player_x,cell.y
NEXT
ENDFUNCTION
FUNCTION player_draw:
DRAWANIM anim_tile,TILE_PLAYER,screen_width/2,player_y
ENDFUNCTION
If your level is defined as a grid of tiles, in fixed locations and with fixed widths, i.e. something like this:
---------------------
| 1 | 2 | 3 | 4 | 5 |
---------------------
| 6 | 7 | 8 | 9 | 10|
---------------------
Then all you will need is an 2D array of numbers, the numbers representing what each tile is. There would be no need to store the width and height of each tile, because they are fixed. There would be no need to store (x,y) locations because the position in the array (e.g. Tiles[4][3]) tells you the (x,y) position - (4 * tilewidth, 3 * tileheight).
If you are considering a level creator with saveable (if that's a word) levels, Matchy's code for loading the map could easily be used to read maps from files.
Yes, I think the issue here is creating the map for tiling and in my case I demonstrate a visual string array of simple mario world. It is easy to plot off the 2D array but there are time where not all tiles require plotting like layers. In my example, I should have excluded the AIR (empy white) tiles from drawing. Also mappy exports 3D arrays, such as layers and animation which can be imported.
Thanks a lot guys!!
I haven't got a chance yet, but I'm gonna look through matchy's code today and try Serpent's suggestion and see if I can get it all figured out.
Thanks again everyone!
:good: :coke: