Hi
@ OOSKA
This was a tutorial I knocked up a while back for someone it may help you
`****************************************************************************************
`**************************** HOW TILE BASED COLLISION WORKS ****************************
`**************************** by pizzaman ****************************
`**************************** Date: 14/6/04 ****************************
`**************************** Time to complete: 1 hour ****************************
`****************************************************************************************
`THE PRINCIPLE -
`the visible screen is devided up into boxes which we call tiles. This means that each
`tile is sitting on a range of coordinates. For example a 20 pixel by 20 pixel tile is
`sitting on the coordinates (0,0),(1,0).....upto (19,19). Since we know each tile is
`sitting on a range of coordinates we can check to see whether a sprite (or image) has
`the same coordinates as the tile. However, we must take into consideration that a
`sprite (or image) is usually bigger than a pixel, so we have to form a collision box
`around the sprite.
`HOW TO IMPLEMENT A TILE BASED COLLISION SYSTEM -
`Firstly we need a 2 dimensional array to store tile data in (Tile data is the image
`numbers of the of the images you are going to use; e.g. 1 could be a wall, 2 could be
`a grass image etc. Note: the image sizes should be the same as the tile size you will
`use.
`Secondly we store the data in the array. Note: you could already store data in an array
`and just load the array - this would be faster for loading times.
`Next we create some collision points around our sprite, usually 4 points which would
`be placed at the corners of the sprite creating a collision box, you could have more
`collision points if a collision box is not suitable.
`Next we have to figure out which tile in the array each collision point is on to do
`this you have to use the formula
`
` Tile = (x / Tile Sise, y / Tile size)
`
` where Tile is the tile in the array, x is the x coordinate of the
` collision point your checking for and y is the y coordinate of the
` collision point your checking for
`
`Now if the tile is a tile you dont want your sprite to go on; just reset the sprites
`coordinates to what they were before the collision and voila!!!! you've got tile
`based collision.
`****************************************************************************************
`*********************************** Start of program ***********************************
`****************************************************************************************
`gosubs are here instead of actual code, just to make things look neat
gosub screensetup
gosub createimages
gosub loaddata
gosub makeplayer
`start the main loop
do
`exit the loop if space bar is pressed - effectively ending the program
`Note: it has to be place here and not in a gosub as it wont work
if spacekey() = 1 then exit
gosub controls
gosub collision
`call our home made function for displaying the tiles
PasteTiles()
gosub displayplayer
`update screen
sync
loop
gosub cleanup
`end the program
end
`****************************************************************************************
`************************************* End of program ***********************************
`****************************************************************************************
screensetup:
`delete anything stored in video memory
flush video memory
`set screen resolution
set display mode 800,600,32
`setup syncing
sync on
sync rate 0
return
createimages:
`create a green box
cls rgb(0,255,0)
get image 1,0,0,40,40,1
`create a yellow box as the player
cls rgb(255,255,0)
get image 2,0,0,40,40,1
`create a red box
cls rgb(255,0,0)
get image 10,0,0,40,40,1
`create a blue box
cls rgb(0,0,255)
get image 11,0,0,40,40,1
return
loaddata:
`create an array called TileMap - we will use this to store the tile data.
`an array is like a file cabinet - in each drawer of the file cabinet there are
`folders that hold our data. Therefore in our "file cabinet" we have 20 drawers; and
`inside of each drawer we 15 folders; which hold data we want to access.
`Also arrays can have up to 5 dimensions (ours has 2 dimensions) - you can visualise
`this as being more folders inside of the other folders and so on; and of course you
`can just have 1 dimension array as well (in other words just the drawers)
dim TileMap(20,15)
`load data into the array - basically the computer will read 20 bits of data from one
`data statment (at the end of the program), then move onto the next data statment
`until all 15 data statments are read. Note: all 15 data statments could have been
`combined into one large data statment of 300 items; the reason why its not currently
`like that is its hard to read also you can kind of see the map the way its currently
`written.
for y = 0 to 14
for x = 0 to 19
read TileMap(x,y)
next x
next y
return
makeplayer:
`store predefined coordinates of player
x1 = 380
y1 = 280
`make the player
sprite 1,x1,y1,2
`this sets the sprites properties; by placing a 0 in the backsave flag the background
`behind sprite will not be saved by the computer, hence will speed up our program a
`little. We are not using the backsave feature because we will be replacing the
`background ourselves; this is due to when a sprite is created the 3d backdrop is
`automatically created (a blue screen wiping any 2d images previously draw to the
`screen) and cannot be turned off as long as you have a sprite on screen.
set sprite 1,0,1
return
controls:
`store the x and y coordinates of the player into the variables oldx1 and oldy1
oldx1 = x1
oldy1 = y1
`makes the player move by altering the sprites coordinates
if leftkey() = 1 then x1 = x1 - 2
if rightkey() = 1 then x1 = x1 + 2
if upkey() = 1 then y1 = y1 - 2
if downkey() = 1 then y1 = y1 + 2
return
collision:
`the following 8 lines of code stores the old and new left,right,top,bottom edges of
`the sprite in the respective variables
`gets which tiles the current left and right co-ordinates of the player are on
LeftTileNum = int(x1 / 40)
RightTileNum = int((x1 + 39) / 40)
`gets which tiles the current top and bottom co-ordinates of the player are on
TopTileNum = int(y1 / 40)
BottomTileNum = int((y1 + 39) / 40)
`gets which tiles the old left and right co-ordinates of the player are on
OldLeftTileNum = int(oldx1 / 40)
OldRightTileNum = int((oldx1 + 39) / 40)
`gets which tiles the old top and bottom co-ordinates of the player are on
OldTopTileNum = int(oldy1 / 40)
OldBottomTileNum = int((oldy1 + 39) / 40)
`this is where we check for those 4 collision points; if the collision point is on a
`tile you are not able to pass through (in our case a tile that has an image number
`of 10 or greater), then the old coordinates of the sprite are restored.
`Note: to have sliding collision we must check the the current x tile against the
`old y tile and vice versa.
`checks for top-left collision point
if TileMap(LeftTileNum, OldTopTileNum) >= 10 then x1 = oldx1
if TileMap(OldLeftTileNum, TopTileNum) >= 10 then y1 = oldy1
`checks for top-right collision point
if TileMap(RightTileNum, OldTopTileNum) >= 10 then x1 = oldx1
if TileMap(OldRightTileNum, TopTileNum) >= 10 then y1 = oldy1
`checks for bottom-left collision point
if TileMap(LeftTileNum, OldBottomTileNum) >= 10 then x1 = oldx1
if TileMap(OldLeftTileNum, BottomTileNum) >= 10 then y1 = oldy1
`checks foe bottom-right collision point
if TileMap(RightTileNum, OldBottomTileNum) >= 10 then x1 = oldx1
if TileMap(OldRightTileNum, BottomTileNum) >= 10 then y1 = oldy1
return
displayplayer:
`display sprite
sprite 1,x1,y1,2
`show frame rate (also sometimes its useful to display debug info like player
`player positions, program specific variables etc)
text 10,10,str$(screen fps())
return
cleanup:
`delete any media involved in this program
for x = 1 to 11
if image exist(x) then delete image x
if sprite exist(x) then delete sprite x
next x
`delete anything thats left in the video memory - if anything
flush video memory
return
`this is a simple user defined function - all it does is paste the tile images to the
`screen in the correct order from the array
function PasteTiles()
for y = 0 to 14
for x = 0 to 19
paste image TileMap(x,y),x*40,y*40
next x
next y
endfunction
`store tile data at the end of the program so its out of the way
data 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
data 10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10
data 10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10
data 10,1,1,11,11,1,1,1,1,1,1,1,1,1,1,11,11,1,1,10
data 10,1,1,11,11,1,1,1,1,1,1,1,1,1,1,11,11,1,1,10
data 10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10
data 10,1,1,11,1,11,1,1,1,1,1,1,1,1,11,1,11,1,1,10
data 10,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,10
data 10,1,1,11,1,11,1,1,1,1,1,1,1,1,11,1,11,1,1,10
data 10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10
data 10,1,1,11,11,1,1,1,1,1,1,1,1,1,1,11,11,1,1,10
data 10,1,1,11,11,1,1,1,1,1,1,1,1,1,1,11,11,1,1,10
data 10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10
data 10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10
data 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
pizzaman