TileMap Collision Problem

BlitzPlus Forums/BlitzPlus Programming/TileMap Collision Problem

maverick69(Posted 2003) [#1]
I have developed a TileEngine using Blitz. Each Tile can have different values. For example if a tile has a value of 1 a collision is possible, if the value is 0, no collision occurs.

Now i have a problem: I have a lot of enemy objects. They fly into one direction and if they collide with a tile they should fly in the other direction but mathematical correct (a little bit like a ball).

I have done a little exmaple programm to show you my problem.

Does anyone know how to solve this problem?

Graphics 320,256
SetBuffer BackBuffer()
SeedRnd MilliSecs();

;Generate Random Map
Dim Map(10,8)
For a=0 To 10
	For b=0 To 8
		Map(a,b)=Rand(0,10)
	Next
Next

Type player
	Field x
	Field y
	Field dx
	Field dy
End Type
Global player.player = New player

player\x=100
player\y=100
player\dx=2
player\dy=2

Repeat
	ClsColor 0,0,0
	Cls
	DrawMap()
	
	;
	; Calc new player position
	;
	
	player\x=player\x+player\dx
	player\y=player\y+player\dy

	If player\x>320 Or player\x<0 Then player\dx=-player\dx
	If player\y>256 Or player\y<0 Then player\dy=-player\dy
	
	If player\x>320 Then player\x=320
	If player\x<0 Then player\x=0
	If player\y>256 Then player\y=256
	If player\y<0 Then player\y=0
	
	;
	; check for wall
	;
	
	If isWall(player\x,player\y)
		 ;
		 ; // TODO //
		 ;
		 ; player\dx=-player\dx
		 ; player\dy=-player\dy
	End If
	
	;
	; draw player
	;
	
	Color 255,0,0
	Rect player\x-1,player\y-1,2,2,1
	Color 64,64,64
	
	Flip
Forever

Function isWall(x,y)
	If Map(x/32,y/32)=8 Then Return True
	Return False
End Function

Function DrawMap()
For a=0 To 10
	For b=0 To 8
		If Map(a,b)=8 ;blocktile
		Rect a*32,b*32,32,32,1
		End If
	Next
Next						
End Function



Ross C(Posted 2003) [#2]
hi!

Try moving the enemy down/up, check for a collision. If one occurs, reverse the y direction of the enemy. Then move the enemy left/right, check for a collision, if one occurs then reverse the x direction. Should keep you right.:) Oh and take out the repeat...forever loop and replace it with a
While Not KeyHit(1)


Wend


loop. it means that ppl can exit the game when escpe is pressed :)


Curtastic(Posted 2003) [#3]
you just need to seperate the x and y movement and collision
and add "if keyhit(1) then end". better than a while loop becuase you can put it wherever you want (like in handleinput())

Graphics 320,256
SetBuffer BackBuffer()
SeedRnd MilliSecs();

;Generate Random Map
Dim Map(10,8)
For a=0 To 10
	For b=0 To 8
		Map(a,b)=Rand(0,10)
	Next
Next

Type player
	Field x
	Field y
	Field dx
	Field dy
End Type
Global player.player = New player

player\x=100
player\y=100
player\dx=2
player\dy=2

Repeat
	ClsColor 0,0,0
	Cls
	DrawMap()
	
	;
	; Calc new player position
	;
	
	player\x=player\x+player\dx

	If player\x>320 Or player\x<0 Then player\dx=-player\dx
	
	If player\x>320 Then player\x=320
	If player\x<0 Then player\x=0

	;
	; check for wall x
	;
	If isWall(player\x,player\y)
		player\dx=-player\dx
		player\x=player\x+player\dx
	End If

	player\y=player\y+player\dy
	If player\y>256 Or player\y<0 Then player\dy=-player\dy
	If player\y>256 Then player\y=256
	If player\y<0 Then player\y=0
	
	;
	; check for wall y
	;
	If isWall(player\x,player\y)
		player\dy=-player\dy
		player\y=player\y+player\dy
	End If
	
	
	;
	; draw player
	;
	
	Color 255,0,0
	Rect player\x-1,player\y-1,2,2,1
	Color 64,64,64
	
	Flip
	If KeyHit(1) Then End
Forever

Function isWall(x,y)
	If Map(x/32,y/32)=8 Then Return True
	Return False
End Function

Function DrawMap()
For a=0 To 10
	For b=0 To 8
		If Map(a,b)=8 ;blocktile
		Rect a*32,b*32,32,32,1
		End If
	Next
Next						
End Function



Mark1nc(Posted 2003) [#4]
You might also want to use Floor() instead of using the built-in Int(). The Int() rounds anything over .5 up to 1
Floor() drops the fraction, which is what you want done.

Function isWall(x,y)
If Map(Floor(x/32),Floor(y/32))=8 Then Return True
Return False
End Function