Unity et C#
C et API Gamebuino
Irrlicht et C++
C++, OpenNI et OpenGL
PHP/SQL et HTML/CSS/Javascript
C++ et OpenGL
Blender
C++ et OpenGL
C++
C++ et OpenCV
Qt et C++
C++ et OpenGL
C
C
Il m'arrive souvent de ressortir mon vieux Rubik's Cube du placard pour voir si j'arrive toujours à le résoudre.. Et puis un jour je me suis dis que ça pourrait être mon prochain projet personnel. Je me suis donc lancé dans la création d'une simulation d'un Rubik's Cube 3x3 avec Unity.
J'ai commencé par créer les éléments 3D (cubes et couleurs), placer la caméra et ajouter des colliders sur les faces visibles du cube pour pouvoir intéragir avec la souris. J'ai ensuite ajouté quelques éléments d'UI (boutons pour mélanger et pour tourner le cube). A partir de là, j'ai pu programmer la partie visuelle du mouvement du cube (rotation de la face au clic de la souris ou du cube entier lors de l'appui sur les boutons fléchés). J'ai eu quelques difficultés à gérer la rotation des éléments les uns par rapport aux autres, mais j'ai fini par trouver une solution en faisant changer les cubes de parent dans la hiérarchie de la scène juste avant de lancer la rotation. J'ai ensuite restreint les inputs souris à attendre la fin de la rotation en cours avant d'accepter une autre requête, grâce à une machine à état.
Un peu plus tard, je me suis attaqué à la partie "logique" du cube, qui m'a donné du fil à retordre. Je voulais réussir à trouver une solution très générique me permettant par exemple de faire également fonctionner un cube 2x2, mais peu importe la façon dont je tournais le problème dans ma tête je ne trouvais pas de solution. J'ai fini par aboutir à une solution très spécifique au cube 3x3, mais qui avait le mérite de fonctionner parfaitement (si vous voulez en savoir plus, je vous invite à aller voir le code source sur mon GitHub).
Enfin, j'ai décidé d'ajouter un outil permettant de jouer directement une séquence de rotations, permettant notamment aux pros du Rubik's Cube de le résoudre grâce à des algorithmes.
J'ai ajouté un effet de highlight, un écran de victoire, quelques animations, changé quelques couleurs... et tada ! Voilà mon Rubik's Cube fini et prêt à être partagé avec la communauté.
Version émulée jouable sur mon itch.io. Code source disponible sur mon GitHub
J'ai reçu la Gamebuino META comme cadeau et je cherchais depuis déjà quelques temps une idée de jeu à créer avec l'API proposé par Gamebuino. J'ai finalement opté pour la création d'un premier niveau de ce que j'ai baptisé Slide'n'Ride. Le jeu consiste à faire passer le carré bleu sur toutes les cases blanches au moins une fois, sans passer plus de 3 fois par la même case. Seulement, le sol est gelé et le carré glisse d'un mur à l'autre alors.. ce n'est pas si facile !
L'idée m'est venue de mes souvenirs de Pokémon version Argent, jeu dans lequel on passe par une grotte dont le sol gelé glissant nous obligeait à nous casser la tête pour trouver le bon chemin.
Ce projet était plutôt court à réaliser (5h) mais j'ai pu expérimenter ce à quoi devait ressembler la programmation de jeux vidéo d'il y a quelques dizianes d'années, ce qui n'a fait que m'émerveiller d'autant plus sur les jeux que l'on est capables de créer aujourd'hui. En effet bien que l'API Gamebuino permette d'afficher des pixels, des rectangles ou du texte, le niveau d'abstraction reste très bas par rapport à de la programmation sous Unity.
Version émulée jouable sur le site de Gamebuino. Code source disponible sur mon GitHub
Lors du module "Jeux vidéo", nous avons pu découvrir le moteur de jeu Irrlicht dont la version 1.0 date de 2006. Il a l'avantage d'être Open Source et cross plateforme, mais n'offre pas beaucoup de fonctionnalités déjà développées. C'était idéal pour se rendre compte de l'évolution faite avec les moteurs de jeux plus récents comme Unity ou Unreal.
Il nous a été demandé de coder avec C++ et en utilisant Irrlicht, un jeu vidéo de notre choix, par binôme, en 16h. J'ai travaillé avec Pedro Foletto-Pimenta sur ce projet, et nous avons eu l'idée de créer une version minimaliste du très célèbre Tekken 3 (sorti par Namco sur Playstation en 1998).
Le jeu se présente donc sous la forme d'une arène de combat où s'affrontent deux personnages contrôlés par les deux joueurs (pas d'IA disponible). Le but est de gagner sortir vainqueur de 2 manches en mettant son adversaire K.O. ou en ayant plus de vie à la fin du temps imparti. Pour combattre, on peut utiliser les flèches directionnelles pour se déplacer ou esquiver, et les touches d'attaque pour donner un coup de pied ou un coup de poing.
Les animations ont été réalisées sous Blender : après avoir chargé un modèle disponible sur internet, je lui ai appliqué rigging, skinning et mouvements, puis j'ai importé le modèle sous un format Direct X avec Irrlicht.
Ce projet a été idéal pour se confronter aux difficultés que l'on pouvait rencontrer en codant un jeu vidéo. En effet, j'ai appris comment insérer des animations, comment gérer l'écoulement du temps dans le jeu et également comment contrôler la caméra. Ce type de programmes devant afficher en permanence quelque chose, il a fallu réfléchir aux différentes variables d'état, et aux gestions de l'interaction avec le clavier pour garder une bonne fluidité.
Version disponible sur mon GitHub
Avec Edouard Mior et Théo Leplomb, j'ai participé à la création de notre application Air Drums lors du projet de majeure de 96h. Durant ce projet, nous avons décidé de travailler avec la caméra Kinect de Microsoft pour créer une batterie virtuelle, à laquelle nous pouvons jouer avec les mains. Notre idée a ensuite évolué jusqu'à donner un jeu rythmique ressemblant à Guitar Hero ou Rock Band, mais utilisant la caméra comme interaction.
La librairie de la Kinect possède un API assez complet sur la détection et le suivi des positions de la main une fois celle-ci détectée (par un mouvement de poussée par exemple). Nous avons ensuite créé 5 zones qui correspondent aux emplacements des éléments de batterie. Rentrer avec sa main dans ces zones en appliquant un mouvement de haut en bas active alors la détection.
Ensuite, nous avons ajouté la partie sonore, avec la librairie Fmod. En créant un nouveau thread à chaque fois que la main est détectée dans une zone, nous avons pu jouer les sons correspondant. Finalement, la partie d'affichage des modèles 3D avec OpenGL a été la plus longue et complexe. Une fois la position adaptée par rapport aux zones de détections définies précédemment, nous avons fait en sorte de jouer avec la transparence afin de donner à l'utilisateur l'impression de frapper quelque chose.
Pour la version 2.0, nous avons ajouté des baguettes tombant pour indiquer le rythme à suivre, ainsi qu'une musique de fond (par manque de temps pour notre présentation, le rythme d'apparition des baguettes était codé à la main et correspondait à la musique).
Etant un grand fan de football, et pour suivre la coupe du monde 2018 de manière un peu plus excitante, je voulais participer à des paris entre amis. Comme je n'ai pas trouvé une formule qui m'intéressait sur internet, je me suis mis au défi de programmer dans mon temps libre un site de paris entièrement avec PHP/SQL et HTML/CSS. J'ai été aidé par Claire Poinsignon pour le design des différentes pages et de l'application en globalité, ainsi que l'intégration mobile.
Après avoir créé un compte et s'être connecté, on arrive sur la page principale, contenant un rappel des scores des 5 derniers matchs :
Puis après avoir fait ses paris pour la phase suivante dans l'onglet "Betting", on les voit apparaître dans l'onglet "Results". En passant la souris sur nos paris, on peut afficher le résultat réel du match et confronter notre résultat.
Enfin, si l'on a rejoint un groupe avec des amis ou de la famille, on peut vérifier son classement dans l'onglet "Ranking"
La programmation de ce site web m'a fait beaucoup progressé en langages du web et m'a aussi montré ce qu'était l'administration d'un site (hébergement, sauvegardes de database, bugs). Mes erreurs m'ont permis d'apprendre et finalement le site a été utilisé par une cinquantaine de personnes dont certaines que je ne connaissais même pas. Et puis, la France a gagné la coupe alors... ça ne pouvait que bien se passer !
Le lien : https://www.besstfriends.com
Pendant les cours de programation GPU, nous avons appris à utiliser OpenGL et les shaders afin d'afficher des maillages texturés avec une illumination de type Phong.
Après avoir maîtrisé l'utilisation de fragment shader et vertex shader, nous avons étudié des outils plus complexes comme les Frame Buffer Object (FBO), le Transform Feedback ...
Nous avons appris à utiliser les geometry shaders pour afficher les normales d'un maillage, effectuer un culling (n'afficher que les triangles visibles du point de vue de la caméra), ou encore déformer totalement un maillage :
Nous avons enfin mis toutes ces connaissances en application dans le cours de shaders avancés, où nous avons vu notamment l'effet parallax et l'algorithme des marching cubes. Nous avons pu avec une carte des normales et des profondeurs, ajouter un effet de relief à une texture de mur de briques, et également à partir d'une fonction de densité créer une forme de roche très complexe :
J'ai choisi de suivre un module optionnel enseignant l'utilisation du logiciel Blender, à travers des tutoriaux et un rendu final. Pour ce rendu, j'ai décidé de modéliser Sonic le fameux personnage de SEGA.
J'ai commencé par télécharger une feuille détaillée des différents points de vue de Sonic, et j'ai créé son modèle vertex après vertex. Je me suis également aidé de vidéos Youtube m'indiquant certains détails simplifiant le travail. J'ai également ajouté de la couleur aux différents éléments du modèle.
Finalement, je lui ai ajouté un squelette et des poids de skinning pour modifier sa posture et créer une animation.
Pendant les cours d'animation, nous avons appris à appliquer des poids de skinning à nos maillages et à les déformer de manière à obtenir une animation. Nous avons commencé par déformer un simple cylindre, avec des poids fixes, puis des poids variables le long de sa hauteur. Nous avons associé des positions à des keyframes, puis effectué une interpolation des différentes positions des vertex entre ces keyframes. Enfin, nous avons étendu ce code pour animer le maillage d'un chat : oreilles, pattes, langue et queue.
Les cours de simulation, eux, nous ont appris à modéliser des systèmes physiques avec des forces simulées, agissant sur la position et la vitesse de particules modélisées par des vertex. Ici, nous avons travaillé sur l'exemple d'un tissu composé d'un maillage de 30x30 vertex, dont on a modélisé les forces de tensions par des ressorts (structurels, cisaillement et courbure). Nous modélisons ensuite l'effet de la force de gravité sur le tissu accroché par deux extrémités, ainsi que les courbures du tissu liées aux obstacles (sphère et plan).
Pendant les cours de modélisation 3D, nous avons vu différentes méthodes de rendu graphique dont la projection et le ray-tracing ... Nous avons dû implémenter chacune de ces méthodes en se basant sur une structure de code dont nous devions remplir les différentes fonctions essentielles en C++.
Le rendu projectif se base sur la représentation d'une forme 3D par un ensemble de triangles. Nous avons donc implémenté les fonctions de tracé sur l'espace image d'un point, d'une ligne, puis d'un triangle, en implémentant des interpolations en couleur et en profondeur. Ensuite, nous avons effectué l'affichage du maillage d'un dinosaure, avec le calcul d'illumination de Phong et avons implémenté l'interpolation des couleurs de texture. Enfin nous avons créé un fragment shader pour interpoler à chaque pixel la couleur de la texture correspondante.
Le ray-tracing ou tracé de rayons consiste à représenter les objets en considérant l'aspect physique du rayonnement lumineux (ombres, réflexions). Pour cela il faut calculer des intersections entre nos rayons et les objets de la scène et ceci pour chaque pixel de notre image. Nous avons donc implémenté les calculs d'intersection pour nos différents objets, les calculs d'ombrage et d'illumination, puis les fonctions liées à la réflexion des différent s objets de l'image. Nous avons ensuite amélioré notre rendu en ajoutant un algorithme d'anti-aliasing.
Lors de la 4ème année à CPE, il est demandé de réaliser un projet de 40h par binôme pour approfondir les sujets vus en cours de traitement d'image. Maxime Castello et moi-même avons choisi d'utiliser OpenCV et une webcam pour faire du traitement en temps réel. Nous avions libre choix de l'application et nous avons décidé de créer une calculatrice graphique utilisable avec le doigt de la main. Nous utilisions la librairie OpenCV pour la première fois et codions en langage C++.
Nous avons appris comment lire une frame de la webcam et l'afficher, puis comment rajouter de l'information graphique sur cet affichage avec Qt (painter, rectangle ...) ce qui a permis de créer les boutons de la calculatrice. Nous avons ensuite découvert les traitements d'image basiques pour détecter la peau, notamment le seuillage dans l'espace HSV, pour isoler la main. Ensuite nous avons utilisé la détection de contours pour essayer de déterminer la position du doigt. Nous nous basons sur la distance entre le barycentre du contour et les points le constituant, en prenant la distance la plus éloignée (lorsque l'on pointe avec n'importe quel doigt, cette distance maximale est obtenue au bout du doigt).
Nous détectons ensuite la position de ce point du contour, normalement situé au bout du doigt utilisé pour taper sur les touches de la calculatrice virtuelle, et faisons correspondre la valeur "cliquée" par le doigt pour l'afficher. Enfin, lors de l'appui sur la touche "=", le résultat est calculé par un programme que nous avons développé (parseur) et affiché par la calculatrice.
Ce projet est un travail facultatif demandé dans le cadre d'un cours/TP sur Qt et ses librairies d'interface graphiques. Ce programme codé en C++ est l'oeuvre de Maxime Castello et moi-même. Le but était d'utiliser Qt pour créer un jeu de casse-brique, avec si possible l'ajout de bonus/malus.
Pour garder une structure de code cohérente, nous avons utilisé des classes, pour séparer les briques, la bille, le pad, et les bonus/malus. L'ensemble de briques est en réalité une liste de rectangles de même couleur et dimension, placés les uns à côtés des autres. Le pad se contrôle à l'aide de la souris sur la ligne horizontale dans le bas de la fenêtre. La bille avance sur la fenêtre par intégration du temps (horloge) et rebondit contre les parois, les briques et le pad par réflexion de la vitesse incidente. Les bonus et les malus sont contenus aléatoirement dans les blocs et tombent à vitesse constante lorsque ce bloc est détruit. Si le pad les attrape alors leurs effets sont déclenchés : augmentation/diminution de la vitesse de la bille, augmentation/diminution de la taille du pad.
Si la bille touche la paroi basse de la fenêtre, la partie est perdue, on peut alors voir son score et recommencer. Si l'on a détruit toutes les briques, on gagne la partie et on a terminé le jeu.
Ce projet s'inscrivait dans le module de découverte de programmation avec OpenGL, à la suite d'un TP de découverte. Il s'agissait d'utiliser des fonctions déjà données (chargement d'un objet, associations de textures, shaders etc...) en les modifiant pour créer un mini jeu vidéo. La consigne à respecter était simplement de faire appraître au moins 3 référentiels différents, qui sont ici le canon, le Rammus et le bâtiment dans lequel les personnages se déplacent.
Le jeu est une sorte de Shoot'em Up version FPS. On contrôle avec Z,Q,S,D notre personnage pour le faire avancer à travers le décor et avec notre souris on peut se tourner à gauche ou à droite, et déclencher le tir d'un boulet de canon par un clic gauche. Si l'on touche le Rammus, il disparaît de la carte tandis que d'autres apparaissent en convergeant vers nous. Il faut donc être adroit au tir afin de diminuer leur nombre et de ne pas se faire submerger. Si un seul des Rammus nous touche, le jeu s'arrête et l'on peut alors recommencer pour améliorer son score. Notre score final est calculé en fonction du nombre de Rammus total éliminés et du temps pendant lequel on a réussi à rester en vie.
J'ai donc dû implémenter différentes fonctions executées à chaque mise à jour de l'image comme le calcul des collisions, les transformations à appliquer aux objets à chaque mouvement du personnage ou de la souris, le compte du temps et des points... La caméra est positionnée de manière à donner l'illuson d'être dans les yeux d'un personnage et le canon est situé très proche de la caméra, mais sur le côté pour ne pas gêner la vision. Lors du déplacement du personnage, une translation est effectuée sur tous les autres objets du décor hormis le canon et la caméra. Lors du déplacement de la souris, c'est une rotation qui est effectuée sur ces objets.
Le personnage ne peut pas traverser les murs, et le jeu s'arrête lors de la collision avec un Rammus. Pour la gestion du tir, on considère une hitbox en forme de sphère autour du Rammus, que la balle intersecte ou non. Le canon est légèrement animé pour donner une impression de recul et de temps de rechargement. Les Rammus touchés disparaissent, et pendant ce temps-là d'autres apparaissent de manière aléatoire sur la carte en convergeant vers le personnage. Le rythme de leur apparition augmente au fur et à mesure de l'avancée du jeu ce qui rend la survie de plus en plus difficile.
J'ai réalisé ce projet en collaboration avec Sébastien Altounian. Nous avons dû développer en C un jeu de plateau inconnu : Siam. C'était pendant ma première année d'école (3ème année post-bac), juste après que j'aie appris les bases du langage C. Comme nous découvrions le langage, les règles, la conception du jeu et les noms des fonctions ont été donnés. Il nous suffisait de compléter, réécrire, ajouter des descriptions dans les fichiers d'en-tête afin d'apprendre de bonnes méthodes comme par exemple utiliser assert, donner un nom compréhensible à nos variables, commenter notre code, écrire des codes test, déboguer etc....
Le code a été développé avec Qtcreator sous Linux. L'enseignant a également ajouté un visualiseur pour donner une impression de réalisme.
Le jeu est un jeu de plateau, qui est une sorte de morpion 2.0.
Ce projet a été mon premier projet de jeu en C lors de ma 1ère année à CPE (3ème année d'enseignement supérieur). Je venais d'avoir des cours sur le langage C pendant 6 semaines quand j'ai dû développer ce jeu. En binôme, avec Margaux Masson, nous avons eu 2 heures pour réfléchir à l'implémentation et 4 heures pour écrire et tester le code du jeu dont l'affichage se fait directement sur le terminal.