Tilemap Collision Response

BlitzMax Forums/BlitzMax Programming/Tilemap Collision Response

zoqfotpik(Posted 2012) [#1]
I have a rectangular vehicle which I would like to respond physically to collisions with walls on a tilemap.

If I had verlet physics this would be easy-- I'd just find which of the edges of the colliding tile the points in the rectangle collided with first, and then move that point to the surface of that edge.

But I don't have that and I was wondering if there might be another recommended way of doing this. Perhaps the simplest would be coding up a 2D verlet system, but I'm wondering if I could get close to the same effect by simply moving the vehicle until there was no collision, without a verlet physics system.

An aside: Verlet systems are pretty easy to code and very fun to play with-- I am just wanting to work on other aspects of my game at this time.


zoqfotpik(Posted 2012) [#2]
Here is the routine I came up with. It's quick and dirty but serviceable. It's based on a cross, and each point of the cross is indexed into the tilemap. This doesn't take corners into account and tends to get stuck but the game is a tank game and it works all right for that application-- there has to be some penalty for running into walls! The worldpointtomap functions of the tilemap are for indexing the world coordinates into 32x32 tile blocks and basically work simply by dividing the world x and y by 32.

Method crosscollide()' cross-based collision response
			' collisions between tilemap cells up, down, left, right
			' with tank's central cross (shield collision)
			' uses worldtomap
		updatecross()
		If tmap.worldpointtomapcollision(mycross.x1, mycross.y1)
			x = oldx 
			y = oldy
			vy = vy/2
			If closeto(angle, 270, 20)
				vx = vx / 1.1
				angle = angle + 1
			Else
				vx = vx /2
				power:/2
			EndIf
			If closeto(angle, 90,20)
				vx = vx / 1.1
				angle = angle -1
			Else
				vx = vx /2
				power:/2
			EndIf

		EndIf
		
		If tmap.worldpointtomapcollision(mycross.x2, mycross.y2)
			x=oldx
			y=oldy
			vx=vx/2
		
			If closeto(angle, 180, 20)
				vy = vy / 1.1
				angle = angle - 1
			Else
				vy = vy /2
				power:/2
			EndIf
			If closeto(angle, 1,20) Or closeto(angle,360,20)
				vy = vy / 1.1
				angle = angle +1
			Else
				vy = vy /2
				power:/2
			EndIf

			
		EndIf
		
		If tmap.worldpointtomapcollision(mycross.x3, mycross.y3)
			x=oldx
			y=oldy
			vx = vx/2
			vy = vy /2
			If closeto(angle, 270, 20)
				vx = vx / 1.1
				angle = angle - 1
			Else
				vx = vx /2
				power:/2
			EndIf
			If closeto(angle, 90,20)
				vx = vx / 1.1
				angle = angle +1
			Else
				vx = vx /2
				power:/2
			EndIf

		EndIf
		
		If tmap.worldpointtomapcollision(mycross.x4, mycross.y4)
			x=oldx
			y=oldy
			vx:/2
			vy:/2
			power:/2
		EndIf
		
	End Method


Last edited 2012