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
- Completed Part 4: Platforms and Collision
- Understanding of UI elements in cocos2d-mono
- Basic game state management concepts
Step 1: Collectible Assets
You'll need these assets for collectibles:
coin.png
- Coin spritecoin_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:
- Coins appear on platforms and animate (rotate and bob)
- Walking into coins collects them and increases score
- 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.