podzit / CovidGame

Jeu en ligne pour rire
https://podz.be/CovidGame
0 stars 1 forks source link

Optimisation #2

Closed cromatikap closed 3 years ago

cromatikap commented 3 years ago

J'ai simplifié pas mal de code redondant et résolu le bug des images qui ne s'affichent pas. A part ca le code agit exactement de la meme manière qu'avant, il est juste optimisé pour etre plus simple à lire et plus rapide à executer.

cromatikap commented 3 years ago

Pour le tirage des cartes j'ai du mal à comprendre ce que tu veux faire, tu veux des images rangées dans 2 catégories différentes genre toi et ennemi?

podzit commented 3 years ago

Les 2 catégories sont "comploteurs" et "complotistes". Chaque catégorie possède son dossier dans assets/img (1 et 2). Ça simplifie l'ajout de nouvelles cartes.

cromatikap commented 3 years ago

Oui car cet id n'est pas utilisé. Ce qui est utilisé est id="img-toi" et id="img-ennemi". Cherche pour ces références dans main.js tu vas comprendre comment les cartes se font remplacer. Par contre parfois ça va chercher des .jpeg avec des nombres au delà de ce qui existe dans assets/img/.

cromatikap commented 3 years ago

ça ne peux pas fonctionner, les cartes sont dans les dossiers assets/img/1 ou 2. C'est pour cette raison que j'avais rajouté la variable sep avec la valeur '/'

Okay, peux tu faire un push en ajoutant ces dossiers? Ils sont manquants. Tu peux aussi remettre sep = '/' du coup si les dossiers sont en place

EDIT: au lieu d'appeler les dossiers 1 et 2, appelle les directement par complotistes et comploteurs, toujours dans assets/img/ 😉

podzit commented 3 years ago

ça ne peux pas fonctionner, les cartes sont dans les dossiers assets/img/1 ou 2. C'est pour cette raison que j'avais rajouté la variable sep avec la valeur '/'

Okay, peux tu faire un push en ajoutant ces dossiers? Ils sont manquants. Tu peux aussi remettre sep = '/' du coup si les dossiers sont en place

EDIT: au lieu d'appeler les dossiers 1 et 2, appelle les directement par complotistes et comploteurs, toujours dans assets/img/

ils s'appellent 1 et 2 pour pouvoir choisir aléatoirement, toi et l'ennemi peut avoir cat 1 ou 2 peu importe, ça change juste la tournure du résultat.

cromatikap commented 3 years ago

ils s'appellent 1 et 2 pour pouvoir choisir aléatoirement, toi et l'ennemi peut avoir cat 1 ou 2 peu importe, ça change juste la tournure du résultat.

Tu peux tout à fait nommer tes dossiers par des mots:

// Ici tu déclares le array de catégories
const categories = ['complotistes', 'comploteurs'];

// On prend un nombre au hasard compris entre 0 et la taille du array categories-1
let index = Math.floor(Math.random() * Math.floor(categories.length));

// categories[index] affiche le nom de catégorie lié à la variable index générée la ligne d'avant
document.getElementById("img-toi").innerHTML = `<img src="assets/img/${categories[index]}/${image}" />`;

Liste des avantages:

Si tu connais pas les Array: https://www.w3schools.com/jsref/jsref_obj_array.asp

podzit commented 3 years ago

ils s'appellent 1 et 2 pour pouvoir choisir aléatoirement, toi et l'ennemi peut avoir cat 1 ou 2 peu importe, ça change juste la tournure du résultat.

Tu peux tout à fait nommer tes dossiers par des mots:

// Ici tu déclares le array de catégories
const categories = ['complotistes', 'comploteurs'];

// On prend un nombre au hasard compris entre 0 et la taille du array categories-1
let index = Math.floor(Math.random() * Math.floor(categories.length));

// categories[index] affiche le nom de catégorie lié à la variable index générée la ligne d'avant
document.getElementById("img-toi").innerHTML = `<img src="assets/img/${categories[index]}/${image}" />`;

Liste des avantages:

  • Le code est réutilisable: tu peux ajouter d'autres catégories au array, le code va toujours marcher et choisir aléatoirement une des catégories! Essaye pour voir :)
  • Le code est facile à lire et donc à comprendre: ça permet de minimiser les bugs et de pouvoir améliorer le jeu sans etre perdu.
  • Quelqu'un qui regarde l'arborescence de ton projet comprend beaucoup mieux comment est structuré tes données avec des noms plein que des dossiers numérotés Ce quelqu'un sera aussi toi plus tard quand ton projet prendra en complexité, si tu reviens sur un morceau de code que tu n'as pas vu depuis longtemps tu vas préférer qu'il soit au plus simple et au plus explicite ;)

Si tu connais pas les Array: https://www.w3schools.com/jsref/jsref_obj_array.asp

Ok pour le côté lisible, j'ai déjà expérimenté ce phénomène fort désagréable ;) Mais je me pose la question avec l'array comment gérer l'attribution des valeurs aux cartes ensuite? un truc comme ça? if (categories[index] == 'comploteurs' && choix == 1){valeur1 = 1};

cromatikap commented 3 years ago

Dans ta série de if actuelle, cat est en fait ni plus ni moins que ce que j'ai appelé index dans

...
// On prend un nombre au hasard compris entre 0 et la taille du array categories-1
let index = Math.floor(Math.random() * Math.floor(categories.length));
...

Simplement, j'ai décidé de changer le nom pour que ce soit explicite: ce nombre est un indexe du tableau nommé categories. Il faut juste remplacer tous les cat par index ou renommer index en cat et le code devrait fonctionner exactement comme avant


J'ai du mal à comprendre ce que tu fais avec tous ces if 😅

Ce que ton programme fais, c'est afficher un résultat binaire (gagné ou perdu) + une phrase marrante qui change en fonction des deux cartes tirées de chaque coté toi et ennemi, à partir de là j'ai du mal à comprendre les règles qui régissent le résultat.

podzit commented 3 years ago

😂😂😂 j'avoue que j'ai fait fort avec les if. En fait c'est pour attribuer une "force" à la carte (valeur1 et valeur2). Quand je crée les cartes je leur attribue cette "force" (de façon totalement arbitraire) avec une valeur entre 1 et 6. Donc à un moment dans le code je dois faire une correspondance entre sa catégorie (1 ou 2 pour le moment mais je vais me pencher sur "complotistes" et "comploteurs") son numéro (*.jpeg) et sa "force" (valeur1 ou 2) pour que l'affichage final soit cohérent. exemple avec cette carte de catégorie 1, numéro 10, force 5: 10 J'avais réfléchi à une méthode pour passer la force au script à travers un nommage particulier du fichier image mais à priori javascript n'en est pas capable (client-side et pas server-side). Donc j'ai fait du if frénétique 😂

cromatikap commented 3 years ago

Okay, ça commence à etre plus clair mais pas completement encore. Pour chaque duel de carte, la carte la plus forte l'emporte si j'ai bien compris. D'abord tu cherches à prendre au hasard une catégorie, puis dans cette catégorie tu veux une image prise au hasard, c'est bien ça ?

En fait dans ce cas là tu peux simplement voir chaque carte comme un objet qui a comme propriétés une categorie, un nom et une force. Exemple:

const carte = {
  categorie: 'comploteur',
  force: 5,
  nom: 10 // <- la carte 10.jpeg
}
console.log(`Carte de niveau ${carte.force} dont l'image se trouve à assets/img/${carte.categorie}/${carte.nom}.jpeg`);

output: Carte de niveau 5 dont l'image se trouve à assets/img/comploteur/10.jpeg

Une fois que tu as bien compris cette histoire d'objet, il suffit de faire un array de cartes Exemple:

const deck = [
{
  categorie: 'comploteur',
  force: 5,
  nom: 10 // <- la carte 10.jpeg
},
{
  categorie: 'complotiste',
  force: 2,
  nom: 3 // <- la carte 3.jpeg
},
{ 
  etc... 
},
etc...
];

let carteToi = deck[Math.floor(Math.random() * Math.floor(deck.length))]
let carteEnnemi = deck[Math.floor(Math.random() * Math.floor(deck.length))];

document.getElementById("img-toi").innerHTML = `<img src="assets/img/${carteToi.nom}.jpeg" />`;
document.getElementById("img-ennemi").innerHTML = `<img src="assets/img/${carteEnnemi.nom}.jpeg" />`;

if (carteToi.force === carteEnnemi.force)
  // egalité
else if (carteToi.force < carteEnnemi.force)
  // perdu
else
  // gagné

