Basic 2D Tile Collision

Hello,

I’ve noticed that there are a lot of 2d platforming related questions lately so I hacked up a simple demo.

Collisions are axis-based so this would work wether your player size is bigger or smaller than the map tiles.


package net.phatcode.rel;

/**
 * @author Richard Eric M. Lope (relminator)
 *
 */


public class Collision
{

	public enum CollisionType
	{
		COLLIDE_NONE,
		COLLIDE_FLOOR,
		COLLIDE_WALL,
		COLLIDE_CEILING,
		
	}
	
	private static int tileX;
	private static int tileY;
	
	public static boolean collideWalls( float offset, Entity e, LevelMap levelMap )
	{
		
		int ix = (int)(e.getX() + offset);
		int iy = (int)e.getY();
		
		int hei = (int)e.getHeight();
		
		int tileYpixels = iy - ( iy % Constants.TILE_SIZE );
		int testEnd = iy + hei;	
		
		tileX = ix / Constants.TILE_SIZE;
		tileY = tileYpixels / Constants.TILE_SIZE;
		
		
		int[][] map = levelMap.getMap();
		while( tileYpixels <= testEnd )
		{		
			if( map[tileX][tileY] > 0 )
			{
				return true;
			}
			tileY++;
			tileYpixels += Constants.TILE_SIZE;
		}
		
		return false;
	}
	
	public static boolean collideFloors( float offset, Entity e, LevelMap levelMap )
	{
		
		int ix = (int)e.getX();
		int iy = (int)(e.getY() + offset);
		
		int wid = (int)e.getWidth();
		
		int tileXpixels = ix - ( ix % Constants.TILE_SIZE );
		int testEnd = ix + wid;	
		
		tileX = tileXpixels / Constants.TILE_SIZE;
		tileY = iy / Constants.TILE_SIZE;
		
		
		int[][] map = levelMap.getMap();
		while( tileXpixels <= testEnd )
		{		
			if( map[tileX][tileY] > 0 )
			{
				return true;
			}
			tileX++;
			tileXpixels += Constants.TILE_SIZE;
		}
		
		return false;
	}
	
	public static CollisionType collideOnMap(  Entity e, LevelMap levelMap )
	{
		
		tileX = 0;
		tileY = 0;
		CollisionType collision = CollisionType.COLLIDE_NONE;
		
		if( e.getDx() > 0 )
		{
		
			if( collideWalls( e.getDx() + e.getWidth(), e, levelMap ) )
			{
				e.setX( (tileX  * Constants.TILE_SIZE) - e.getWidth() - 1 );
				collision = CollisionType.COLLIDE_WALL;
			}
			else
			{
				e.addX( e.getDx() );
			}
	
		}
		
		else if( e.getDx() < 0 )
		{

			if( collideWalls( e.getDx(), e, levelMap ) )
			{
				e.setX( ( tileX + 1 ) * Constants.TILE_SIZE + 1 );
				collision = CollisionType.COLLIDE_WALL;
			}
			else
			{
				e.addX( e.getDx() );
			}
			
		}
		
		
		if( e.getDy() < 0 )
		{
			
			if( collideFloors( e.getDy(), e, levelMap ) )
			{
				e.setY( ( tileY + 1 ) * Constants.TILE_SIZE + 1 );
				e.setDy( 0 );
				collision = CollisionType.COLLIDE_CEILING;
			}
			else
			{
				e.addY( e.getDy() );
				e.addDy( Constants.GRAVITY );
			}
			
		}
		else
		{
			
			if( collideFloors( e.getDy() + e.getHeight(), e, levelMap ) )
			{
				e.setY( (tileY  * Constants.TILE_SIZE) - e.getHeight() - 1 );
				e.setDy( 1 );
				collision = CollisionType.COLLIDE_FLOOR;
			}
			else
			{
				e.addY( e.getDy() );
				e.addDy( Constants.GRAVITY );
			}
		}
		
		
		return collision;
		
	}
	
	
}

Full source and binary here:

http://rel.phatcode.net/junk.php?id=143

Screen:

I’m not sure if the links work as I’m using a phone to post.

Enjoy!

very helpful! simple and clean.
you could always add a comment line with a little description of the different methods, but the names of the methods are pretty descriptive anyway. great work :slight_smile:

been trying to find something like this for the last few days :slight_smile:

thank you for sharing this code i can now get one step further to building my first game

Sorry about that. My laptop was getting low on battery so I sped up the process a bit.

Thanks heaps for this! Taking the confusion out of tutorials :wink: