Particle follower with CocosSharp and Xamarin.Forms

CocosSharp is a library for building 2D games using C# and F#. It is a .NET port of the popular Cocos2D engine. I wanted to play around with this library for a while and came up with a very simple demo to get a basic understanding of it.

This demo shows how to create a Particle follower. Simply drag your finger across the screen and a particle explosion will occur! You can view the source on Github if you directly want to dive into the code. Otherwise, read on and learn how to build a particle follower using the CocosSharp 2D Game Engine and Xamarin.Forms to build a beautiful cross-platform app.

The goal

The goal is to create a neat particle follower that follows your fingers around on the phone when you touch it. Although it’s not very useful, it’s beautiful to look at and will help you get your first steps into development with CocosSharp.

Play around with the source to change colors, speed and more!

Getting started

I’ll use Xamarin.Forms as starting point. Simply add the CocosSharp.Forms NuGet package to all Projects (iOS, Android and .NET Standard).

Once we got that in place, let’s move on!

Device specific variables

First, we’ll need to determine the size of the screen so we’ll be able to use it later. Since that differs for each device, we’ll need to request the OS to pass along that value to Xamarin.Forms. Add the following to the App.cs-file.

public partial class App : Application {
    public static int Height { get; set; }
    public static int Width { get; set; }
    public static int Density { get; set; }

To fill these values, we’ll need to add them in the OS specific solutions. For iOS, this means changing the AppDelegate.cs.

public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
    App.Height = (int)UIScreen.MainScreen.Bounds.Height;
    App.Width = (int)UIScreen.MainScreen.Bounds.Width;
    App.Density = (int)UIScreen.MainScreen.Scale;

And for Android, we’ll need to update the MainActivity.cs.

protected override void OnCreate(Bundle bundle) {
    var metrics = Resources.DisplayMetrics;
    App.Width = (int) metrics.WidthPixels / metrics.Density;
    App.Height = (int) metrics.HeightPixels / metrics.Density;
    App.Density = (int) metrics.Density;

Now that we got these values inside of Xamarin.Forms, we can move on!

The view

CocosSharp uses a CCGameView in order to work. We’ll wrap that inside of a Xamarin.Forms ContentView. I called this the ParticlesView.

public class ParticlesView : ContentView {
    ParticlesScene _scene;

    public ParticlesView() {
        var sharpView = new CocosSharpView {
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand,
            ViewCreated = HandleViewCreated
        Content = sharpView;

    void HandleViewCreated(object sender, EventArgs e) {
        var ccGView = sender as CCGameView;
        if (ccGView != null) {
            ccGView.DesignResolution = new CCSizeI(App.Width, App.Height);
            _scene = new ParticlesScene(ccGView);

A couple of things that I’d like to point out:

  • ViewCreated – This is the event when the element is placed which we’ll use to draw the CCGameView
  • DesignResolution – Here you see why we need the App.Width and App.Height to determine the dimensions to draw on
  • RunWithScene – CocosSharp uses a CCScene to run the application, which we’ll create in the next step

Add a scene with particles

The scene is the piece of code that’ll actually draw the different particles on a CCLayer. Let’s see how the ParticlesScene looks like!

public class ParticlesScene : CCScene {
    CCLayer _layer;
    public ParticlesScene(CCGameView gameView) : base(gameView) {
        _layer = new CCLayer();

    public void DrawParticle(CCPoint point) {
        var explosion = new CCParticleExplosion(CCPoint.Zero) {
            TotalParticles = 10,
            StartColor = new CCColor4F(CCColor3B.White),
            EndColor = new CCColor4F(CCColor3B.Black),
            Position = new CCPoint(point.X / App.Density, App.Height - point.Y / App.Density)

The DrawParticle-method will be called later on to draw the particles. CocosSharp comes with a couple of built-in Particles, like CCParticleFire and CCParticleSmoke. In this demo, we’ll be using the CCParticleExplosion but you can play around with these values as well. Just play around with these variables do have more fun!

Enable touch

Update the HandleViewCreated-method of the ParticlesView and add an CCEventListenerTouchOneByOne to enable listening to touch events. From here, we’ll call the DrawParticle-method.

_scene = new ParticlesScene(ccGView);
var touchEvent = new CCEventListenerTouchOneByOne();
touchEvent.OnTouchBegan = (touch, _event) => {
    return true;
touchEvent.OnTouchMoved = (touch, _event) => {

Finally, update the MainPage.xaml to use the new view and you’re ready to go!

<ContentPage xmlns:local="clr-namespace:Particles" x:Class="Particles.MainPage">
        <local:ParticlesView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />

Conclusion & Download

Although the sample is pretty simple, it gives me a basic understanding of CocosSharp. The outcome looks pretty good and is fun to play around with! Since the Android Emulator supports multi-touch, we can even check how amazing that looks.

Take note there’s a discussion on where the future of CocosSharp as well as Cocos2d is going. What do you think? Let me know in the comments or on Twitter and feel free to improve the code.

Further reading:

2 comments On Particle follower with CocosSharp and Xamarin.Forms

  • Is there someway we could implement this functionality in a pre-existing Xamarin Forms app, so if the consumer tapped on a button/field there would be an explosion of particles (implementing it at the content page level)?

    • Absolutely! The ParticlesView is just a Xamarin.Forms ContentView, so if the Scene is already created you can easily pass along any action from the ContentPage downwards. Good luck!

Leave a reply:

Your email address will not be published.

Site Footer