A partir de là, tu as 2 cartes tirée aléatoirement et le résultat de qui a gagné. Tu as peut-etre remarqué que, structuré de cette manière, il n'est plus nécessaire de créer un sous dossier par catégorie puisque cette information réside directement dans le code, dans chaque objet carte contenu dans le Array deck. Dans le meme temps, tu peux aussi appeler les cartes par leur nom d'usage, pas besoin de numéroter.

Après ce morceau de code, la seule chose qui reste à faire est de générer les phrases finales en fonction des catégories misent en jeu (Ex: Si ton résultat est "perdu", tu peux alors voir "Looser ! Le complot mondial a eu ta peau" ou encore "Dommage ! Tu as été trahis par tes amis" ou encore etc...) :+1:

podzit commented 3 years ago

ah oui ça m'a l'air vraiment plus simple et plus clair. Du coup pour les phrases finales ça donnerait un truc du genre? //perdu if (carteToi.categorie == 'comploteurs' && carteEnnemi.categorie == 'complotistes'){result="battu par les complotistes"}

podzit commented 3 years ago

Je garderai bien quand même la numérotation et les 2 dossiers pour les noms des images des cartes je trouve ça plus simple pour les nouveaux ajouts.

podzit commented 3 years ago

Bon bah je viens d'appliquer tes suggestions et clairement c'est top !

podzit commented 3 years ago

mouhahahaha j'ai ajouté un générateur de phrases finales !!! Je m'éclate...

cromatikap commented 3 years ago

ah oui ça m'a l'air vraiment plus simple et plus clair.

On a divisé la logique en 4 parties:

Ainsi tu peux te concentrer sur chaque partie sans penser au reste. Comme tu viens de le remarquer, ça te donne ensuite la possibilité de visualiser et écrire la prochaine fonctionnalité naturellement (le générateur de phrases finales) Il faut toujours chercher redécouper ton programme en plusieurs petites parties simples 👍

Du coup pour les phrases finales ça donnerait un truc du genre? //perdu if (carteToi.categorie == 'comploteurs' && carteEnnemi.categorie == 'complotistes'){result="battu par les complotistes"}

Oui tout à fait!

Je garderai bien quand même la numérotation et les 2 dossiers pour les noms des images des cartes je trouve ça plus simple pour les nouveaux ajouts.

Si ça te semble plus simple pour l'ajout des cartes tu peux garder le système des sous-dossiers, mais je te conseille de les nommer avec le nom de la catégorie et non pas par des numéros, ça t'aidera aussi beaucoup pour ne pas t'emmeler les pinceaux quand tu mets une image dans une certaine catégorie. Ce qui serait encore mieux, c'est aussi de nommer tes images par le nom de la carte (ex: assets/img/comploteurs/illuminatis.jpeg)

En tout cas bravo à toi ! J'essaierai ton dernier commit cette après-midi si je trouve le temps. J'aimerais bien améliorer le visuel avec un peu de css. Maintenant que le html est simple et que toute la partie logique (javascript) a été bougé dans un autre fichier, ça va être faisable facilement sans créer de bug ;)

Ce que je te propose de faire maintenant, c'est de diviser le fichier javascript en deux:

podzit commented 3 years ago

C'est la révolution pour moi les array et objets ! J'ai gardé les 2 sous dossiers pour les cartes et les ai renommés en 'comploteurs' et 'complotistes'. Je ne sais pas comment faire un push à partir de github (je n'ai pas d'accès ssh à mon serveur web).

Je vais probablement finir par renommer les cartes, effectivement ce sera plus simple.

En tout cas bravo à toi ! J'essaierai ton dernier commit cette après-midi si je trouve le temps. J'aimerais bien améliorer le visuel avec un peu de css. Maintenant que le html est simple et que toute la partie logique (javascript) a été bougé dans un autre fichier, ça va être faisable facilement sans créer de bug ;)

Merci. J'apprend beaucoup grace à tes modifs, c'est super intéressant.

Ce que je te propose de faire maintenant, c'est de diviser le fichier javascript en deux:

assets/main.js <- le fichier principal qui régie les règles algorithmiques du jeu assets/data.js <- le deck de cartes

OUI ! j'ai regardé vite fait comment c'était possible de scinder les javascript mais j'ai préféré laisser ça de côté et étoffer le main.js pour éviter de faire planter le jeu.

