Le jeu d'échec holographique - nsobczak/e-Holographer GitHub Wiki

Le jeu d'échec holographique

Pour mettre en avant les possibilités offertes par le e-Holographer, nous avons développé un jeu d'échec holographique. Il s’agit d’un jeu d’échec connecté à la plateforme d’interconnexion des objets, Constellation. Le jeu relie un(e) smartphone/tablette, le e-Holographer et le serveur constellation.

Vous savez maintenant contrôler l'affichage du e-Holographer. Pour réaliser notre jeu d'échec Holographique ce n'est pas beaucoup plus compliqué puisque cela repose sur de l'affichage d'image.

L'idée du jeu d'échec Holographique est d'afficher un plateau holographique en 3D représentant l'état du jeu à partir d'un jeu disponible sur smartphone/tablette. Afin d'apporter un intérêt supplémentaire à notre plateau holographique nous souhaitons afficher des animations de combat lorsqu'une pièce est prise par une autre. Cependant, nous ne détaillerons ici que l'affichage des images. C'est pourquoi nous choisissons de travailler avec un Raspberry pi 3.

1. Le jeu d'échec 3D

Pour réaliser notre plateau d'échec holographique en 3D nous choisissons d'utiliser un modèle 3D open source créé avec le logiciel Blender. Ce modèle est disponible ici. Vous pouvez constater qu'il s'agit en réalité d'un jeu indépendant. Encore une fois nous n'allons pas avoir besoin de toutes ses fonctionnalités. Nous ne prenons que le modèle 3D. Il nous faut pouvoir afficher des images du plateau mis à jour selon 4 points de vue différents. Nous avons donc créé 2 caméras supplémentaires. Afin de pouvoir afficher toutes les configurations imaginables, nous prenons des rendus de chaque pièce, sur chaque case, avec chaque caméra. Nous utiliserons ensuite des scripts python pour reconstituer le plateau en cours de jeu à partir de ces images unitaires. Ce travail étant très fastidieux, vous pouvez retrouver toutes ces images sur notre github.

Image unitaire

Les scripts python

A chaque instant, le e-Holographer projette l’état du plateau de jeu. Pour réaliser cela, notre package doit fusionner les images unitaires des différentes pièces. Il réalise cette action sous 4 angles différents (vues de face, de côtés et de dos). Il réunit ensuite ces 4 images sur une seule plus grande de façon à ce que l’écran puisse projeter les 4 angles de l’image. Nous créons donc un script python qui s'occupe de faire tout cela.

Nous créons également un script python permettant de lancer des vidéos avec le logiciel vlc en plein écran.

Ces scripts python sont également disponibles sur notre github.

Image représentant l'état du plateau en cours de jeu

Le package

Nous avons réalisé notre package en python. Il contient plusieurs message callbacks qui utilisent nos scripts python. Nous pouvons également ajouter des state object à notre package.

La 1ère chose à faire est d'importer les bibliothèques dont nous aurons besoin, à savoir Constellation et les scripts que nous avons créés.

import Constellation
import ScriptRpi
import FusionImagesCreationPlateau
import os
Les message callbacks

Nous utilisons des message callbacks pour utiliser interagir avec la projection du e-Holographer.

Nous créons un 1er message callback qui sera appelé lorsque nous connecterons notre application à Constellation. Il s'agit simplement de générer un log dans la console de notre serveur.

#Connexion démarrée
@Constellation.MessageCallback()
def InfosConnection():
    "Bouton qui écrit 'connecté' dans la console log"

    Constellation.WriteInfo("Holographer connecté à Constellation")

Nous voyons bien que notre message écrit dans notre console log.

Console log connexion

Le message callback principal est celui de la mise à jour du plateau. Lorsqu'un mouvement est exécuté dans l'application Androïd, le message est envoyé au e-Holographer qui met alors à jour son plateau holographique en 3D. Il prend en paramètres les numéros correspondant aux cases de départ et d'arrivée de la dernière pièce jouée (0 et 0 pour initialiser le plateau la 1ère fois). Par la suite, il suffira donc d'utiliser la fonction sendmessage() dans le fichier javascript de notre application 2D pour mettre à jour la position des pièces sur notre plateau holographique.

