Maison >interface Web >js tutoriel >Cellule libre gratuite
Il y a longtemps, exactement dans la même galaxie, j'ai commencé à essayer de créer Freecell, pour apprendre Angular 1.3.
Je suis arrivé jusqu'ici, puis j'ai été distrait par d'autres choses, tout comme les projets parallèles.
J'ai eu du temps libre récemment (je sais, je ne m'y attendais pas non plus) et j'ai donc pensé que j'allais essayer à nouveau.
Je suis essentiellement parti de zéro, car je ne suis plus intéressé par Angular 1.3, et j'ai tendance à utiliser VueJS pour mes contenus Web si j'ai besoin d'un framework.
Pour voir les résultats, c'est sur github.io : cliquez ici pour jouer à freecell !
Depuis que j'ai appris WPF il y a quinze ans, j'ai vraiment aimé le style de programmation MVVM. VueJS permet ce style très facilement, et l'améliore même, sans avoir besoin d'événements explicites pour mettre à jour l'interface utilisateur.
Cela signifie que la logique du jeu est complètement séparée de la logique de vue, ce qui a rendu l'écriture de ce jeu un jeu d'enfant.
Ce n'était pas uniquement une navigation en avion, car, pour une raison quelconque, j'ai décidé de stocker les cartes dans un tableau irrégulier 2D. Ce n'est pas une mauvaise idée, mais chaque tableau interne est une colonne, et donc quand j'essayais de disposer correctement les cartes dans une grille CSS, je ne pouvais pas simplement parcourir l'extérieur puis l'intérieur comme
<template v-for="cardCol in game.table"> <template v-for="card in cardCol">
Parce que cela disposerait les colonnes sous forme de lignes. J'ai donc dû utiliser des indices (pourquoi VueJS ne démarre-t-il pas à 0 ???) plutôt que des objets et boucler sur le tableau externe sur la boucle intérieure :
<template v-for="rowi in game.getLargestColumnCount()"> <template v-for="coli in game.table.length"> <div v-if="game.table[coli-1].length == 0 && rowi == 1" :class="'card column'+coli+' freecell'"> <img src="cards/blank.png" @click="game.selectDropClear(coli-1, rowi-1)" > </div> <div v-else-if="game.getCard(coli-1, rowi-1) != ''" :class="'card '+cardClass(coli-1, rowi-1)"> <img :alt="cardToCardName(game.getCard(coli-1, rowi-1))" :src="'cards/'+game.getCard(coli-1, rowi-1)+'.png'" @click="game.selectDropClear(coli-1, rowi-1)"> </div> </template> </template>
Je pense que les deux autres mauvaises décisions de conception que j'ai prises sont d'implémenter la saisie semi-automatique et de faire en sorte que les gestionnaires de clics ne soient qu'une fonction dans le jeu (c'est-à-dire le modèle), plutôt que dans la vue et que la vue détermine quel processus action à entreprendre.
Le fait que le jeu décide quelle action le joueur veut dire (c'est-à-dire sélectionner une carte (ou une pile de cartes), placer des cartes sur une autre pile ou désélectionner des cartes) a conduit à un code spaghetti que je souhaiterais peut-être refactoriser plus tard.
Au départ, je ne voulais pas implémenter la saisie semi-automatique parce que je ne voulais pas penser à la logique. Mais après avoir joué quelques parties sans cela, je me suis tellement ennuyé en tapant chaque carte dans la rangée de départ que je me suis senti obligé de le mettre en œuvre.
J'aurais dû m'en tenir à mes positions parce que c'est tout simplement mauvais. Il s’agit d’un énorme morceau de code qui a initialement provoqué un tas de bugs et de casse-tête. Ce n'est même pas entièrement automatique. D'un autre côté, je n'ai plus besoin de faire autant de tapotements.
Je suis resté fidèle à mon objectif de ne pas faire en sorte que les cartes soient glissées et déposées, car j'ai fait cela principalement pour jouer sur mon téléphone et ma tablette, donc il est beaucoup plus facile de les mettre en place du point de vue UX (du moins mon UX, miamv).
Dans l'ensemble, je suis satisfait du résultat, même s'il reste quelques bugs qui persistent juste hors de vue.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!