Journal Gamedev Framework 0.2.0

Posté par  (Mastodon) . Licence CC By‑SA.
Étiquettes :
36
14
oct.
2016

Sommaire

Gamedev Framework (gf) est un framework de développement de jeu vidéo 2D en C++11. Il est basé sur SDL et OpenGL ES 2.0 et s'inspire très largement de l'API du module graphique de SFML avec quelques différences mineures et surtout en ajoutant des fonctionnalités non-présentes dans SFML.

J'avais présenté la version 0.1.0 dans une dépêche, et plus précisément l'histoire de gf. Aujourd'hui, à l'occasion de la sortie de la version 0.2.0, je vais présenter les fonctionnalités que vous pourrez trouver dans gf et pas dans SFML.

Dessine moi un mouton

Pour dessiner, SFML propose deux façons de faire. Premièrement, la classe RenderTarget fournit une méthode générique qui utilise des vertex. Dans ce cas, il faut construire la géométrie de ce qu'on veut dessiner et l'envoyer à SFML qui va se charger d'envoyer tout ça à OpenGL. Deuxièmement, parce qu'il y a quand même des cas qui reviennent souvent, SFML propose des Drawable, c'est-à-dire des géométries prédéfinis. On va retrouver des formes classiques : rectangle, disque, polygone régulier, forme convexe générique. Et surtout, la classe Sprite qui permet de dessiner un bout d'image et la classe Text qui permet d'afficher du texte. Bref, juste le minimum.

Dans gf, tout ça existe aussi, mais il y a d'autres Drawable. Il y a des formes supplémentaires : le rectangle au bord arrondi, l'étoile. Il y a aussi des courbes ! Rien de bien original, juste des classiques : ligne droite, courbes de Bézier quadratique et cubique, et puis des courbes composées de plusieurs morceaux des courbes précédentes. gf offre aussi des sprites animés et deux cas particuliers bien pratiques : le Nine-Patch et la couche de tuile (tilelayer).

Un Nine-Patch est une image qu'on peut étirer en son milieu. C'est pratique pour créer des boutons, parce qu'on n'a besoin que d'une seule image pour toutes les tailles. gf permet d'afficher un Nine-Patch facilement. Quant à la couche de tuile, c'est un cas particulier qui revient souvent. Dès qu'on veut afficher un fond composé de tuiles (qu'on a construit avec Tiled par exemple), on peut se taper tout le boulot à la main et SFML fournit même un tutoriel pour ça. Ou alors, on crée une classe générique qui fait tout le boulot correctement. Dans les trucs un peu délicat, il y a le calcul de la portion à afficher en prenant en compte les rotations de vue par exemple. Je préfère nettement avoir un code générique dans une bibliothèque plutôt que devoir (mal) refaire à chaque fois.

Interface en mode immédiat

Un ajout important de la version 0.2.0 est une API pour faire des interfaces en mode immédiat. C'est quoi le mode immédiat ? C'est une méthode alternative pour faire des interfaces graphiques. Plutôt que d'avoir des classes, un widget est représenté par une fonction (ou plutôt une méthode d'un contexte). Par exemple, on appelle une fonction button qui va afficher un bouton et renvoyer un booléen qui indique si le bouton a été pressé. En fait, souvent, la fonction n'affiche pas directement le bouton, elle va mettre des commandes de dessin dans une file. À la fin, la file de commandes peut être lue pour afficher effectivement les widgets. L'avantage des interfaces en mode immédiat, c'est qu'on peut insérer le code de l'interface n'importe où, et notamment on n'a pas à dupliquer l'état du modèle, la vue peut utiliser directement les données du modèle. Le mode immédiat est bien adapté pour faire des petits outils rapides.