#En cours de jeu
@Constellation.MessageCallback()
def MAJPlateau(caseDeDepart, caseDarrivee):
    "Bouton qui génère le plateau suivant à partir de 2 integer - mettre 0, 0 pour générer le plateau initial"
    
    global IdProcI
    
    Constellation.WriteInfo( "MAJ du plateau lancee | [case de depart = " + str(caseDeDepart) + " | case d'arrivee = " + str(caseDarrivee) + "]" )

    global listeDesPieces 
    global cheminIdImage
    global cheminScriptImage

    if ((caseDeDepart == 0) and (caseDarrivee == 0)):
        #Creation du plateau de départ quand on est en cours de jeu
        Constellation.WriteInfo( "Initialisation du plateau" )
        listeDesPieces = FICP.creePlateauHolographique(nomImage, [], 0, 0)
        
        #Fermeture d'une eventuelle image
        if (IdProcI): 
            os.system( "kill " + str(IdProcI) )

        #Affichage de l'image
        IdProcI = SR.showImage(cheminScriptImage)

        Constellation.WriteInfo("Génération du plateau terminée")

    else:
        #Mise A Jour (MAJ) de la position des pieces sur le plateau
        listeDesPieces = FICP.creePlateauHolographique(nomImage, listeDesPieces, caseDeDepart, caseDarrivee)

        #Fermeture d'une eventuelle image
        if (IdProcI):
            os.system( "kill " + str(IdProcI) )

        #Affichage de l'image
        IdProcI = SR.showImage(cheminScriptImage)
        
        Constellation.WriteInfo("Maj plateau terminée")

Il ne faut pas oublier d'initialiser les variables globales.

listeDesPieces = []	
IdProcI = 0 
cheminScriptVideo = "/home/pi/Desktop/scriptsRpi/bash/scriptVideo"
cheminScriptImage = "/home/pi/Desktop/scriptsRpi/bash/scriptImage"
cheminIdImage = "/home/pi/Desktop/scriptsRpi/bash/IdImage"
cheminIdVideo = "/home/pi/Desktop/scriptsRpi/bash/IdVideo"

Par la suite nous souhaiterions déclencher des animations de combats lorsqu'un mouvement engendre la prise d’une pièce adverse. Cependant nous n'avons pas encore intégré cette fonctionnalité. Il s'agirait simplement d'un message callback qui lirait une vidéo.

#A utiliser quand on aura cree des animations pour les combats entre les différentes pièces
@Constellation.MessageCallback()
def AnimationCombat():
    "Bouton qui lance une animation de combat"

    Constellation.WriteInfo("Animation de combat lancée")

Lorsque la partie est finie, nous voulons écrire un warning dans la console de notre serveur Constellation.

#Fin du jeu
@Constellation.MessageCallback()
def FinDuJeu():
    "Bouton qui signale la fin du jeu"

    Constellation.WriteWarn("Game Over")

Nous choisissons d'écrire un warning car il ressort au milieu des infos classiques.

Console log game over

Nos message callbacks apparaissent dans notre ConstellationConsole.

MC

Les state object

Nous avons créé un state object qui affiche l'état de la connexion lorsque la package est déployé sur une sentinelle et qu'il est connecté à Constellation.

def OnStart():
    #State Object
    Constellation.PushStateObject("Holographer", { "Sender": "Holographer" }, "Info", { "Device_Id": "RPi", "Etat du package":"lancé" })

Notre state object apparait dans notre ConstellationConsole.

SO

Nous aimerions créer des state object permettant d'obtenir des informations sur une partie. Il serait alors possible de dresser le profil d'un joueur et de suivre l'évolution de son niveau. Idées d'informations à transmettre dans les state object :

  • Nombre de pièces perdues pendant la partie
  • Type des pièces perdues
  • Nombre de pièces perdues/prises
  • Types des pièces perdues/prises
  • Durée moyenne pour réaliser un coup
  • Pièce la plus souvent déplacée

