Skip to main content

Part 5: Game Mechanics

In this part, we'll add game mechanics that make our platformer engaging: collectible coins, a scoring system, and user interface elements.

What We'll Accomplish

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

  • Collectible coin objects with physics
  • A scoring system that tracks collected coins
  • UI elements displaying score and other game information
  • Win condition when all coins are collected
  • Sound effects for collecting coins
  • Level completion detection

Prerequisites

Step 1: Collectible Assets

You'll need these assets for collectibles:

  • coin.png - Coin sprite
  • coin_pickup.wav - Collection sound effect (optional)

Add these to your Content folder. Find them in the complete project reference.

Step 2: Create Collectible Class

Create a new file called Collectible.cs:

using Cocos2D;
using Box2D.Dynamics;
using Box2D.Common;
using Box2D.Collision.Shapes;
using CocosDenshion;

namespace Platformer
{
public class Collectible : CCSprite
{
private b2Body _body;

public Collectible(b2World world, float x, float y) : base("coin")
{
Position = new CCPoint(x, y);

// Create physics body
b2BodyDef bodyDef = new b2BodyDef();
bodyDef.type = b2BodyType.b2_staticBody;
bodyDef.position = new b2Vec2(x / PhysicsHelper.PTM_RATIO, y / PhysicsHelper.PTM_RATIO);

_body = world.CreateBody(bodyDef);

// Create circle shape for collectible
b2CircleShape shape = new b2CircleShape();
shape.Radius = ContentSize.Width * 0.3f / PhysicsHelper.PTM_RATIO;

b2FixtureDef fixtureDef = new b2FixtureDef();
fixtureDef.shape = shape;
fixtureDef.isSensor = true; // Make it a sensor (no collision response)
fixtureDef.filter.categoryBits = PhysicsHelper.CATEGORY_COLLECTIBLE;
fixtureDef.filter.maskBits = PhysicsHelper.CATEGORY_PLAYER;

_body.CreateFixture(fixtureDef).UserData = this;

// Add a rotation action
RunAction(new CCRepeatForever(new CCRotateBy(2.0f, 360)));
}

public void Collect(GameLayer gameLayer)
{
// Remove from physics world
_body.World.DestroyBody(_body);
_body = null;

// Play collection animation
RunAction(new CCSequence(
new CCScaleTo(0.2f, 1.5f),
new CCScaleTo(0.2f, 0.0f),
new CCCallFunc(() => RemoveFromParent())
));

// Play collection sound
CCSimpleAudioEngine.SharedEngine.PlayEffect("coin_pickup");

// Increase score
gameLayer.IncreaseScore(10);
}
}
}

Step 3: Update Contact Listener

Update your ContactListener.cs to handle coin collection:

// Add this to the BeginContact method in ContactListener.cs
public override void BeginContact(b2Contact contact)
{
// ...existing code

// Check for collectible contacts
CheckCollectibleContact(contact.GetFixtureA(), contact.GetFixtureB());
CheckCollectibleContact(contact.GetFixtureB(), contact.GetFixtureA());
}

private void CheckCollectibleContact(b2Fixture fixtureA, b2Fixture fixtureB)
{
// Check if fixA is a collectible and fixB is the player
Collectible collectible = fixtureA.UserData as Collectible;
if (collectible != null &&
fixtureB.Filter.categoryBits == PhysicsHelper.CATEGORY_PLAYER)
{
// Get the game layer from the player's parent
Player.FootSensorUserData playerNode = fixtureB.UserData as Player.FootSensorUserData;
if (playerNode != null && collectible.Parent is GameLayer gameLayer)
{
collectible.Collect(gameLayer);
}
}
}

Step 4: Update GameLayer

Update your GameLayer.cs to include collectibles:

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

// Create collectibles
for (int i = 0; i < 3; i++)
{
Collectible coin = new Collectible(_world, 200 + i * 200, 200);
AddChild(coin);
}
}

🎯 Checkpoint: Game Mechanics

At this point, you should have:

  • ✅ Collectible coins placed throughout the level
  • ✅ Working score system that updates when coins are collected
  • ✅ UI showing current score and coin collection progress
  • ✅ Sound effects for collecting coins (if audio files are included)

Test your game: Run the project and verify that:

  1. Coins appear on platforms and animate (rotate and bob)
  2. Walking into coins collects them and increases score
  3. UI updates correctly showing score and coin count

Troubleshooting

Coins not collecting: Check that contact listener is handling sensor collisions correctly.

UI not updating: Verify that event handlers are properly connected to GameManager events.

Sound not playing: Ensure audio files are added to Content folder with proper build action.

Complete Code Reference

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

Congratulations! 🎉

You've successfully created a complete 2D platformer game using cocos2d-mono! Your game features:

  • Physics-based gameplay with Box2D integration
  • Smooth character controls with jump mechanics
  • Collectible system with scoring
  • Professional polish with effects and animations
  • Complete game states from menu to gameplay
  • Audio integration for immersive experience

Next Steps for Enhancement

Consider adding these features to further improve your game:

  • Multiple levels with different layouts
  • Enemy characters with AI
  • Power-ups and special abilities
  • Better sprite artwork and animations
  • Level editor functionality
  • Achievements and high scores
  • Mobile touch controls

Final Complete Code Reference

The complete, final project with all assets can be found in the tutorial samples repository.

Thank you for following this tutorial series! You now have the foundation to create more complex 2D games with cocos2d-mono.