Collisions with multiple tiles issue

Subscribe to Collisions with multiple tiles issue 3 posts

avatar for alecz127 alecz127 817 posts
Flag Post

Hey guys, I’ve made some huge progress because of Qwerbers collision tutorial.
I’ve got this last issue to deal with, I have no idea whats causing it.
My character is fine when colliding with a single tile, but colliding with two tiles at once and it goes haywire.

If its colliding with “ground” aka tile from above, than its y rapidly changes between being perfectly on top of the tile and being just above it.

If its colliding with “wall” aka tile from left or right, same but with its x respectively.

Everything is working besides that though, I’m actually quite proud.
Works with arrays of tiles (besides this issue obviously) and its x isn’t stuck if moving left or right while colliding with “ground” and vice versa.

private function updateCollisions(){
	for(var i in ground_a){
		squareX2 = ground_a[i].x;
		squareY2 = ground_a[i].y;
		squareWidth2 = ground_a[i].width;
		squareHeight2 = ground_a[i].height;
		solveCollision();
	}
}
public function solveCollision() {
	var velocityY = squareY - prevSq1Y;
	var velocityX = squareX - prevSq1X;
	var distanceX1;
	var distanceY1;
	var distanceX2;
	var distanceY2;
		if(velocityX < 0){
			distanceX1 = squareX2 + squareWidth2 - prevSq1X;
			distanceX2 = squareX2 - prevSq1X - squareWidth;
		} else {
			distanceX1 = squareX2 - prevSq1X - squareWidth;
			distanceX2 = squareX2 + squareWidth2 - prevSq1X;
		}
		if(velocityY < 0){
			distanceY1 = squareY2 + squareHeight2 - prevSq1Y;
			distanceY2 = squareY2 - prevSq1Y - squareHeight;
		} else {
			distanceY1 = squareY2 - prevSq1Y - squareHeight;
			distanceY2 = squareY2 + squareHeight2 - prevSq1Y;
		}
	var timeX = distanceX1/velocityX;
	var timeY = distanceY1/velocityY;
	var actualTime = Math.max(timeX,timeY);
	var disjointTimeX = distanceX2/velocityX;
	var disjointTimeY = distanceY2/velocityY;
	var actualDisjointTime = Math.min(disjointTimeX, disjointTimeY);
	if (timeX < 0 && timeY < 0){
		//trace("COLLISION FOUND UNWORTHY");
		return;
	}
	if(timeX > 1 || timeY > 1){
		//trace("COLLISION FOUND UNWORTHY");
		return;
	}
	if(actualTime < actualDisjointTime){
		//trace("COLLISION FOUND WORTHY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>>>>>");
			player.y = player.y - ((1-actualTime) * velocityY);
			if(timeX < 1 && timeX > 0){
				player.x = player.x - ((1-actualTime) * velocityX);
			}
	}
}
 
avatar for qwerber qwerber 4761 posts
Flag Post

What I did was test collision against all interested tiles and save the time of collisions(TOC). I don’t resolve immediately. Then, I find the first collision by looping through the TOCs and finding the smallest one. Alongside the TOCs, I also store the nature of the collisions. If the nature is x axis, I only move it back along that axis(this way you can slide against walls or the ground). Also remember to set the velocity of that axis to zero.

 
avatar for alecz127 alecz127 817 posts
Flag Post
Originally posted by qwerber:

What I did was test collision against all interested tiles and save the time of collisions(TOC). I don’t resolve immediately. Then, I find the first collision by looping through the TOCs and finding the smallest one. Alongside the TOCs, I also store the nature of the collisions. If the nature is x axis, I only move it back along that axis(this way you can slide against walls or the ground). Also remember to set the velocity of that axis to zero.

ah thanks man!
That makes perfect sense!