2. L'application de contrôle (jeu d'échec 2D)

Pour réaliser notre application de contrôle nous souhaitons utiliser un jeu d'échec 2D pour smartphone/tablette. Pour cela nous choisissons d'utiliser une application web open source disponible ici. Cette application est très complète et nous n'aurons pas besoin de toutes ses fonctionnalités. Nous voulons qu'à chaque déplacement de pièce les informations de mise à jour soient envoyées à notre package par l'intermédiaire de message callback.

Le html : index.html

Afin de connecter notre application à Constellation, nous réalisons ce que nous avons déjà fait pour notre 1ère application, à savoir ajouter les bibliothèques et lancer la connexion à constellation. La différence est qu'ici le javascript se situe dans le head de notre html. De plus, nous ne démarrons pas la connexion à constellation à la fin de ce javascript.

Pour lancer la connexion, nous définirons une fonction setConnectionToConstellation() dans notre javascript. Nous appellerons cette fonction dans la fonction initChess() de la partie javascript du head de notre html :

function initChess() {
    chess.setConnectionToConstellation(constellation);   //démarre la connexion à constellation
    chess.useAI(document.chessCtrl1.useAI.checked);
}

Le javascript : chess.js

La première chose que nous faisons dans le javascript est d'ajouter la fonction setConnectionToConstellation() dont nous avons parlée. Nous l'ajoutons à la fin de notre variable chess, dans le return.

return {
    setConnectionToConstellation: function (serveurConstellation) {
        //Fonction qui initialise la connexion au serveur constellation
        console.log("setConnectionToConstellation()");
        serveurConstellation.connection.start();        
    },
    help: ...

Avec la connexion à constellation, notre application web ressemble à ça : Application Web Les prochaines modifications ne modifieront pas cet affichage.

Ensuite il nous faut utiliser le message callback de mise à jour du plateau lorsqu'une pièce est déplacée. Nous l'ajoutons à la fin de la fonction writeFlatPieces() de notre chess.js. Nous ajoutons également un console log afin de pouvoir connaitre à tout instant les cases envoyées en paramètres de notre message callback.

function writeFlatPieces() {
    ...

    console.log("lastStart = case de départ :", lastStart, " | lastEnd = case d'arrivée :", lastEnd);

    //envoi du message callback
    constellation.server.sendMessage({ Scope: 'Package', Args: ['HolographerPythonPackage'] }, 'MAJPlateau',
        [ lastStart, lastEnd ]);
}

Enfin, quand la partie est finie, nous utilisons le message callback de fin de partie. C'est la fonction getInCheckPieces() de notre chess.js qui signale une fin de partie.

function getInCheckPieces() {
    ...
    if (bNoMoreMoves) {
        if (bCheck) {
            ...
            console.log("MAT");
            constellation.server.sendMessage({
                Scope: 'Package',
                Args: ['HolographerPythonPackage']
            }, 'FinDuJeu', '');
        } else {
            ...
            console.log("PAT");
            constellation.server.sendMessage({
                Scope: 'Package',
                Args: ['HolographerPythonPackage']
            }, 'FinDuJeu', '');
        }
        bGameNotOver = false;
    } 
    ...
}

L'application pour smartphone/tablette

Nous avons à présent une application web qui fonctionne. Afin de convertir notre application, nous utilisons Cordova pour obtenir une application Androïd.

Comme pour la création de notre 1ère application, il faut inclure le fichier html dans l'html de Cordova. Cependant, cette fois-ci nous avons un javascript indépendant. Il faut simplement l'appeler dans le html.

<script type="text/ecmascript" src="scripts/chess.js"></script>

Nous créons un logo pour notre application. Il remplacera le logo proposé par défaut par Cordova :

Logo de l'appli 2D

Vous pouvez retrouver notre application complète dans la partie "code" de notre github

Le résultat final

Désormais, lorsque nous jouons aux échecs sur notre smartphone, le e-Holographer nous affiche le plateau en hologramme.

Résultat final

⚠️ **GitHub.com Fallback** ⚠️