Jump to content

  • Log In with Google      Sign In   
  • Create Account

Gilla

Member Since 29 Mar 2011
Offline Last Active Oct 01 2011 03:11 AM

Topics I've Started

Tile based collision bug

26 September 2011 - 10:42 PM

I'm making a 2D game with a tile engine. The issue seems to be my code is testing vertical and horizontal collision in a different order then I intended, causing the sprite get pushed off the screen when colliding. Or in some cases being locked in place due to faulty collision. My code is fairly simple so I can't see why it's failing. Here is the collision component, and I'll explain the code below.
public class CollisionComponent {

	float x, y;
	/*
     * This here is a collision array
     * I know, wtf right?
     * He'eres the idea.
     * I need to test for verticle and horizontal collision seperatly.
     * If i don't then my game will ignore one for the other. This causes
     * falls through floors and stuff. With collision being an array
     * I can have one function return two values intead of two functions
     * returning one value each. 
     */
	
	public void checkTouching(Entity entity, editor.MapComponent map ){
		
		entity.collision[0] = 0;
		entity.collision[1] = 0;
			
		/*
	     * Entity is falling, check bottom side collision
	     */
		if (entity.verticleVelocity > 0.0f){
			bottom (entity, map);
			if (entity.collision[0] == 1){
				entity.Y = ((map.rowIndex * map.tileHeight) - entity.Height) ;
				entity.verticleVelocity = 0.0f;
			}
		}
		/*
	     * Entity is rising, check top side for collision
	     */
		else if (entity.verticleVelocity <  0.0f){
			top (entity, map);
			if (entity.collision[0] == 2){
				entity.Y = ((map.rowIndex + 1) * map.tileHeight);
				entity.verticleVelocity = 0.0f;
			}
			
		}
		/*
	     * Entity is moving right, check right for collision
	     */
		if (entity.Velocity > 0.0f){
			right(entity, map);
			if (entity.collision[1] == 3){
				entity.X = ( ((map.columnIndex ) * map.tileWidth) - entity.Width) ;
				
			}
		}
		/*
	     * Entity is moving left, check left for collision
	     */
		else if (entity.Velocity < 0.0f){
			left(entity, map);
			if (entity.collision[1] == 4){
				entity.X = ((map.columnIndex + 1) * map.tileWidth);
				
			}
		}
		
	}
	
	public void bottom(Entity entity, editor.MapComponent map){
							
			/*
		     * calculate which tile the bottom of entity is in
		     */
			map.rowIndex = (int) ((entity.Y + entity.Height ) / map.tileHeight);
			
			for (float x = (entity.X); x <= ((entity.X) + entity.Width); x += map.tileWidth){

				map.columnIndex = (int) (x / map.tileWidth); // the (int) casts the entity.x float into an int so I can do the calculation
				map.selectedTile = map.map[map.rowIndex][map.columnIndex];		
				if( map.selectedTile == 1){
					entity.collision[0] = 1;
				}

			}
			/*
		     * this copy pasta code is horrible I know ..... same as above
		     * it's actually kind of meta now as I just copy pasta'd the
		     * copy pasta code for each side of the sprite....
		     */
			map.columnIndex = (int) (( (entity.X ) + entity.Width) / map.tileWidth); 
			map.selectedTile = map.map[map.rowIndex][map.columnIndex];
		
			if( map.selectedTile == 1){
				entity.collision[0] = 1;
			}
			
	}
	
	public void top(Entity entity, editor.MapComponent map){
		
		/*
	     * calculate which tile the top of entity is in
	     */
		map.rowIndex = (int) ((entity.Y ) / map.tileHeight);
		
		for (float x = (entity.X); x <= ((entity.X ) + entity.Width); x += map.tileWidth){

			map.columnIndex = (int) (x / map.tileWidth); // the (int) casts the entity.x float into an int so I can do the calculation
			map.selectedTile = map.map[map.rowIndex][map.columnIndex];		
			if( map.selectedTile == 1){
				entity.collision[0] = 2;
			}

		}
		/*
	     * this copy pasta code is horrible I know ..... same as above
	     * it's actually kind of meta now as I just copy pasta'd the
	     * copy pasta code for each side of the sprite....
	     */
		map.columnIndex = (int) (( (entity.X) + entity.Width) / map.tileWidth); 
		map.selectedTile = map.map[map.rowIndex][map.columnIndex];
	
		if( map.selectedTile == 1){
			entity.collision[0] = 2;
		}
		
	}
	
	public void right(Entity entity, editor.MapComponent map){
		
		/*
	     * calculate which tile the right of entity is in
	     */
		
		map.columnIndex = (int) ((entity.X + entity.Width ) / map.tileWidth);
		
		for (float y = (entity.Y) ; y <= ((entity.Y ) + entity.Height); y += map.tileHeight){
			map.rowIndex = (int) ( (y) / map.tileHeight); // the (int) casts the entity.x float into an int so I can do the calculation
			map.selectedTile = map.map[map.rowIndex][map.columnIndex];		
			if( map.selectedTile == 1){
				entity.collision[1] = 3;
			}

		}
		/*
	     * this copy pasta code is horrible I know ..... same as above
	     * it's actually kind of meta now as I just copy pasta'd the
	     * copy pasta code for each side of the sprite....
	     */
		map.rowIndex = (int) (((entity.Y)  + entity.Height) / map.tileHeight); 
		map.selectedTile = map.map[map.rowIndex][map.columnIndex];
	
		if( map.selectedTile == 1){
			entity.collision[1] = 3;
		}
		
	}
	
	public void left(Entity entity, editor.MapComponent map){
		
		/*
	     * calculate which tile the right of entity is in
	     */
		
		map.columnIndex = (int) ((entity.X) / map.tileWidth);
		
		for (float y = (entity.Y) ; y <= ((entity.Y ) + entity.Height); y += map.tileHeight){
			map.rowIndex = (int) ((y) / map.tileHeight); // the (int) casts the entity.x float into an int so I can do the calculation
			map.selectedTile = map.map[map.rowIndex][map.columnIndex];		
			if( map.selectedTile == 1){
				entity.collision[1] = 4;
			}

		}
		/*
	     * this copy pasta code is horrible I know ..... same as above
	     * it's actually kind of meta now as I just copy pasta'd the
	     * copy pasta code for each side of the sprite....
	     */
		map.rowIndex = (int) (( (entity.Y) + entity.Height) / map.tileHeight); 
		map.selectedTile = map.map[map.rowIndex][map.columnIndex];
	
		if( map.selectedTile == 1){
			entity.collision[1] = 4;
		}
		
	}
	
	
	
}

It is rough I know. I hold the collision results in a 2d array. The first index hold vertical collision(0 for not, 1 for collision on bottom, 2 for collision on top), and I use the second index for the horizontal collision. I test verticle collision first and move the sprite if collision was true. I then test horizontal collision and so blah blah. The rest of my code basically works by polling input (which only changes velocity), applying physics (which applies the velocity to the sprite's position), then testing collision and finally updating the screen. I've included all my source if you want to look at it, but the collision code should be enough.

Any ideas where I'm going wrong here? I think this collision code should work.

PARTNERS