Edge detection for platformers?



  • Has anyone tried to implement edge detection? In other words, detecting when your character/player sprite is sitting on the edge of a platform? The way I was taught to implement this in other engines is that you have two raycasts pointing down the y-axis on the left and right of your character. These raycasts get the coordinates of the tiles your character is standing on.

    Then you check and see if the tile coordinates returned by the raycasts on the right or the left are lower on the y axis than the tile coordinates returned by the other raycast.

    [So far I can see how this would be implemented in Haxeflixel easily, save for the last part here.]

    The final step is you compute the width of the player, the width of the tile the player is standing on, and at what point along the x-axis of the tile the player is standing (usually by referencing the raycast that is still detecting the tile that the player is standing on.)

    the reason you do this last step is because you don't want to have a callback for an edge detection if, say, the player's bounding box is only 1 pixel over the edge of the platform. You only want this callback to fire just as the player is about to fall off the platform, this way you can load a sprite animation that shows the player struggling to maintain their balance. You could even have a function that pushes them off the edge if they remain in this position for too long.



  • Here. It's a bit clunky, but should work. I use it to stop AI-controlled guys from falling:

            var edgeLeft(get, null): Bool;
    	var edgeRight(get, null): Bool;
    	var wallLeft(get, null): Bool;
    	var wallRight(get, null): Bool;
    	var wallUp(get, null): Bool;
    	var wallDown(get, null): Bool;
    	var tileX(get, null): Int;
    	var tileY(get, null): Int;
    	var tileShiftX(get, null): Float;
    	var tileShiftY(get, null): Float;
    
    	var tileSize: FlxPoint = new FlxPoint(32, 32);
    	
    	function get_tileX()
    	{
    		//trace(pivot[0]);
    		
    		return Math.floor((x + width / 2 - environment.levelMap.x) / (tileSize.x * scale.x));
    	}
    	
    	function get_tileY()
    	{
    		return Math.floor((y + width / 2 - environment.levelMap.y) / (tileSize.y * scale.y));
    	}
    	
    	function isTileShiftLeft(): Bool
    	{
    		return (tileShiftX <= this.width / 2);
    	}
    	
    	function isTileShiftRight(): Bool
    	{
    		return (tileShiftX >= tileSize.x - this.width / 2);
    	}
    	
    	function isTileShiftUp(): Bool
    	{
    		return (tileShiftY <= this.height / 2);
    	}
    	
    	function isTileShiftDown(): Bool
    	{
    		return (tileShiftY >= tileSize.y - this.height / 2);
    	}
    	
    	function get_tileShiftX()
    	{
    		//trace(pivot[0]);
    		var x = this.x + this.width / 2;
    		return (x - environment.levelMap.x) % (tileSize.x * scale.x);
    	}
    	
    	function get_tileShiftY()
    	{
    		var y = this.y + this.height / 2;
    		return (y - environment.levelMap.y) % (tileSize.y * scale.y);
    	}
    	
    	function get_edgeLeft()
    	{
    		return isTileShiftLeft() && !isCollider(tileX - 1, tileY + 1, FlxObject.UP) && !wallLeft;
    	}
    	
    	function get_edgeRight()
    	{
    		return isTileShiftRight() && !isCollider(tileX + 1, tileY + 1, FlxObject.UP) && !wallRight;
    	}
    	
    	function get_wallLeft()
    	{
    		return isTileShiftLeft() && isCollider(tileX - 1, tileY, FlxObject.RIGHT);
    	}
    	
    	function get_wallRight()
    	{
    		return isTileShiftRight() && isCollider(tileX + 1, tileY, FlxObject.LEFT);
    	}
    	
    	function get_wallUp()
    	{
    		return isTileShiftUp() && isCollider(tileX, tileY - 1, FlxObject.DOWN);
    	}
    	
    	function get_wallDown()
    	{
    		return isTileShiftDown() && isCollider(tileX, tileY + 1, FlxObject.UP);
    	}
    	
    	function isCollider(tileX: Int, tileY: Int, colliderType: Int): Bool
    	{
    		var map = environment.levelMap;
    		//if (map == null)
    		//	return false;
    		
    		if ((tileX < 0) || (tileY < 0) || (tileX >= map.widthInTiles) || (tileY >= map.heightInTiles))
    			return true;
    		
    		var collisions = map.getTileCollisions(map.getTile(tileX, tileY));
    		return (collisions & colliderType) != 0;
    	}
    

Log in to reply
 

Looks like your connection to HaxeFlixel was lost, please wait while we try to reconnect.