I have a 2d game and I am using a tileset to dynamically scroll in all directions. Just wondering is there a tutorial or something about placing stationary objects on my map. That is to say my guy walks around just fine and the screen scrolls but what if I want to put in a building or a rock or something. how do I keep track of where to draw it when scrolling? I guess legend of zelda would be an example of what I'm trying to accomplish here.
stationary objects when dynamically scrolling
BlitzPlus Forums/BlitzPlus Beginners Area/stationary objects when dynamically scrolling I assume you are keeping a record like in a type for instance of what the properties of the object are such as:
type stuffinthegame
field worldx,worldy
field health
field class$ ; building, rock, player etc
end type
and then all you need to do is keep track of where the upper left corner pixel is in the world with a pair of variables 'cornerx, cornery' for instance and then when drawing all objects simply subtract the cornerx,cornery from the object's worldx,worldy - if the resulting value is within the boundaries of the screen then it can be drawn.
type stuffinthegame
field worldx,worldy
field health
field class$ ; building, rock, player etc
end type
and then all you need to do is keep track of where the upper left corner pixel is in the world with a pair of variables 'cornerx, cornery' for instance and then when drawing all objects simply subtract the cornerx,cornery from the object's worldx,worldy - if the resulting value is within the boundaries of the screen then it can be drawn.
I apolagize at the moment I've been developing in Dark Basic Pro (I like the community here better) but you'll get the idea. From your post I guess I could use my constants GAMEWORLDWIDTH and GAMEWORLDHEIGHT to figure out where I am
here is what I am doing I got alot of it from a dark basic pro game development book
this is a bit long
say I have a bitmap composed of 10 different ground tiles
then I have a data file that is like
data 1,5,6,7,8
data 1,34,7,8 blah blah blah
then I load all this stuff into my array (perhaps a solution to your post :)
` load the tile images
load bitmap "groundtiles.bmp", IMG_TILES
`create the scroll buffer surface in memory, slightly bigger than the screen
create bitmap IMG_SCROLLBUFFER, SCROLLBUFFERWIDTH, SCROLLBUFFERHEIGHT
`load the map data into the array
for y = 0 to MAPHEIGHT-1
for x = 0 to MAPWIDTH-1
read MAPDATA(x,y)
next x
next y
in my main loop I have two methods I keep calling
update the scrolling view
UpdateScrollPosition()
`draw tiles onto the scroll buffer
DrawTileMap()
here is a piece of the update scroll position
function UpdateScrollPosition()
`scroll based on mouse input
if hunter.x < 200 and ScrollX <> 0
hunter.x = 199
dec ScrollX, hunter.speed - 2
hunter.frame = getframe(hunter)
hunter.inactive_timer = 0
endif
if hunter.x > 400 and ScrollX <> GAMEWORLDWIDTH - WINDOWWIDTH
hunter.x = 401
inc ScrollX, hunter.speed - 2
hunter.frame = getframe(hunter)
hunter.inactive_timer = 0
endif
and a couple more if then statements for the y position of the hunter then I do then I do
`update horizontal scrolling position and speed
if ScrollX < 0
ScrollX = 0
else
if ScrollX > GAMEWORLDWIDTH - WINDOWWIDTH
ScrollX = GAMEWORLDWIDTH - WINDOWWIDTH
endif
endif
`update vertical scrolling position and speed
if ScrollY < 0
ScrollY = 0
else
if (ScrollY > GAMEWORLDHEIGHT - WINDOWHEIGHT-1)
ScrollY = GAMEWORLDHEIGHT - WINDOWHEIGHT-1
endif
endif
here is the draw tile map function
`*************************Draw Tile Map*****************************************************
`This function fills the tilebuffer with tiles representing
`the current scroll display based on scrollx/scrolly.
function DrawTileMap()
`calculate starting tile position
tilex = int(ScrollX / TILEWIDTH)
tiley = int(ScrollY / TILEHEIGHT)
columns = int(WINDOWWIDTH / TILEWIDTH)
rows = int(WINDOWHEIGHT / TILEHEIGHT)
`draw tiles onto the scroll buffer surface
for y = 0 to rows
for x = 0 to columns
`retrieve the tile number from this position
tilenum = MAPDATA(tilex+x, tiley+y)
`draw the tile onto the scroll buffer
DrawTile(IMG_TILES,tilenum,TILEWIDTH,TILEHEIGHT,16,IMG_SCROLLBUFFER,x*TILEWIDTH,y*TILEHEIGHT)
next x
next y
`draws the portion of the scroll buffer onto the back buffer
`according to the current "partial tile" scroll position.
left = ScrollX MOD TILEWIDTH
top = ScrollY MOD TILEHEIGHT
`set dimensions of the source image as a rectangle
right = left + WINDOWWIDTH
bottom = top + WINDOWHEIGHT
`draw the partial tile scroll window onto the back buffer
copy bitmap IMG_SCROLLBUFFER, left, top, right, bottom, 0, 0, 0, WINDOWWIDTH, WINDOWHEIGHT
endfunction
here is the draw tile method that draw tile map calls it just draws the tile to the screen
`This function does the real work of drawing a single tile from the source image
`onto the tile scroll buffer. Parameters provide much flexibility.
function DrawTile(source as integer,tile as integer,width as integer,height as integer,columns as integer,dest as integer,destx as integer,desty as integer)
`describe the source image
left = (tile MOD columns) * width
top = (tile / columns) * height
right = left + width
bottom = top + height
`draw the tile
copy bitmap source, left, top, right, bottom, dest, destx, desty, destx+width, desty+height
endfunction
here is what I am doing I got alot of it from a dark basic pro game development book
this is a bit long
say I have a bitmap composed of 10 different ground tiles
then I have a data file that is like
data 1,5,6,7,8
data 1,34,7,8 blah blah blah
then I load all this stuff into my array (perhaps a solution to your post :)
` load the tile images
load bitmap "groundtiles.bmp", IMG_TILES
`create the scroll buffer surface in memory, slightly bigger than the screen
create bitmap IMG_SCROLLBUFFER, SCROLLBUFFERWIDTH, SCROLLBUFFERHEIGHT
`load the map data into the array
for y = 0 to MAPHEIGHT-1
for x = 0 to MAPWIDTH-1
read MAPDATA(x,y)
next x
next y
in my main loop I have two methods I keep calling
update the scrolling view
UpdateScrollPosition()
`draw tiles onto the scroll buffer
DrawTileMap()
here is a piece of the update scroll position
function UpdateScrollPosition()
`scroll based on mouse input
if hunter.x < 200 and ScrollX <> 0
hunter.x = 199
dec ScrollX, hunter.speed - 2
hunter.frame = getframe(hunter)
hunter.inactive_timer = 0
endif
if hunter.x > 400 and ScrollX <> GAMEWORLDWIDTH - WINDOWWIDTH
hunter.x = 401
inc ScrollX, hunter.speed - 2
hunter.frame = getframe(hunter)
hunter.inactive_timer = 0
endif
and a couple more if then statements for the y position of the hunter then I do then I do
`update horizontal scrolling position and speed
if ScrollX < 0
ScrollX = 0
else
if ScrollX > GAMEWORLDWIDTH - WINDOWWIDTH
ScrollX = GAMEWORLDWIDTH - WINDOWWIDTH
endif
endif
`update vertical scrolling position and speed
if ScrollY < 0
ScrollY = 0
else
if (ScrollY > GAMEWORLDHEIGHT - WINDOWHEIGHT-1)
ScrollY = GAMEWORLDHEIGHT - WINDOWHEIGHT-1
endif
endif
here is the draw tile map function
`*************************Draw Tile Map*****************************************************
`This function fills the tilebuffer with tiles representing
`the current scroll display based on scrollx/scrolly.
function DrawTileMap()
`calculate starting tile position
tilex = int(ScrollX / TILEWIDTH)
tiley = int(ScrollY / TILEHEIGHT)
columns = int(WINDOWWIDTH / TILEWIDTH)
rows = int(WINDOWHEIGHT / TILEHEIGHT)
`draw tiles onto the scroll buffer surface
for y = 0 to rows
for x = 0 to columns
`retrieve the tile number from this position
tilenum = MAPDATA(tilex+x, tiley+y)
`draw the tile onto the scroll buffer
DrawTile(IMG_TILES,tilenum,TILEWIDTH,TILEHEIGHT,16,IMG_SCROLLBUFFER,x*TILEWIDTH,y*TILEHEIGHT)
next x
next y
`draws the portion of the scroll buffer onto the back buffer
`according to the current "partial tile" scroll position.
left = ScrollX MOD TILEWIDTH
top = ScrollY MOD TILEHEIGHT
`set dimensions of the source image as a rectangle
right = left + WINDOWWIDTH
bottom = top + WINDOWHEIGHT
`draw the partial tile scroll window onto the back buffer
copy bitmap IMG_SCROLLBUFFER, left, top, right, bottom, 0, 0, 0, WINDOWWIDTH, WINDOWHEIGHT
endfunction
here is the draw tile method that draw tile map calls it just draws the tile to the screen
`This function does the real work of drawing a single tile from the source image
`onto the tile scroll buffer. Parameters provide much flexibility.
function DrawTile(source as integer,tile as integer,width as integer,height as integer,columns as integer,dest as integer,destx as integer,desty as integer)
`describe the source image
left = (tile MOD columns) * width
top = (tile / columns) * height
right = left + width
bottom = top + height
`draw the tile
copy bitmap source, left, top, right, bottom, dest, destx, desty, destx+width, desty+height
endfunction
Perhaps if you are using an array you could add an extra dimension to the array "MapData(X,Y,Layer)". The 'Layer' elements of the array would hold a number of things like this for instance:
MapData(x,y,0) -> this holds the tiles in much the same way as you are currently doing
MapData(x,y,1) -> this holds the ID number or handle of the 'creature'/'building' etc that is within that tile. Then you simply use a similar technique to what you have above to draw the building/creature.
However - using the method I've just given you will only allow you to have one object per tile which is most likely not what you want. Instead you could do this:
MapData(x,y,1) -> this holds the handle to a 'bank' containing a list of handles of objects within that tile. You then just have to remember to update the bank and the array whenever a creature/building moves from one tile to the next.
Hope that is of some help.
MapData(x,y,0) -> this holds the tiles in much the same way as you are currently doing
MapData(x,y,1) -> this holds the ID number or handle of the 'creature'/'building' etc that is within that tile. Then you simply use a similar technique to what you have above to draw the building/creature.
However - using the method I've just given you will only allow you to have one object per tile which is most likely not what you want. Instead you could do this:
MapData(x,y,1) -> this holds the handle to a 'bank' containing a list of handles of objects within that tile. You then just have to remember to update the bank and the array whenever a creature/building moves from one tile to the next.
Hope that is of some help.
Thanks, I like that idea