Jeu de puzzle basé sur jQuery

JavaScriptJavaScriptBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Ce projet, le "jQuery Flip Puzzle Game", offre une expérience pratique en développement web, en mettant l'accent sur JavaScript, jQuery et Bootstrap. Il implique la programmation orientée objet en JavaScript et aborde le problème courant de la liaison de "this" dans le contexte du développement web. Le jeu est implémenté à l'aide de jQuery et de Bootstrap 3 pour l'interface utilisateur. Bien que la familiarité avec Bootstrap soit utile, la logique centrale du projet est construite avec jQuery et JavaScript.

Dans le jeu, les joueurs commencent avec une grille de blocs orange. Chaque bloc a un côté orange et un côté bleu. Lorsqu'un joueur clique sur un bloc, sa couleur bascule, et les couleurs des blocs adjacents changent également. Le but est de transformer tous les blocs en bleu pour terminer le jeu.

👀 Aperçu

jQuery Flip Puzzle Game

🎯 Tâches

Dans ce projet, vous allez apprendre :

  • Comment implémenter la programmation orientée objet en JavaScript et résoudre le problème de liaison de "this".
  • Comment construire la logique centrale du jeu à l'aide de jQuery et de JavaScript.
  • Comment créer un jeu de puzzle interactif où les joueurs basculent les couleurs des blocs pour gagner.

🏆 Réalisations

Après avoir terminé ce projet, vous serez capable de :

  • Appliquer les principes de programmation orientée objet en JavaScript.
  • Gérer la liaison de "this" en JavaScript pour la gestion des événements et les méthodes d'objets.
  • Développer des jeux web interactifs à l'aide de jQuery.
  • Utiliser Bootstrap 3 pour créer des interfaces visuellement attrayantes et conviviales pour l'utilisateur.

Structure HTML de base

Selon l'image d'aperçu, une mise en page préliminaire de la page web est créée. Dans Bootstrap, il existe une boîte de dialogue Modal similaire à la fenêtre pop-up alert, et le style de Modal est plus esthétique par rapport.

Nous devons inclure les styles CSS de Bootstrap, nos styles CSS personnalisés, le fichier jQuery, le fichier JavaScript de Bootstrap et le fichier JavaScript principal du jeu dans le projet. Écrivez le code suivant dans la balise head de la page HTML :

<head>
  <meta charset="utf-8" />
  <title>Blue Puzzle</title>
  <!-- Inclure le CSS de Bootstrap -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
  />
  <!-- Inclure le CSS personnalisé -->
  <link rel="stylesheet" href="style.css" />

  <!-- Inclure jQuery et le JavaScript de Bootstrap -->
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
  <!-- Inclure le JavaScript principal du jeu -->
  <script src="game.js"></script>
</head>
✨ Vérifier la solution et pratiquer

Configuration de la zone de jeu

Pour configurer la zone de jeu, y compris les boutons pour réinitialiser le jeu et d'autres fonctions, insérez le code suivant dans la balise body :

<div class="container">
  <div class="heading">
    <h1 class="title">jQuery Flip Puzzle Game</h1>
    <div class="scoresContainer">
      <!-- Afficher le niveau actuel du jeu -->
      <div class="currLevel">Niveau actuel : <b>1</b></div>
    </div>
  </div>
  <div class="aboveGame">
    <!-- Boutons du jeu -->
    <a
      class="instruct btn btn-primary"
      data-toggle="modal"
      data-target="#instructions"
      >Instructions du jeu</a
    >
    <a
      class="newgame btn btn-primary"
      data-toggle="modal"
      data-target="#newGame"
      >Recommencer</a
    >
    <a
      class="reset btn btn-primary"
      data-toggle="modal"
      data-target="#restartLevel"
      >Réinitialiser le niveau</a
    >
  </div>
  <div class="board">
    <!-- Zone de jeu -->
    <div class="gamerow">
      <div class="gamesquare coord0q0"></div>
    </div>
  </div>
</div>
✨ Vérifier la solution et pratiquer

Mise en page de la fenêtre pop-up de jeu

Modifiez le contenu de la fenêtre pop-up correspondant au bouton "Modifier les instructions du jeu". Écrivez le code suivant sous le code de la zone de jeu :

<!-- Fenêtre pop-up de jeu -->
<div
  class="modal fade"
  id="instructions"
  tabindex="-1"
  role="dialog"
  aria-hidden="true"
