Skip to main content

Part 4: Platforms and Collision

In this part, we'll create platforms for our player to jump on and implement proper collision detection between the player and platform objects.

What We'll Accomplish​

By the end of this part, you'll have:

  • Platform objects with physics bodies
  • Collision detection between player and platforms
  • Proper ground detection for jumping
  • A basic level layout with multiple platforms
  • Contact listener for physics interactions

Prerequisites​

Step 1: Platform Assets​

For platforms, we'll need:

  • platform.png - Simple platform sprite

Add these to your Content folder. You can find these assets in the complete project reference.

Step 2: Create Platform Class​

Create a new file called Platform.cs:

using Cocos2D;
using Box2D.Dynamics;

namespace Platformer
{
public class Platform : CCSprite
{
// Physics body
private b2Body _body;

public Platform(b2World world, float posX, float posY, float width, float height) : base("platform")
{
// Set position and scale to match desired dimensions
this.Position = new CCPoint(posX, posY);
this.ScaleX = width / this.ContentSize.Width;
this.ScaleY = height / this.ContentSize.Height;

// Create physics body
_body = PhysicsHelper.CreateBoxBody(
world,
posX,
posY,
width,
height,
false, // Static body
1.0f, // Density
0.3f, // Friction
0.0f // No bounce
);

// Set collision filtering
b2Fixture fixture = _body.FixtureList;
b2Filter filter = fixture.Filter;
filter.categoryBits = PhysicsHelper.CATEGORY_PLATFORM;
filter.maskBits = PhysicsHelper.CATEGORY_PLAYER;
fixture.SetFilterData(filter);

// Store reference to this platform
_body.UserData = this;
}
}
}

Step 3: Collision Detection System​

Create a contact listener to handle collisions. Create ContactListener.cs:

using Box2D.Collision;
using Box2D.Dynamics;
using Box2D.Dynamics.Contacts;

namespace Platformer
{
public class ContactListener : b2ContactListener
{
public override void BeginContact(b2Contact contact)
{
// Check for foot sensor contacts to enable jumping
object userDataA = contact.GetFixtureA().UserData;
object userDataB = contact.GetFixtureB().UserData;

Player.FootSensorUserData footData = userDataA as Player.FootSensorUserData
?? userDataB as Player.FootSensorUserData;

if (footData != null)
{
footData.Player.SetCanJump(true);
}
}

public override void EndContact(b2Contact contact)
{
// Check for foot sensor contacts to disable jumping
object userDataA = contact.GetFixtureA().UserData;
object userDataB = contact.GetFixtureB().UserData;

Player.FootSensorUserData footData = userDataA as Player.FootSensorUserData
?? userDataB as Player.FootSensorUserData;

if (footData != null)
{
footData.Player.SetCanJump(false);
}
}

public override void PostSolve(b2Contact contact, ref b2ContactImpulse impulse)
{

}

public override void PreSolve(b2Contact contact, b2Manifold oldManifold)
{

}
}
}

Step 4: Level Creation​

Update your GameLayer.cs to create a level with platforms:

private List<Platform> _platforms = new List<Platform>();
private ContactListener contactListener;

protected override void AddedToScene()
{
base.AddedToScene();

// ...existing code

// Set up contact listener for collisions
contactListener = new ContactListener();
_world.SetContactListener(contactListener);

// Create platforms
CreateLevel();

// ...existing code
}

private void CreateLevel()
{
// ...existing code

// Create floor platform
Platform floor = new Platform(_world, visibleSize.Width / 2, 32, visibleSize.Width, 64);
_platforms.Add(floor);
AddChild(floor);

// Create some platforms
Platform platform1 = new Platform(_world, 200, 100, 200, 32);
_platforms.Add(platform1);
AddChild(platform1);

Platform platform2 = new Platform(_world, 600, 100, 200, 32);
_platforms.Add(platform2);
AddChild(platform2);
}

🎯 Checkpoint: Platforms and Collision​

At this point, you should have:

  • ✅ Multiple platforms that the player can stand on
  • ✅ Proper collision detection between player and platforms
  • ✅ Ground detection that allows jumping only when on platforms
  • ✅ A basic level layout with different platform heights
  • ✅ Smooth character movement and jumping

Test your game: Run the project and verify that:

  1. The player can walk on all platforms
  2. The player can jump from platform to platform
  3. The player cannot jump while in mid-air
  4. Collision detection works smoothly without jittering
  5. The player properly lands on platform surfaces

Troubleshooting​

Player falls through platforms: Check that platform physics bodies are created correctly and collision detection is properly set up.

Jumping doesn't work: Verify that ground detection is working and the contact listener is properly registered.

Jittery movement: Adjust physics timestep or add damping to the player's physics body.

Player sticks to walls: Reduce friction between player and platforms, or adjust the collision normal detection logic.

Next Steps​

In Part 5: Game Mechanics, we'll add collectible items, a scoring system, and UI elements to make our platformer more engaging.

Complete Code Reference​

You can find the complete code for this part in the tutorial samples repository.