XNA sous Linux et Mac avec MonoGame

XNA est une Framework de développement génial qui permet de créer des jeux en C# pour Windows, Xbox 360 et Windows Phone 7. Un des défaut du Framework est d’être très lié aux technologies de Microsoft et par conséquant de ne pas fonctionner sur d’autres plateformes. Cela est cependant révolu grâce à MonoGame (et bientôt ExEn), un Framework portable et Open Source calqué sur XNA et qui fonctionne sur une multitude de plateformes grâce au runtime Mono et/ou .Net. Grâce à MonoGame vous pourrez développer vos jeux pour

  • Windows XP, Vista, 7, 8
  • Linux
  • Mac OSX
  • iOS (en utilisant MonoTouch)
  • Android (en utilisant MonoDroid)

L’avantage de MonoGame est d’utiliser les mêmes espaces de noms que XNA, en réalité c’est une réécriture total du Framework de Microsoft pour fonctionner avec OpenGL. En théorie un code XNA peut être recompilé directement avec MonoGame sans aucune modifications (seules les références du projet devront être changées). Par contre attention, pour le moment il n’y a qu’un support pour la 2D et partiellement pour la 3D (depuis la version 2.1). Il peut aussi manquer certaines choses comme le Son (qui n’est pas totalement supporté), le réseau (une autre couche réseau à été implémentée car le service Live de Microsoft est propriétaire), etc…

Prérequis

Pour mettre en place un environnement de développement MonoGame c’est à la fois simple et complexe.. Le gros problème du Framework est posé par les nombreuses dépendances requises à son fonctionnement. En effet, MonoGame à besoin de

  • Tao.Sdl.dll (qui a besoin de la bibliothèque native SDL)
  • OpenTK.dll (qui a besoin d’OpenGL pour fonctionner et OpenAL)
  • Libgren.Network