>
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">Jeu</h4>
      </div>
      <div class="modal-body">
        <p>
          Comment gagner : Faire tourner toutes les pièces du puzzle en bleu.
        </p>
        <p>
          Mode de jeu : Chaque carré a un côté orange et un côté bleu. Lorsque
          vous cliquez sur un carré, sa couleur bascule, et les couleurs des
          carrés voisins basculent également.
        </p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-dismiss="modal">
          Commencer le jeu
        </button>
      </div>
    </div>
  </div>
</div>
✨ Vérifier la solution et pratiquer

Mise en page de la fenêtre pop-up du nouveau jeu

Modifiez le contenu de la fenêtre pop-up correspondant au bouton "Recommencer". Écrivez le code suivant sous le code de la logique du jeu :

<!-- Fenêtre pop-up du nouveau jeu -->
<div
  class="modal fade"
  id="newGame"
  tabindex="-1"
  role="dialog"
  aria-hidden="true"
>
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">Recommencer</h4>
      </div>
      <div class="modal-body">
        <p>Êtes-vous sûr de vouloir recommencer?</p>
      </div>
      <div class="modal-footer">
        <button
          type="button"
          class="btn btn-primary"
          id="newGameConfirm"
          data-dismiss="modal"
        >
          Commencer le jeu
        </button>
      </div>
    </div>
  </div>
</div>
✨ Vérifier la solution et pratiquer

Mise en page de la fenêtre pop-up de confirmation de réinitialisation du niveau

Modifiez le contenu de la fenêtre pop-up correspondant au bouton "Réinitialiser le niveau". Ajoutez le code suivant sous le code "Réinitialiser le niveau" :

<!-- Fenêtre pop-up de confirmation de réinitialisation du niveau -->
<div
  class="modal fade"
  id="restartLevel"
  tabindex="-1"
  role="dialog"
  aria-hidden="true"
>
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">Confirmation de réinitialisation du niveau</h4>
      </div>
      <div class="modal-body">
        <p>Êtes-vous sûr de vouloir réinitialiser le niveau?</p>
      </div>
      <div class="modal-footer">
        <button
          type="button"
          class="btn btn-primary"
          id="resetLevelConfirm"
          data-dismiss="modal"
        >
          Réinitialiser
        </button>
      </div>
    </div>
  </div>
</div>
✨ Vérifier la solution et pratiquer

Styles CSS

Les styles CSS du jeu sont relativement simples. Le code dans style.css est montré ci-dessous :

.container {
  width: 600px;
  margin: 0 auto;
}

/* Niveau du jeu */
.scoresContainer {
  float: right;
  text-align: right;
  font-size: 18px;
}

/* Boutons du jeu */
.aboveGame:after {
  display: block;
  margin: 20px 0;
  content: "";
  clear: both;
}

/* Zone de jeu */
.board {
  position: absolute;
  background-color: #5f5f5f;
  border-radius: 4px;
}

.gamesquare {
  float: left;
  margin-right: 15px;
  border-radius: 3px;
}
✨ Vérifier la solution et pratiquer

Configuration de la scène du jeu

