stationary objects when dynamically scrolling

BlitzPlus Forums/BlitzPlus Beginners Area/stationary objects when dynamically scrolling

bryan970(Posted 2007) [#1]
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.


Matty(Posted 2007) [#2]
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.


bryan970(Posted 2007) [#3]
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


Matty(Posted 2007) [#4]
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.


bryan970(Posted 2007) [#5]
Thanks, I like that idea