Tile Collision help

BlitzMax Forums/BlitzMax Programming/Tile Collision help

SillyPutty(Posted 2005) [#1]
Hi all, I need some help with the code below, specifically detecting collisions correctly

if I move with increments of 32(tile size) collision is perfect, but obviously this is not ideal, so if I move say 3 unit increments, collision gets screwy, as in the example below. Can anyone help me this ?







Scott Shaver(Posted 2005) [#2]
this is a bit messy but it works - I just noticed some situations where this does quite cut it, working it out...

'tile map example by Deux


Strict
Graphics 640,480,0

Const TILE_TYPE_WALL=1
Const TILE_TYPE_ROOF=2
Const TILE_TYPE_GROUND=3

Const MAP_WIDTH = 10
Const MAP_HEIGHT = 10



'SetClsColor 155,155,155
Type TTile
	Field x#
	Field y#
	Field width#
	Field height#
	Field red#
	Field green#
	Field blue#
	Field TileType%
	Field image:TImage
End Type


Global map[] = [2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,3,3,3,3,3,3,3,3,3,3]

Global TileList:TList=CreateList()

Global playery#=64
Global playerx#=64
Global oldx#
Global oldy#

Global x#
Global y#



Function LoadMap()

	Local tile_countx%=0
	Local tile_county%=0
	
	For Local x%=EachIn map
		Local t:TTile = New TTile
		If(tile_countx = MAP_WIDTH) Then
			tile_county :+1
			tile_countx = 0
		End If	
		
		
		Select x
		
			Case 1
				t.red# = tile_countx*10
				t.green# = tile_county*10
				t.blue# = 125
				t.width#=32
				t.height#=32
				t.x# = (tile_countx)*t.width#
				t.y#=(tile_county)*t.height#
				t.TileType = TILE_TYPE_WALL
				TileList.AddLast t
			Case 2
				t.red# = tile_countx*10
				t.green# = tile_county*10
				t.blue# = 125
				t.width#=32
				t.height#=32
				t.x# = (tile_countx)*t.width#
				t.y#=(tile_county)*t.height#
				t.TileType = TILE_TYPE_ROOF
				TileList.AddLast t
			Case 3
				t.red# = tile_countx*10
				t.green# = tile_county*10
				t.blue# = 125
				t.width#=32
				t.height#=32
				t.x# = (tile_countx)*t.width#
				t.y#=(tile_county)*t.height#
				t.TileType = TILE_TYPE_GROUND
				TileList.AddLast t
			
		End Select
			
	tile_countx :+ 1


	Next

End Function

Function RenderMap()
	For Local t:TTile=EachIn TileList
		SetColor t.red#,t.green#,t.blue#
		DrawRect t.x#,t.y#,32,32
		DrawText t.tiletype,t.x#,t.y#
	Next
End Function


LoadMap()

HideMouse

While Not KeyDown(KEY_ESCAPE)

	RenderMap()
	oldx# = playerx#
	oldy# = playery#
	Local index:Int = 0
	Local temp:Int=0
	
	If KeyDown(KEY_A) Or KeyDown(KEY_LEFT) Then 
		If playerx# > 0 Then playerx#:-3
		If playerx# < 0 Then 
			playerx#=0
		Else
			' check the characters upper left corner
			index=(playerx#/32)
			temp:Int=(playery#/32)
			temp:*MAP_HEIGHT
			index:+temp
			If map[index]<>0 Then 
				playerx#:+3
			Else ' check the characters lower left corner
				index=(playerx#/32)
				temp:Int=((playery#+32)/32)
				temp:*MAP_HEIGHT
				index:+temp
				If map[index]<>0 Then playerx#:+3
			EndIf
		EndIf
	EndIf
	
	If KeyDown(KEY_D) Or KeyDown(KEY_RIGHT) Then 
		If playerx# < (MAP_WIDTH*32)-32 Then playerx#:+3
		If playerx#+32 > (MAP_WIDTH*32)-32 Then 
			playerx#=(MAP_WIDTH*32)-32
		Else
			' check the characters upper right corner
			index=((playerx#+32)/32)
			temp:Int=(playery#/32)
			temp:*MAP_HEIGHT
			index:+temp
			If map[index]<>0 Then 
				playerx#:-3
			Else ' lower right corner
				index=((playerx#+32)/32)
				temp:Int=((playery#+32)/32)
				temp:*MAP_HEIGHT
				index:+temp
				If map[index]<>0 Then playerx#:-3
			EndIf
		EndIf
	EndIf
	If KeyDown(KEY_W) Or KeyDown(KEY_UP) Then 
		If playery# > 0 Then playery#:-3
		If playery# < 0 Then 
			playery#=0
		Else
			' check the characters upper left corner
			index=(playerx#/32)
			temp:Int=(playery#/32)
			temp:*MAP_HEIGHT
			index:+temp
			If map[index]<>0 Then 
				playery#:+3
			Else
				' check the characters upper right corner
				index=((playerx#+32)/32)
				temp:Int=(playery#/32)
				temp:*MAP_HEIGHT
				index:+temp
				If map[index]<>0 Then playery#:+3
			EndIf
		EndIf
	EndIf
	If KeyDown(KEY_S) Or KeyDown(KEY_DOWN) Then 
		If playery# < (MAP_HEIGHT*32)-32 Then playery#:+3
		If playery# > (MAP_HEIGHT*32)-32 Then 
			playery#=(MAP_HEIGHT*32)-32
		Else
			' check the characters lower left corner
			index=(playerx#/32)
			temp:Int=((playery#+32)/32)
			temp:*MAP_HEIGHT
			index:+temp
			If map[index]<>0 Then 
				playery#:-3
			Else
				' check the characters lower right corner
				index=((playerx#+32)/32)
				temp:Int=((playery#+32)/32)
				temp:*MAP_HEIGHT
				index:+temp
				If map[index]<>0 Then playery#:+3
			EndIf
		EndIf
	EndIf
	
	'If KeyDown(KEY_LEFT) playerx# :-3
	'If KeyDown(KEY_RIGHT) playerx# :+3
	'If KeyDown(KEY_UP) playery# :-3
	'If KeyDown(KEY_DOWN) playery# :+3
	
	'Local index:Int = playerx#/32+(playery#/32*MAP_HEIGHT)
	'DrawText map[index],10,50
	
	'If map[index] = 0 Then
	'Else
	'	playerx# = oldx#
	'	playery# = oldy#
		
	'End If
	
	DrawRect  playerx#,playery#,32,32
	
	Flip
	FlushMem
	Cls
	
	
Wend

 






SillyPutty(Posted 2005) [#3]
Ah thanks scott !

What problems were you experiencing ?


SillyPutty(Posted 2005) [#4]
I now understand the above code, it works well, but how would one handle collision on slopes ?

Also another silly question, I am using a linear array, and pushing each element tile into a list, is there any advantage in rather using a multi-dimensional array instead of a linear array ? ala map[x][y] and looping through it ? Would it make life easier ?

I am just trying to gauge how this tiling thing is done.



ok, was playing around a bit with this, i like muti-dim arrays better :)




SillyPutty(Posted 2005) [#5]
ok, I am ready to pull all my hair out :(

for some reason, the collisions are screwy, misaligned if you will.

Could someone please point out the error of my ways here, I cant spot why.

You will notice than in some occations the rects are flush. I think this is what scott was talking about.

Anyway, I built in a little level editor, so you can place tiles down, press [space] to activate the editor, place your tiles, and move the player around.

Any help would be greatly appreciated.




SillyPutty(Posted 2005) [#6]
Is there nobody that can point me in the right direction ?

Looks like I have to use AABB :(


SillyPutty(Posted 2005) [#7]
I seem to have fixed it, w00t !


Scott Shaver(Posted 2005) [#8]
Sorry I didn't get back to you sooner. Yeah the flush issues was part of the problem in my code above. You have it fixed though, it sounds like. I was going to use Mod to determine the number of pixels the player could move if they couldn'e move an entire 3 pixels.


SillyPutty(Posted 2005) [#9]
yeah, change the coordinates for getting 4 points from 32 to 31.