Je vais faire un nouveau commit d'ici quelques minutes avec plus de mots et... du son. à voir si c'est pas trop prise de tête pour le visiteur, moi ça me fait marrer, ça ajoute un peu d'ambiance.

cromatikap commented 3 years ago

Je ne sais pas comment faire un push à partir de github (je n'ai pas d'accès ssh à mon serveur web).

Normalement tu développe sur ta machine localement, ensuite c'est

$ git add .
$ git commit -m "explication du commit"
$ git push origin main

C'est un serveur ftp que tu as? Tu te connectes avec filezilla?

Merci. J'apprend beaucoup grace à tes modifs, c'est super intéressant.

Bienvenue dans l'open source ;)

OUI ! j'ai regardé vite fait comment c'était possible de scinder les javascript mais j'ai préféré laisser ça de côté et étoffer le main.js pour éviter de faire planter le jeu.

C'est un petit challenge que je te laisse, c'est pas très compliqué, normalement même sans google tu devrais trouver comment faire (mais n'hésite pas à chercher sur google quand même!)

Je vais faire un nouveau commit d'ici quelques minutes avec plus de mots et... du son. à voir si c'est pas trop prise de tête pour le visiteur, moi ça me fait marrer, ça ajoute un peu d'ambiance.

C'est bon ça! 😆

Je te laisse faire les modifs que tu veux sur la partie javascript, je vais faire un commit côté html et css, ça devrait pas créer de conflit comme ça

podzit commented 3 years ago

j'ai modifié l'index pour ajouter une balise pour l'audio hyper complexe: <div id="audio"></div> Hésite pas à me contacter si tu as du mal à la comprendre lol

cromatikap commented 3 years ago

Yep j'ai vu, il devrait y avoir une solution pour ne pas avoir besoin de rajouter une balise mais c'est bien petit, clean et on comprend clairement à quoi sert cette balise donc pour l'instant on peut laisser comme ça :)

Je viens de pull la dernière version avec le son c'est top!

podzit commented 3 years ago

C'est un serveur ftp que tu as? Tu te connectes avec filezilla?

Oui exactement. il y a une façon de faire du git via filezilla?

cromatikap commented 3 years ago

Oui exactement. il y a une façon de faire du git via filezilla?

Non, simplement tu dévelopes en local sur ton PC et regarde les changements dans ton navigateur. Tu push pour mettre à jour le code et le partager publiquement. Une fois que tu es pret à release la dernière version (mise en production), simplement tu remplaces tous les fichiers du FTP par ceux qui sont dans ton répertoire local en utilisant filezilla.

Et avec git, tu as la possibilité de pull les autres branches pour voir les changements et tester le code, ensuite si le résultat te plait tu peux merger la branche dans main et ensuite push sur github. Normalement c'est ca le flow developpement / production

podzit commented 3 years ago

Je galère pour la séparation des fichiers. J'ai essayé pleins de chose mais rien ne fonctionne. celui qui devrait fonctionner à priori c'est :

dans data.js export const deck =[...]

dans main.js import deck from "./data.js"

dans index.html <script type="module" src="assets/data.js" ></script>

mais rien n'y fait du coup le jeu ne fonctionne plus du tout.

J'ai une erreur dans la console mais pas sûr que ce soit vraiment ça qui bloque: Uncaught SyntaxError: Cannot use import statement outside a module

podzit commented 3 years ago

ok problem solved !

cromatikap commented 3 years ago

Ta page html demande déjà au navigateur "d'importer" et d'executer assets/data.js puis assets/main.js via les balises <script>. Si tu ne le déclares pas en type module, ça devrait fonctionner sans même utiliser import/export. Mais le déclarer en type module est aussi une bonne pratique, bien joué pour ça.

Je te conseille de mettre les <script type="module" src="assets/data.js" ></script> et <script type="module" src="assets/main.js" ></script> au même endroit dans ton code html (dans le <head> avec data.js par exemple).

Habituellement, on met souvent les <script> en bas de page html, comme ça on est sûr que le navigateur a d'abord bien lu toutes les balises html avant d'executer le javascript (qui, bien souvent, va venir modifier le DOM). Mais heureusement, les standards web ont évolué et si tu ajoutes type="module", le navigateur va attendre que le document html soit complètement chargé et prêt avant de les executer (ce qui est une bonne chose!)