Souvent, les bibliothèques d'interface en mode immediat (imgui pour les intimes) ne proposent pas directement d'afficher les widgets, ce qui les rend assez agnostiques. D'un autre côté, il est nécessaire d'avoir un peu de glue avec son système d'affichage préféré pour que ça fonctionne. La plus connue des bibliothèque imgui est Dear Imgui : 1400 lignes d'en-tête, 10000 lignes de source, le tout dans un seul fichier à chaque fois (pratique à intégrer dans un projet).

Pour gf, j'ai décidé de partir d'une bibliothèque plus simple. J'ai tout encapsulé proprement dans une classe, et j'ai même amélioré le bouzin avec un système basique de style. Et j'ai ajouté un widget de cycle parce que je trouvais que ça manquait. Évidemment, dans mon cas, comme j'ai un système d'affichage sous la main, j'ai caché la file de commande, mais elle est bien là. Voilà ce que ça donne.

imgui

Faites du bruit !

Comme vous le savez, j'adore le bruit ! Et comme la génération procédurale, c'est à la mode et que le bruit cohérent fait partie des outils de base pour la génération procédurale, j'ai ajouté les principaux bruits que j'avais implémenté dans MapMaker. Et j'en ai profité pour ajouter les versions 3D (à l'exception de celles qui sont couvertes par un brevet).

Et puis, j'avais envie de créer une petite interface pour créer du bruit avec plein de paramètres. Et comme j'avais désormais à ma disposition une bibliothèque imgui, j'ai créé un outil.

gf_noise

J'ai prévu d'ajouter d'autres bruits un peu plus tard.

Du pain et des jeux

Finalement, j'ai ajouté des exemples de jeux. Parce que c'est encore la meilleure manière de voir comment on utilise la bibliothèque. J'ai mis un pong et un 2048 qui sont des exemples suffisamment simples pour être compréhensible facilement.

gf_pong gf_2048

Et j'ai également mis Huaca, un jeu que j'avais réalisé (avec une équipe) pour la Global Game Jam 2016. Ce jeu est un peu plus complexe et permet de voir l'utilisation de fonctionnalités avancées (comme les couches de tuiles).

Huaca

Conclusion

J'aimerais bien continuer à faire des sorties tous les 3 mois, donc rendez-vous sans doute le 14 janvier pour la version 0.3.0. J'espère pouvoir avancer sur Akagoria également. J'ai mis deux jours à porter Akagoria depuis SFML vers gf.

  • # Mode boulet

    Posté par  (Mastodon) . Évalué à 10.

    J'ai oublié le principal : mettre quelques liens vers le projet !

  • # Ça semble bien

    Posté par  . Évalué à 6.

    Je n'ai aucune expérience dans le développement de jeux, mais ce que tu as fait semble intéressant.

    Il y a une raison pour laquelle tu ne contribues pas directement à SFML (ou autre) pour y ajouter ton travail ?

    • [^] # Re: Ça semble bien

      Posté par  (Mastodon) . Évalué à 7.

      Oui, il y a une raison, je l'avais expliqué un peu dans la dépêche. La raison principale, c'est le conservatisme du principal mainteneur sur les évolutions possibles (y compris des évolutions triviales) et le fait qu'il refuse d'accepter que SFML est utilisée à 99% pour des jeux (et donc il refuse tout ce qui est lié à la programmation des jeux).

  • # Moteur physique?

    Posté par  (site web personnel) . Évalué à 7.

    Est-ce que l'intégration de moteurs physiques (réaliste, arcade…) est prévu?

    Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

    • [^] # Re: Moteur physique?

      Posté par  (Mastodon) . Évalué à 5.

      Non, pas directement.

      En revanche, je vais essayer d'intégrer des algorithmes de détection de collisions. Il y a déjà les plus basiques (cercle/cercle, rectangle/rectangle, cercle/rectangle), j'aimerais ajouter la collision entre deux polygones convexes quelconques (l'algorithme GJK). Je pense que ça peut permettre de faire pas mal de choses déjà. Mais pour toute la partie simulation physique, je ne me sens pas compétent. Et à titre personnel, je préfère utiliser Box2D si j'ai une simulation complexe à faire. D'ailleurs, je ne vois pas bien ce que peut être un moteur physique arcade.

      • [^] # Re: Moteur physique?

        Posté par  (site web personnel) . Évalué à 4.

        D'ailleurs, je ne vois pas bien ce que peut être un moteur physique arcade.

        C'est ce dont on a besoin pour la plupart des jeux (Action RPG, shoot them up, beat them all, plateformes…).

        Regarde les moteurs Arcade et Ninja de Phaser ( http://phaser.io/docs/2.6.2/index#arcadephysics ).

        Je trouve ça souvent plus pratique que de tordre un moteur réaliste comme box2d pour avoir un rendu oldschool.

        Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

        • [^] # Re: Moteur physique?

          Posté par  (Mastodon) . Évalué à 3.

          Haaa ! En fait, je ne mettrais pas tous ces cas là dans le même panier.

          Par exemple, pour les jeux à gravité nulle (en vue de 3/4 ou vue de dessus typiquement : ARPG, Shoot Them Up, etc), une simple détection de collision suffit. Pour Huaca, j'ai uniquement utilisé la détection de collision déjà présente dans gf en modélisant les murs, le héros et les objets avec des rectangles alignés sur les axes. Par exemple, pour les murs, si le héros entre dans un mur, je déplace le héros hors du mur. Je n'appelle pas ça de la physique vraiment, et ça suffit amplement. Il peut y avoir des cas un peu plus complexes où tu dois avoir des rectangles non-alignés sur les axes. J'avais fait un jeu où il y avait une voiture qui se baladait dans un décor, il m'aurait fallu une collision entre forme convexe quelconque, je ne l'avais pas donc j'ai pris Box2D. Mais pareil, ça peut se régler uniquement avec de la détection de collision en première approximation.

          Pour les jeux à gravité non-nulle (typiquement les plateformers), il y a un peu plus de boulot mais guère plus. Si tu veux un truc ultra-simple, tu dois juste appliquer les lois de Newton (huhu) à ton héros et faire le calcul à chaque tour de boucle, c'est à peu près 3 lignes à ajouter, pas vraiment besoin d'un moteur physique, je suis d'accord. Tu peux même faire que ton héros traverse les plateformes en montant en vérifiant juste la direction de la normale qui est renvoyée par ta collision. Je peux éventuellement faire un tutoriel là dessus, ça peut être une bonne idée tiens.

          • [^] # Re: Moteur physique?

            Posté par  (site web personnel) . Évalué à 4.

            Je suis en train de travailler sur un futur jeu avec Phaser et ce genre de fonctionnalité fait toute la différence: c'est peut être simple, mais ça permets de gagner des heures de boulot. Pour prototyper ou tester une idée, c'est bien d'avoir pleins choses toutes prêtes sous la main.

            Pour éviter de bloater ton moteur, tu peux en faire des greffons.

            Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

            • [^] # Re: Moteur physique?

              Posté par  (Mastodon) . Évalué à 2.

              Je préfère tout intégrer qu'avoir des greffons. C'est un framework, c'est le principe d'avoir plein de briques de base. Je vais voir ce que je peux faire, je vais jeter un œil du côté de Phaser pour savoir comment ils modélisent leur truc. Mais ça me semble faisable sans que ça devienne un vrai moteur physique complet.

            • [^] # Re: Moteur physique?

              Posté par  (Mastodon) . Évalué à 3.

              Du coup, j'ai regardé hier soir. Pour un moteur simple, le moteur physique Arcade de Phaser est quand même assez complexe, je trouve. 1214 + 355 + 1788 sloc (donc sans les commentaires), ça fait quand même pas mal. Les seules simplifications par rapport à Box2D, c'est qu'il n'y a pas de joints. Je crois que tout le reste y est.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.