A cela il faut bien évidement ajouter le runtime Mono et ses paquets de développement (sauf sous Windows où le .Net Framework sera/(pourra être) utilisé.

Une fois toutes ces dépendances installées, un projet de base est très facile à mettre en place. Sous Linux ou Mac nous utiliserons MonoDevelop qui nous fournira les outils pratiques tel que la completion et la compilation en un clic. Sous Windows vous pourrez utiliser au choix Visual Studio, MonoDevelop ou SharpDevelop.

Compilation de MonoGame

La première chose à faire est de compiler MonoGame pour votre plateforme, je vous propose la démarche qui fonctionne sous Windows et Linux (surement sur Mac aussi mais je n’ai pas de Mac).

  1. Télécharger les sources de MonoGame
  2. Télécharger la dernière version d’OpenTK

MonoGame est livré sous forme d’une archive, il faut dans un premier temps la décompresser, une fois que cela est fait il faut faire la même chose avec OpenTK (qui est livrée déjà compilé). Je vous recommande de prendre une version nightly d’OpenTK (le lien que je fournis). Une fois que vous avez tout téléchargé et décompressé, ouvrez la solution de MonoGame qui vous intéresse.

Le problème que vous allez rencontrer est que la référence vers OpenTK est manquante et il faut simplement la remplacer avec la version d’OpenTK que vous venez de décompresser. La manipulation en image :

On supprime la référence qui n'existe pas
On utilise la version fraîchement téléchargée d'OpenTK

Attention, avec MonoDevelop il faut bien cliquer sur « add » pour que la référence soit ajoutée à la solution. Il ne reste plus qu’à construire MonoGame, je vous conseil de la construire en mode release (le mode debug ne nous intéresse pas ici car nous ne n’allons pas faire de débogage sur la lib MonoGame).

Rendez vous maintenant dans le dossier bin/Release où vous trouverez 6 fichiers .dll que nous devront ajouter à la solution de notre projet de jeu.

GamepadBridge.dll, GamepadConfigControls.dll et Tao.Sdl.dll sont utilisées pour la gestion du joystick et du pad Xbox 360.

Lidgren.Network.dll permet d’utiliser certaines fonctionnalités réseau

MonoGame.Framwork.{Linux/Windows/Mac}.dll est la dll qui permettra à votre jeu de fonctionner sous Linux, Windows, Linux, iOS, Android

OpenTK.dll est la bibliothèque qui permet d’utiliser OpenGL en C# et qui est donc utilisée par MonoGame pour gérer l’affichage entre autre.

Création d’un projet standard

Pour créer un projet de base il n’y a rien de plus simple, dans un premier temps nous créons un nouveau projet « console » et nous ajoutons les références suivantes :

  • GamepadBridge.dll (fournis par MonoGame)
  • GamepadConfigControls.dll (fournis par MonoGame)
  • Lidgren.Network.dll (fournis par MonoGame)
  • MonoGame.Framwork.{Linux/Windows/Mac}.dll
  • OpenTK.dll
  • Tao.Sdl.dll
  • System (Fournis par Microsoft/Mono de base)

La bonne pratique est de se créer un dossier « externals » à la racine de votre projet avec des fichiers dll et de les ajouter via l’éditeur de référence de votre EDI.

La prochaine étape va être de créer 2 classes C#, donc 2 fichiers. Nous ferons comme Microsoft et nous créerons

  1. Program.cs (qui contiendra la méthode Main)
  2. Game1.cs (le fichier contenant votre jeu)

Contenu de Program.cs

using System;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MonoGameTutorial
{
    static class Program
    {
        private static Game1 game;

        [STAThread]
        static void Main()
        {
            game = new Game1();
            game.Run();
        }
    }
}

Là c’est très classique et je pense que ça se passe de commentaires 😉 On créé une instance de Game1 et on lance le jeu.

Contenu de Game1.cs

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

namespace MonoGameTutorial
{
  public class Game1 : Game
  {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    public Game1 ()
    {
      graphics = new GraphicsDeviceManager(this);
      Content.RootDirectory = "Content";

      graphics.PreferredBackBufferWidth = 640;
      graphics.PreferredBackBufferHeight = 480;
      graphics.IsFullScreen = false;

      Window.Title = "Tutoriel MonoGame 0";
    }

    protected override void Initialize()
    {

      base.Initialize();
    }

    protected override void LoadContent()
    {

      base.LoadContent();
    }

    protected override void UnloadContent()
    {

      base.UnloadContent();
    }

    protected override void Update(GameTime gameTime)
    {

      base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
      graphics.GraphicsDevice.Clear(Color.AliceBlue);

      base.Draw(gameTime);
    }
  }
}

Comme vous pouvez le remarquer c’est exactement le même contenu que le fichier de base généré par Visual Studio lorsque l’on créé une projet XNA.

La classe dérive de Game et peut être vue comme le coeur du jeu, elle contient plusieurs méthodes que nous allons détailler tout de suite.

La méthode Initialize() permet d’initialiser vos objets

la méthode LoadContent() est utilisée pour charger votre contenu. Le contenu peut être du son, des textures, des fichiers XML, etc… tout cela est stocké dans le dossier Content qui doit être présenté à côté de l’exécutable de votre jeu. Par défaut il n’existe pas et il faudra le créé après la compilation (avec vos ressources dedans bien entendu 😉 ).

La méthode UnloadContent() est appelée quand votre jeu se termine, c’est là que l’on va libérer les ressources prises par vos objets (graphique, son, etc…)

La méthode Update(GameTime gameTime) servira à mettre à jour la logique du jeu. Donc typiquement on y exécutera des tests relatifs au déplacement du personnage par exemple. Cette méthode est appelée en boucle.

En la méthode Draw(GameTime gameTime) est appelée en boucle elle aussi (tout de suite après Update) et c’est ici qu’on affichera les éléments visuels du jeu (Sprites, modèles 3D, effets, etc…)

Et la suite

Background, Sprite et déplacement clavier

La suite ce sera pour un prochain article et voilà ce que nous réaliserons 😉