IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2018
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2018
    Messages : 41
    Par défaut JS / Svelte: intégrer dans un store et rendre réactives des règles de jeu codéés dans un autre packageque l'UI
    Bonjour à tous !

    Ma question porte sur la possibilité de transformer un objet Javascript ordinaire et non réactif en une série des stores réactifs (base + dérivés) pour Svelte.

    J'ai une bibliothèque de jeu externe au projet UI Svelte qui valide les règles du jeu dès qu'on effectue une action de jeu. Cette instance d'objet est capable, en principe, de jouer toute une partie en gardant l'historique pour le replay. Une instance de cet objet représente une parite unique, il faut créer un nouvel objet pour chaque manche, il n'y a pas de méthode game.reset().

    Maintenant il me faut intégrer cette lib dans un store réactif pour Svelte, pour exposer uniquement les méthodes de mutation (apres validation des actions) du jeu) et les getters (pour l'état du plateau, les scores des jouerus et les drapeaux de la partie); ce store sera dérivé suivant les différents getters. Je souhaite pouvoir écrire des instructions réactives du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
        // composant Board.svelte
        import { GameStore } from '../stores/GameStore.js'
        import { GameBoardStore } from '../stores/GameBoardStore.js'
        import  Tile  from '../arena/Tile.svelte'
     
        ...
     
         on_button_clicked = () => {
            // déclencher unupdate sur le store
            GameStore.play( /* ... */ )
        }
     
        ...
     
        {#if $GameStore.ready }        
            {#each $GameBoardStore.tiles() as tile }
                <Tile {...tile}>
            {/each}
        {/if}
    Mais je cherche encore une "bonne" façonn de procéder, qui soit assez simple à coder, sans pour autant affaiblir lastabilité de l'application.

    Remarques:

    * Le plateau est en SVG, avec des images et des animations possibles,
    * il faut prévoir des splash screens pour les transitions entre les tours des jouerus
    , les communications entre joueurs se feront via socket.io

    Idée: j'ai pensé dans une première version à ne stocker dans le store qu'un entier incrémnté à chaque tour de jeu et à lire les getters quand cet entier est mis à jour...

    En bref quelle seraient les pistes que vous adopteriez ?

  2. #2
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2018
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2018
    Messages : 41
    Par défaut
    Bonjour à tous !

    EDIT: je remarque qu'il y a eu beaucoup de lectures sur ce post mais pas de réponses ou de suggestions. C'est peût être un manque de clarté de ma part, aussi ai-je décidé de le ré-écrire.

    Pour faire simple, j'ai créé une bibliothèque (package node JS) moteur/validateur de règles de jeu, indépendamment du projet SvelteKit pour l'interface et la communication multi-joueurs pendant une partie. Ce moteur n'est pas réactif par construction,il s'agit ici lui donner ce comportement via les stores de Svelte.

    Le moteur du jeu sse crée comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        import { make_engine } from '...'
     
        const game = make_engine({
            players: 3, // ou 2 joueurs
            debug: true
        })
    A ce moment 'game' est un objet qui expose les méthodes de jeu et les getters pour connaître l'état de la partie. Il est à noter que cet état est bien caché dans une fermeture (closure) JSafin de limiter les risques de hacks type: game.position.board[coords] = null... ou autre choses du même genre, qui pourraient outrepasser les règles et feraient foirer la partie.

    Le jeu est multi-joueurs et la validation d'un tour se fera par consensus entre les joueurs afin de ne pas trop encombrer le serveur : celui ci se contentera de faire le relai ("passe-plats') des coups joués et sommes de contrôle des plateaux au fur et à mmesure que la partie avancez.

    Concrètement la partie avancera à chaque tour de la sorte:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        const prepared = game.prepare_action({ 
            action: 'drop,'
            figure: 'XYZ',
            coords
        })
     
        // à ce moment 'prepared' contient une checksum du plateau >= 0 si les règles 
        // sont respectées et permettent de calculer la position suivante, et -1 sinon.
     
        // si le coup est validé on peut effectuer la mutation/patch du plateau
        game.validate_turn(prepared)
    Le réseultat peut être lu par des getters:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        const figure = game.whois(coords)
        const scores = game.players(0).scores
        const isgame_over = game.flags('game-over')
    Le problçme porte sue l'intégration dans les stores de Svelte.

    L'API de 'game' N'EST PAS REACTIVE puisque le programme en question est un module est UMD et peut être executé aussi bien dans le navigateur que dans un script NodeJS pour les cas de tes.

    Comment faire en sorte que les stores de Svelte puissent

    * 0: préparer un coup de jeu
    * 1: si valide: envoyer checksum aux autres joueurs, sinon: retour à 0
    * 2: si consensensus: jouer effectivement le coup, sinon: annuler partie
    * 3: afficher l'état du plateau, puis retour à 0

    ... puisque 'game' n'est pas, par construction, une variable réactive ???

    Merci si vous avez des idées à propser !

    En fait on a un diagramme à états finis au niveau de l'application, peut être faudrait-il stocker les états dans un store et le dériver pour lire l'état interne (board, score, flagsà du jey par un store dérivé sur celui qui représente l'automate d'états de l'application.

    Qu'en pensez vous ?

    L'idée serait d'avoir un store pour les états de l'application
    et d'effectuer toutes les dérivations nécessaires pour lire les différents getters. (board, flags et scores)

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2018
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2018
    Messages : 41
    Par défaut
    En fait il y a au moins trois façons de partager de l'information entre les composants Svelte

    * Props et bindings de props (parent --> enfant)
    * Stores réactifs : pour des variables observables par le DOM (réactivité)
    * context API : pour passer de l'information dans toute une hiérachie de composants

    Pour ce qui est de ma lib de jeu, vu que c'est un objet exposant des méthodes et non une simple variable, je vais la passer par le contexte, vu qu'elle est globale, en me plaçant au niveau du composant container du jeu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    const engine = make_engine({ players: 2, debug: true })
     
    // et de là plusieurs possibllités:
    setContext(game',  engine ') // le plus simple
    setContext(game', { engine }') // nullable
    setContext(game', writable(engine)') // dans un store
    ... qui peuvent avoir chacune leurs avantages en termes d'acc_s aux données.

    Il me faut préciser que le moteurs de jeu devrait avoir 4 modes de fonctionnement :
    * automatique pour la démo
    * un joueur pour l'entraînement (local, avec bot(s) bzaiques)
    * multijoueurs online (socket.io... ou autre)
    * automatique, local pour le replay d'une partie.

    Donc j'aurais dans cette applications au mois 3 machines à états finis (automates)
    * M1: successions des écrans du jeu
    * M2: action de jeu en cours
    * M3 dérouleement de la partie et échange avec le réseau pour la validation des tours en multijoueurs

    les questions que je me pose sont:

    * comment dans une logique de stores distinguer joueur bot local et joueur physique distant

    * comment créer à partir d'un store représentation le jeu, autant de stores dérivés qu'il y a de cases sur le plateau, sachant que ces stores ne pourront exister effectivement , ou ne rendre une valeur, que quand les écrans d'initialisation (nombres de joueurs, local ou réseau) auront été franchis ?

Discussions similaires

  1. [Objective-C] Passer d'un UITextField a un autre ( exemple pour entrez des identifiant login)
    Par darKnight0504 dans le forum Objective-C
    Réponses: 2
    Dernier message: 20/05/2014, 13h47
  2. Architecture jeu XNA 2D
    Par Hylarium dans le forum XNA/Monogame
    Réponses: 3
    Dernier message: 16/04/2013, 21h25
  3. Réponses: 8
    Dernier message: 11/05/2012, 10h25
  4. Réponses: 5
    Dernier message: 13/12/2011, 13h18
  5. Réponses: 5
    Dernier message: 10/12/2011, 10h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo