• Home
  • Nous contacter

Le blog d'Adfab

Le blog d'Adfab

Le blog d'Adfab

Le blog d'Adfab
Frontend Jeux

Le cycle de vie d’un jeu

La réalisation d’un jeu (web ou autre) n’est pas plus complexe que celle d’une web app : elle aussi requiert en amont une conception particulière pour la gestion de son cycle de vie.
Que le jeu soit très basique (un simple quizz) ou au contraire très complexe, il y aura très souvent un système d’écrans et d’étapes qui se suivent les unes après les autres.

Prenons un exemple d’écrans se succédant :

  • Chargement / Introduction
  • Tutoriel du jeu
  • Le jeu
  • Ecran de Fin (victoire ou défaite)

Cette liste est non exhaustive car nous pourrions en ajouter / supprimer en fonction de la demande. La particularité de ces écrans est qu’ils sont indépendants les uns des autres : ils doivent s’enchaîner, passer de l’un à l’autre sans tenir compte de l’écran qui le précède et de celui qui suivra.

Prérequis

Nous utiliserons un émetteur d’événements pour la communication entre nos objets javascript : on.js est une petite librairie qui fait très bien le travail. Le code javascript sera écrit en ES6.

Voici la structure du projet :

  • index.js (point d’entré de notre code)
  • GameManager.js
  • GameScene.js
  • /0_intro/index.js
  • /1_tuto/index.js
  • /2_play/index.js
  • /3_end/index.js

One manager to rule them all

Pour gérer l’état de nos écrans il va nous falloir mettre en place un Game manager qui sera chargé de gérer le passage d’une étape à l’autre.

GameManager.js

// import de nos différentes scène
import Intro from './0_intro'
import Tuto from './1_tuto'
import Play from './2_play'
import End from './3_end'

export default class GameManager {
  constructor(type = 'default') {
    this.scene = Intro
    this._container = document.querySelector('.game-container')
  }
  startScene() {
    this._container.innerHTML = this._scene.html
    this._scene.start()
  }
  // Lorsqu’une scène enverra un événement de fin 
  // notre game manager aura la responsabilité de 
  // choisir quel sera la scène suivante
  sceneEnd(evt) {
    switch (evt.step) {
      case Intro.STEP:
        this.scene = Tuto
        break
      case Tuto.STEP:
        this.scene = Play
        break
      case Play.STEP:
        this.scene = End
        break
      case End.STEP:
        console.log('the game is over')
        break
    }
  }
  get scene() {
    return this._scene
  }
  set scene(scene) {
    this._scene = scene
    this._step = this._scene.step
    // nous verrons plus tard comment
    //la scène va émettre l’évènement de fin de scène
    this._scene.onEvent(evt => this.sceneEnd(evt))
  }
}

Tous en scène

Tous nos écrans de jeu vont avoir en commun différentes actions, c’est pourquoi il est intéressant de faire un objet de scène de jeu qui sera hérité par toutes nos scènes :

GameScene.js

// import de notre bibliothèque d'émetteur d'événement
import on from 'on'

export default class GameScene {
  constructor(step = 'default') {
    this.step = step
    // on transforme notre scène en émetteur d'événement
    this.onEvent = on(this)
  }
  start() {
    console.log(`scene ${this.step} started`)
  }
  end() {
    // lorsque l’écran se termine
    //nous envoyons l'événement de fin
    this.onEvent._fire({ event: 'sceneEnd', step: this.step })
  }
  // Voici le contenu par défaut d'une scène
  get html() {
    return `<div>Je suis l'étape : ${this.step}</div>`
  }
}

Les deux actions communes à toutes les scènes sont la méthode start (début du jeu) et end (fin du jeu) qui a pour objectif d’envoyer l’événement de fin de jeu qui pourra être écouté par notre game manager. De plus, chaque scène aura un type enregistré dans la variable this.step, qui sera accessible par notre manager pour qu’il sache quelle étape vient de se finir.

Ensuite voyons comment une scène va hériter de notre objet GameScene et l’utiliser :

/0_intro/index.js

import GameScene from '../GameScene'

const STEP_VALUE = 'intro'

class Scene extends GameScene {
  get STEP() {
    return STEP_VALUE
  }
  constructor() {
    super(STEP_VALUE)
  }
  // Nous pouvons overrid les méthodes
  // de GameScene si besoin
  // get html() {}
}

Notre scène d’intro étend GameScene pour profiter des méthodes start et end, de plus elle est typé avec le valeur de STEP qui est égale a intro pour que le manager sache a quel étape en est le déroulement des différents écrans.

Passage d’un écran à un autre

L’étape d’intro pourrait charger les assets de notre jeu, afficher un loader puis une animation / cinématique, pour se terminer et appeler la méthode end()

Pour l’exemple nous allons seulement voir l’écran intro

/0_intro/index.js

import GameScene from '../GameScene'

const STEP_VALUE = 'intro'

class Scene extends GameScene {
  get STEP() {
    return STEP_VALUE
  }
  constructor() {
    super(STEP_VALUE)
  }
  start() {
   let btn = document.querySelector('.btn')
   // lors du click sur notre bouton 
   //nous envoyons l'evenement de fin de scène
   btn.addEventListener('click', () => this.end())
   super.start()
  }
  get html() {
   return `<button class="btn">fin de l'intro</button>`
  }
}

export default new Scene()

Une fois le bouton cliqué notre méthode sceneEnd() du fichier GameManager.js sera appelé et il s’occupera de passer à la scène d’intro, puis ainsi de suite pour chacune des scènes.

Cette exemple est plutôt réduit mais il offre une bonne base pour un cycle de vie des différents écrans d’un jeu.

Dans notre scène d’intro, nous aurions par exemple pu overrider la méthode end(), sans oublier d’appeler super.end(), pour retirer l’écouteur d’événement clique sur notre bouton. En effet il est important qu’une scène gère sa création et sa destruction pour des raison de performances.

Vous pouvez retrouver le code complet ici sur github et n’hésitez pas à commenter cet article si vous des questions !

12/09/2017 7 MIN READ TAGS: Développement frontend, Web app BY: Fabrice LABBE 0 COMMENT
SHARE
LIRE LA SUITE

Fabrice LABBE

Ignite boilerplate pour React Native

Ma première fois sur Pagekit !

VOUS POURRIEZ AIMER

Frontend Les microdatas HTML5

Frontend dotJS : les Bonnes pratiques de développement selon John K. Paul

Frontend Animations web: Optimiser le FPS de son CSS

Design Développement Frontend Outils Entre design et développement frontend [2/2]

Développement Frontend BEM : organisez vos CSS !

Frontend AngularJS et PopcornJS sont dans un bateau

A propos d’Adfab

Nous sommes un studio de production digitales et d’innovation digitales au service des agences et des annonceurs
Nous recherchons le scintillement dans les regards et le plaisir de réalisations sur-performantes
Nous sommes techno-agnostiques
Nous sommes Adfab

Le blog d'Adfab
Copyright © 2018 Adfab Connect