Les tuiles dans le panneau de jeu sont stockées sous forme d'un tableau bidimensionnel, où chaque élément a une valeur de 0 (paramétré en orange) ou 1 (paramétré en bleu). Au départ, toutes les valeurs sont paramétrées sur 0. Lorsqu'une tuile est cliquée, sa couleur est inversée, et les coordonnées des tuiles adjacentes sont déterminées pour inverser également leurs couleurs, tout en changeant les valeurs dans le tableau bidimensionnel. Le jeu est terminé lorsque toutes les valeurs dans le tableau deviennent 1 (c'est-à-dire que toutes les tuiles sont bleues).

Logique principale :

  1. La relation entre la taille de la scène du jeu, le niveau de difficulté et la taille et le nombre de tuiles.

  2. Cliquez sur une tuile et changez l'état des tuiles adjacentes.

  3. Vérifiez si tous les états des tuiles sont 1.

function SetStyle() {}
SetStyle.prototype.setGridSize = function (level) {
  var margin = this.getMargin(level);
  var res = ($(".container").width() - margin * level) / level;

  // Définissez la taille et l'espacement des tuiles
  $(".gamesquare").css("margin-right", margin);
  $(".gamesquare").css("width", res);
  $(".gamesquare").css("height", res);

  // Définissez la hauteur, la marge droite et la marge inférieure de chaque ligne
  $(".gamerow").css("height", res);
  $(".gamerow").css("margin-right", margin * -1);
  $(".gamerow").css("margin-bottom", margin);

  // Définissez le rembourrage de la zone de jeu
  $(".board").css("padding", margin);
  $(".board").css("padding-bottom", 0);
};
SetStyle.prototype.getMargin = function (level) {
  if (level <= 6) return 15;
  if (level > 15) return 5;
  return 20 - level;
};
✨ Vérifier la solution et pratiquer

Création du constructeur de jeu

// Constructeur de jeu
function Game() {
  // Niveau du jeu
  this.level = 1;
  // Création d'objets pour contrôler le jeu
  this.gb;
  this.sh = new SetStyle();
}

Le constructeur de jeu est destiné à créer des instances d'un jeu avec des propriétés pour suivre l'état du jeu et des méthodes pour gérer les fonctionnalités du jeu telles que le lancement du jeu, la mise à jour de son état et la présentation visuelle. Cependant, la logique réelle de ces fonctionnalités (à l'intérieur des méthodes start, update et render) n'est pas actuellement fournie, et des emplaceholders sont en place pour une implémentation future.

✨ Vérifier la solution et pratiquer

Configuration des détails du jeu

Configurez les détails du jeu dans les méthodes prototypiques de la classe Game :

// Méthode prototypique de la classe Game, contrôlant la logique spécifique du jeu, assurez-vous de réinitialiser la référence 'this'
Game.prototype = {
  processClick: function (w, h) {
    this.gb.processClick(w, h);
    this.updateCounts();
    if (this.gb.isGameWin()) {
      this.gameEnd();
    }
  },
  // Démarrer le jeu
  beginGame: function () {
    this.setupLevel();
  },
  // Fin du jeu
  gameEnd: function () {
    this.level++;
    this.resetGame();
  },
  // Réinitialiser le jeu, rediriger 'this' en utilisant bind
  resetGame: function () {
    $("#levelDescriptor").html("Entrez le niveau " + this.level);
    setTimeout(
      function () {
        this.setupLevel(); // Lorsque 'this' n'est pas réinitialisé, il fait référence à l'objet window
      }.bind(this),
      500
    ); // Utilisez bind pour rediriger 'this' de la fenêtre vers l'instance
  },
  // Définir le niveau de difficulté
  setupLevel: function () {
    this.gb = new GameBoard(this.level, this.level);
    $(".board").html(""); // Effacer le plateau de jeu
    this.gb.populate(); // Réinitialiser toutes les tuiles en couleur orange
    this.gb.renderBoard(); // Afficher le plateau de jeu et créer les tuiles
    this.sh.setGridSize(this.level); // Contrôler la taille des tuiles dans la zone de jeu
    this.updateCounts(); // Mettre à jour l'affichage du niveau actuel
    this.applyBindings(); // Inverser les couleurs des tuiles autour de la tuile cliquée
  },
  // Mettre à jour l'affichage du niveau actuel
  updateCounts: function () {
    $(".currLevel").html("Niveau actuel : <b>" + this.level + "</b>");
  },
  applyBindings: function () {
    var that = this; // Sauvegarder 'this' en tant que variable avant le rappel d'événement DOM pour une référence facile
    $(".gamesquare").click(function () {
      // Obtenir la position de la tuile cliquée
      var cname = $(this).attr("class").split(" ")[1];
      var coord = cname.substring(5).split("q");
      var height = parseInt(coord[1]);
      var width = parseInt(coord[0]);
      that.processClick(width, height);
    });
  },
  onNewGameClick: function () {
    this.level = 1;
    this.setupLevel();
  }
};

Ce code étend la fonctionnalité du constructeur Game en ajoutant des méthodes prototypiques. Ces méthodes définissent la logique principale du jeu et les interactions.

✨ Vérifier la solution et pratiquer

Définition des coordonnées des blocs

Ce code définit une fonction constructeur appelée GameBoard qui est utilisée pour créer des objets de plateau de jeu.

// xPos, yPos sont les coordonnées du bloc
function GameBoard(xPos, yPos) {
  // Plateau de jeu
  // Coordonnées des tuiles
  this.high = yPos - 1; // L'index commence à 0
  this.wide = xPos - 1; // L'index commence à 0
  this.count = 0;
  // La coordonnée horizontale est wide, et la coordonnée verticale est high
  //    [0][0] |  [0][1]
  //  - - - - - - - - - - - -
  //    [1][0] |  |[1][1]

  // Création d'un tableau bidimensionnel de tuiles
  this.board = new Array(xPos);
  for (var i = 0; i <= this.wide; i++) {
    this.board[i] = new Array(yPos);
  }
}
✨ Vérifier la solution et pratiquer

Définition des règles du jeu

Le extrait de code que vous avez fourni étend la fonctionnalité du constructeur GameBoard en ajoutant des méthodes prototypiques qui définissent les règles principales du jeu et la logique de présentation.

// Implémentation des règles du jeu
GameBoard.prototype = {
  renderBoard: function () {
    var htmlString = ""; // Structure des carrés de jeu
    for (var j = 0; j <= this.high; j++) {
      htmlString += "<div class='gamerow'>";
      for (var i = 0; i <= this.wide; i++) {
        htmlString += "<div class='gamesquare coord" + i + "q" + j + "'></div>";
      }
      htmlString += "</div>";
    }
    $(".board").html(htmlString);

    for (var i = 0; i <= this.wide; i++) {
      for (var j = 0; j <= this.high; j++) {
        this.processClickView(i, j);
      }
    }
  },
  processClick: function (w, h) {
    //
    // Inversez les couleurs des blocs entourant le bloc cliqué
    //

    // Trouvez les blocs voisins qui doivent être inversés
    var lowx = w - 1;
    var highx = w + 1;
    var lowy = h - 1;
    var highy = h + 1;

    // Vérifiez si le bloc cliqué est un bloc de bord
    if (w == 0) lowx = 0;
    if (w == this.wide) highx = this.wide;
    if (h == 0) lowy = 0;
    if (h == this.high) highy = this.high;

    // Inversez les blocs verticalement adjacents au bloc cliqué
    for (var i = lowy; i <= highy; i++) {
      if (this.board[w][i] == 0) {
        this.board[w][i] = 1;
        this.count++;
      } else {
        this.board[w][i] = 0;
        this.count--;
      }
      this.processClickView(w, i);
    }

    // Inversez les blocs horizontalement adjacents au bloc cliqué
    for (var i = lowx; i <= highx; i++) {
      if (i == w) continue;
      if (this.board[i][h] == 0) {
        this.board[i][h] = 1;
        this.count++;
      } else {
        this.board[i][h] = 0;
        this.count--;
      }
      this.processClickView(i, h);
    }
  },
  // Inversez la couleur d'un bloc
  processClickView: function (w, h) {
    var coord = ".coord" + w + "q" + h;
    if (this.board[w][h] == 0) {
      $(coord).css("background-color", "#e8BB39");
    } else {
      $(coord).css("background-color", "#6060e0");
    }
  },

  // Remettez tous les blocs en couleur orange
  populate: function () {
    for (var i = 0; i <= this.wide; i++) {
      for (var j = 0; j <= this.high; j++) {
        this.board[i][j] = 0;
      }
    }
  },

  // Condition de victoire du jeu
  isGameWin: function () {
    return this.count == (this.wide + 1) * (this.high + 1);
  }
};
✨ Vérifier la solution et pratiquer

Initialisation du jeu

Ce code configure le jeu lorsque le document est prêt. Il initialise le jeu, démarre le premier niveau et configure également des écouteurs d'événements pour réinitialiser le niveau actuel ou démarrer un nouveau jeu.

// Initialiser le jeu
$(document).ready(function () {
  // Créer le jeu
  var game = new Game();
  // Démarrer le jeu
  game.beginGame();

  // Réinitialiser les tuiles du niveau
  $("#resetLevelConfirm").click(function () {
    game.setupLevel();
  });

  // Démarrer un nouveau jeu
  $("#newGameConfirm").click(function () {
    game.onNewGameClick();
  });
});
✨ Vérifier la solution et pratiquer

Exécution de l'application

  • Ouvrez index.html dans un navigateur web.
    open web
  • L'effet de la page est le suivant :
    Image description
✨ Vérifier la solution et pratiquer

Résumé

Dans le développement de ce jeu, nous avons rencontré :

  • Les méthodes orientées objet en JavaScript
  • La référence et la redirection de this interne à JavaScript
  • Comment manipuler le DOM avec jQuery
  • Des problèmes de relation de matrice

Nous n'avons pas réellement besoin de mettre en œuvre cette logique, mais nous devons apprendre l'esprit. Pour résoudre un problème, nous devons tout d'abord analyser le problème et clarifier les relations logiques impliquées. C'est le secret du problème résolu.