SOKOBAN vs POO / Partie 5 : physique & partie

Creations

chris-scientist

5 years ago

INTRODUCTION

Dans les parties précédentes nous avons vu les bases de notre programme, la gestion de la caméra, la gestion de l'affichage et la gestion du personnage. Nous allons voir dans cette cinquième et dernière partie la gestion de la physique et la gestion de la partie, ainsi à la fin de cette partie nous serons en mesure de faire déplacer une caisse par le personnage, de s'arrêter face à un mur et de déterminer si la partie est terminée.

Les pré-requis de ce tutoriel sont :

Je vous invite à télécharger le code qui est le résultat de la quatrième partie, ceci pour partir sur des bases communes.

LA PHYSIQUE : COLLISION AVEC LES MURS

Il faut pouvoir rester bloqué si l'on cherche à franchir un mur, sachez qu'il s'agit de l'affaire de quelques lignes et que tout ce passe dans CharacterController.

D'abord, nous allons écrire la méthode pour détecter que le sprites (que nous nommerons aReplacedSprites) est un mur, il s'agit de la méthode isWall, voici le pseudo code :

SI aReplacedSprites = mur ALORS
  Retourner vrai
SINON
  Retourner faux
FIN SI

Ceci dit ce pseudo code peut-être optimisé, en effet la condition renvoye vrai ou faux, le pseudo code est ainsi :

Retourner (aReplacedSprites = mur)

Voici le code de la méthode :

const bool CharacterController::isWall(const char aReplacedSprites) const {
  return (aReplacedSprites == TypeOfSprites::WALL_TYPE);
}

Enfin nous avons plus qu'à interdire le déplacement si le sprite est un mur. Rappelez-vous du pseudo code du déplacement vers le haut par exemple, qui était le suivant :

Calculer la position fictive relative à un déplacement vers le haut
Récupérer le sprites relatif à la position fictive
SI nous sommes toujours sur la carte avec la position fictive ALORS
  Ecraser la position fictive avec la tuile correspondant au joueur
  Remplacer l'ancienne position du joueur par le sprites qui s'y trouvait avant
  Stocker le sprites relatif à la position fictive
  Mettre à jour la position du personnage
SINON
  Réintialiser la position fictive
FIN SI

Voici le pseudo code d'un déplacement vers le haut qui interdit de franchir un mur :

Calculer la position fictive relative à un déplacement vers le haut
Récupérer le sprites relatif à la position fictive
SI nous sommes toujours sur la carte avec la position fictive ET le sprites où nous voulons aller n'est pas un mur ALORS
  Ecraser la position fictive avec la tuile correspondant au joueur
  Remplacer l'ancienne position du joueur par le sprites qui s'y trouvait avant
  Stocker le sprites relatif à la position fictive
  Mettre à jour la position du personnage
SINON
  Réintialiser la position fictive
FIN SI

Voici le code du déplacement vers le haut avec la contrainte relative au franchissement de mur :

void CharacterController::goUp() {
  // calcul de la nouvelle position
  character->goUp();
  // récupérer la tuile de la nouvelle position
  char newTypeOfSprites = mapModel->getTypeOfSprites(character->getNextPos()[0], character->getNextPos()[1]);
  // si la nouvelle position du personnage est sur la carte et que ce n'est pas un mur
  if(character->getNextPos()[1] >= 0 && !isWall(newTypeOfSprites)) {
    // écraser nouvelle position par la tuile du joueur
    mapModel->setTypeOfSprites(character->getNextPos()[0], character->getNextPos()[1], getPlayerSprites(newTypeOfSprites));
    // remplacer ancienne position par la tuile qui était à cette position précédement
    mapModel->setTypeOfSprites(character->getX(), character->getY(), character->getOldTypeOfSprites());
    // stocker la tuile de la nouvelle position
    character->setOldTypeOfSprites(newTypeOfSprites);
    // mettre à jour la position
    character->updatePositions();
  } else {
    // remettre à zéro la position suivante
    character->resetNextPositions();
  }
}

Ajouter la contrainte aux autres déplacements et le tour sera joué.

LA PHYSIQUE : DÉPLACER UNE CAISSE

Nous allons maintenant voir le déplacement d'une caisse, sachez que c'est plus complexe que la contrainte précédente, mais je suis là pour vous guider. Et comme la contrainte précédente tout ce joue dans CharacterController.

Commençons par écrire le pseudo code de détection d'une caisse, pensez à la simplification utilisé lors de la détection de mur :

Retourner (aReplacedSprites = caisse) || (aReplacedSprites = caisse sur zone de 'chargement')

Voici le code de la méthode isBox :

const bool CharacterController::isBox(const char aReplacedSprites) const {
  return (aReplacedSprites == TypeOfSprites::BOX_TYPE) || 
    (aReplacedSprites == TypeOfSprites::BOX_ON_ZONE_TYPE);
}

Ecrivons un gros morceau, soit le pseudo code pour déplacer une caisse, il s'agit de la méthode moveBox. Les paramètres de cette méthode sont le sprites à remplacer (aReplacedSprites), les coordonnées X1, Y1 ainsi que les coordonnées X2, Y2 ces dernières représentent le sprite après la caisse. Voici le pseudo code  :

Récupérer le sprites ayant pour coordonnéées X2, Y2
Affecter à stopMove la valeur du test suivant : est différent du sol ou différent d'une zone de chargement
SI stopMove est faux ALORS
  SI le sprites de coordonnées X2, Y2 est une zone de chargement ALORS
    Affecter à replacedSprites2 un sprite de type caisse sur zone de chargement
  SINON
    Affecter à replacedSprites2 un sprite de type caisse
  FIN SI
  Ecraser la position X2, Y2 par replacedSprites2
  SI aReplacedSprites = caisse sur zone de chargement ALORS
    Retourner sprites de type zone de chargement
  SINON
    Retourner sprites de type sol
  FIN SI
FIN SI
Retourner aReplacedSprites

Nous pouvons simplifier le code à l'aide d'une condition particulière que l'on appelle condition ternaire. Voyons comment faire sur un exemple de pseudo code :

SI nb > 0 ALORS
  Affecter à signe la valeur '+'
SINON
  Affecter à signe la valeur '-'
FIN SI

Voici le code relatif à cette exemple, utilisant une condition ternaire :

char signe = (nb > 0) ? '+' : '-';

Je vous ai donner cette simplification car nous pouvons l'utiliser à deux reprises dans le code de moveBox que voici :

const char CharacterController::moveBox(const char aReplacedSprites, const int aX1, const int aY1, const int aX2, const int aY2) {
  // on récupère le sprites en X2, Y2
  const char sprites = mapModel->getTypeOfSprites(aX2, aY2);
  // si c'est le sol ou une zone de chargement alors on déplace la caisse
  stopMove = !((sprites == TypeOfSprites::FLOOR_TYPE) || (sprites == TypeOfSprites::DESTINATION_TYPE));
  if(!stopMove) {
    // on calcul le sprites X2, Y2
    const char replacedSprites2 = (sprites == TypeOfSprites::DESTINATION_TYPE) ? TypeOfSprites::BOX_ON_ZONE_TYPE : TypeOfSprites::BOX_TYPE ;
    // on affecte le sprites X2, Y2
    mapModel->setTypeOfSprites(aX2, aY2, replacedSprites2);
    return (aReplacedSprites == TypeOfSprites::BOX_ON_ZONE_TYPE) ? TypeOfSprites::DESTINATION_TYPE : TypeOfSprites::FLOOR_TYPE;
  }
  return aReplacedSprites;
}

Remarque : une optimisation est facultative mais possible, en effet nous n'avons pas besoin du couple de coordonnées X1, Y1, il peut donc être supprimer. Il s'agit d'une erreur de ma part, j'ai oublié de le supprimer dès la partie 1 de ce tutoriel.

Il nous reste plus qu'à connecter les deux méthodes que l'on vient d'écrire au déplacement. Nous allons nous servir du déplacement vers le haut pour notre exemple, voici le pseudo code avec la contrainte de déplacement d'une caisse :

Calculer la position fictive relative à un déplacement vers le haut
Récupérer le sprites relatif à la position fictive
SI nous sommes toujours sur la carte avec la position fictive ET le sprites où nous voulons aller n'est pas un mur ALORS
  SI le sprites relatif à la position fictive est une caisse ALORS
    Faire un appel à la méthode de déplacement d'une caisse et affecter la valeur de retour au sprites relatif à la positioon fictive
  SINON
    Affecter à stopMove la valeur false
  FIN SI

  SI stopMove est faux ALORS
    Ecraser la position fictive avec la tuile correspondant au joueur
    Remplacer l'ancienne position du joueur par le sprites qui s'y trouvait avant
    Stocker le sprites relatif à la position fictive
    Mettre à jour la position du personnage
  SINON
    Réintialiser la position fictive
  FIN SI
SINON
  Réintialiser la position fictive
FIN SI

Voici le code de la méthode goUp modifier avec la contrainte de déplacement d'une caisse :

void CharacterController::goUp() {
  // calcul de la nouvelle position
  character->goUp();
  // récupérer la tuile de la nouvelle position
  char newTypeOfSprites = mapModel->getTypeOfSprites(character->getNextPos()[0], character->getNextPos()[1]);
  // si la nouvelle position du personnage est sur la carte et que ce n'est pas un mur
  if(character->getNextPos()[1] >= 0 && !isWall(newTypeOfSprites)) {
    // déplacer une caisse
    if(isBox(newTypeOfSprites)) {
      newTypeOfSprites = moveBox(newTypeOfSprites, character->getNextPos()[0], character->getNextPos()[1], character->getNextPos()[0], character->getNextPos()[1] - 1);
    } else {
      stopMove = false;
    }

    if(!stopMove) {
      // écraser nouvelle position par la tuile du joueur
      mapModel->setTypeOfSprites(character->getNextPos()[0], character->getNextPos()[1], getPlayerSprites(newTypeOfSprites));
      // remplacer ancienne position par la tuile qui était à cette position précédement
      mapModel->setTypeOfSprites(character->getX(), character->getY(), character->getOldTypeOfSprites());
      // stocker la tuile de la nouvelle position
      character->setOldTypeOfSprites(newTypeOfSprites);
      // mettre à jour la position
      character->updatePositions();
    } else {
      character->resetNextPositions();
    }
  } else {
    // remettre à zéro la position suivante
    character->resetNextPositions();
  }
}

Le code pour les autres directions est similaire, à l'exception des coordonnées X2, Y2 passé à moveBox qu'il faut adapter, voyons cela.

Aller vers la droite

X2 = character->getNextPos()[0] + 1
Y2 = character->getNextPos()[1]

Aller vers le bas

X2 = character->getNextPos()[0]
Y2 = character->getNextPos()[1] + 1

Aller vers la gauche

X2 = character->getNextPos()[0] - 1
Y2 = character->getNextPos()[1]

Une fois les méthodes complétées, amusez vous avec le jeu, en effet vous devriez être en mesure de déplacer les caisses sur les zones de chargement.

GESTION DE LA PARTIE

Dans ce dernier chapitre du tutoriel nous allons aborder la gestion de la fin de partie. Effectivement il serait bien de féliciter le joueur lorsque celui-ci à déplacer l'ensemble des caisses sur les zones de chargement.

Pour cela il faut parcourir la carte, la méthode isFinish de MapModel nous indique si le jeu est terminée ou non (via isEnd), voici le pseudo code :

Affecter à isEnd la valeur true
PARCOURIR la carte sur l'axe Y tant que le jeu est terminé
  PARCOURIR la carte sur l'axe X tant que le jeu est terminé
    Affecter à isEnd la valeur de isEnd ET (sprites X, Y différent de zone de chargement ET sprites X, Y différent de caisse)
  FIN PARCOURIR
FIN PARCOURIR
Retourner isEnd

Voici le code de la méthode :

bool MapModel::isFinish() const {
  bool isEnd = true;
  for(int y=0 ; y < HEIGHT_MAP && isEnd ; y++) {
    for(int x=0 ; x < WIDTH_MAP && isEnd ; x++) {
      isEnd = isEnd && !(mapOfGame[y][x] == TypeOfSprites::DESTINATION_TYPE || mapOfGame[y][x] == TypeOfSprites::BOX_TYPE);
    }
  }
  return isEnd;
}

Il faut maintenant que le contrôleur ai accès à isFinish, on rend cela possible via la méthode isEndOfGame de MapController que voici:

bool MapController::isEndOfGame() const {
  return model->isFinish();
}

Modifions la méthode run de MainController pour que lorsque la partie est finie on affiche un écran "Gagné", soit le code suivant :

void MainController::run() {
  if(! mapController->isEndOfGame()) {
    characterController->run();
    const int* cameraPos = cameraModel->getCameraPositions(characterController->getX(), characterController->getY());
    mapController->paint(cameraPos);
  } else {
    gb.display.setFontSize(2);
    gb.display.setColor(BROWN);
    gb.display.println("");
    gb.display.println("");
    gb.display.println("  Gagne");
  }
}

Votre jeu est maintenant complétement jouable, amusez vous bien !

CONCLUSION

Cette partie était la dernière du tutoriel. Vous pouvez télécharger le code source final. Le jeu est jouable mais également améliorable. En effet il pourrait être intéressant de pouvoir recommencer la partie (sans avoir à quitter le jeu), ou bien avoir plusieurs cartes, etc. Mais le but de ce tutoriel était de proposer une initiation à la programmation orienté objet et au modèle d'architecture Modèle Vue Contrôleur, j'espère que ce tutoriel vous servira dans vos prochaine créations. Le découpage de ce tutoriel n'est pas anodin, effectivement nous avons développer chacune des briques de notre jeu pas à pas, bloc de fonctionnalités après bloc, et c'est comme cela que vous devez concevoir vos jeux. Enfin comme les autres parties n'hésitez pas à me donner votre avis.

Aller plus loin

Avant de partir, et si vous voulez voir une autre approche du MVC, je vous conseille fortement de lire l'excellent tutoriel de steph sur le jeu de la vie disponible ici. Le tutoriel présente le jeu selon différentes approches : une approche fonctionnelle jusqu'au MVC en passant par une version purement objet. De plus, il a ajouté, toujours dans ce tutoriel, des interactions avec les LEDs ainsi que des effets sonores.

View full creation

jicehel

NEW 5 years ago

Bravo, on est au bout et ça fait un bel exercice  ;)  Pour se servir de ton code complètement (par exemple pour des ex-nouveaux qui chercheraient à écrire leur premier programme), tu pourrais ajouter un chapitre bonus simple avec la gestion des sons lors des événements (ça c'est simple) et surtout les états du jeu (initialisation, pause, en cours, menu). Sinon, tu pourrais aussi ajouter la partie changement de niveau et dans ce cas, sauvegarder le dernier niveau atteint et proposer au joueur de repartir du dernier niveau franchi au démarrage ou de choisir lui même un niveau de démarrage parmi ceux déjà passé. Pendant la pause, éventuellement, on peut aussi mettre une petite animation, voir sauvegarder l'état du niveau pour proposer un reprendre au démarrage du jeu. Bon bref, à toi de voir si tu rajoutes ces options dans un 6ème tutoriel "bonus", l'avantage serait d'une part d'avoir un joli jeu complet (d'ailleurs tu pourrais faire une création avec le jeu final) et un exemple commenté d'un jeu réalisé de A à Z avec toutes les composantes principales.

chris-scientist

5 years ago

Merci ;)

Je vais y réfléchir, même si j'avoue que l'idée d'avoir plusieurs niveaux me tente et avec pourquoi pas un système de sauvegarde.

Pour les sons je m'y suis jamais frotter encore mais ça pourrait être cool.

Si je dois intégrer ces modifications en particulier le premier lot ça demande une restructuration du code et donc je ferais probablement un nouveau tutoriels. Ce sera bien évidement une suite mais ça implique des modifications du code (et je pense à des nouveaux concepts comme l'héritage).

Je vais voir la demande qu'il y a sur ces améliorations, à suivre dans de prochaines aventures.

Je vais peut-être faire un jeu pour faire un break.

chris-scientist

NEW 5 years ago

jicehel jicehel

Merci ;)

Je vais y réfléchir, même si j'avoue que l'idée d'avoir plusieurs niveaux me tente et avec pourquoi pas un système de sauvegarde.

Pour les sons je m'y suis jamais frotter encore mais ça pourrait être cool.

Si je dois intégrer ces modifications en particulier le premier lot ça demande une restructuration du code et donc je ferais probablement un nouveau tutoriels. Ce sera bien évidement une suite mais ça implique des modifications du code (et je pense à des nouveaux concepts comme l'héritage).

Je vais voir la demande qu'il y a sur ces améliorations, à suivre dans de prochaines aventures.

Je vais peut-être faire un jeu pour faire un break.

jicehel

NEW 5 years ago

Oui, c'est clair, tu peux faire un break. Tu as atteins l'objectif du tuto qui était d'expliquer la POO (et même plus), de l'illustrer avec des exemples et des exercices et de montrer qu'à la fin ça fonctionne  ;)

Le reste, ce ne sera que du bonus et ce n'est en effet plus lié à la POO à proprement parler mais plus sur la structure du programme et sur le jeu par lui même.

Aurélien Rodot

NEW 5 years ago

Belle série de tutos Chris, merci pour ta contribution ! Je n'ai pas encore eu le temps de me pencher dessus mais ça a l'air bien complet, on pourrait envisager de l'intégrer à l'académie :)

chris-scientist

5 years ago

Merci, ce serait un plaisir que de voir le tutoriel dans l’académie ;)

chris-scientist

NEW 5 years ago

Aurélien Rodot Aurélien Rodot

Merci, ce serait un plaisir que de voir le tutoriel dans l’académie ;)

Come

NEW 5 years ago

j’ai hâte d’avoir le temps de le faire   ;)

chris-scientist

5 years ago

Donne nous ton avis quand tu l’aura fait ;)

chris-scientist

NEW 5 years ago

Come Come

Donne nous ton avis quand tu l’aura fait ;)

Max

NEW 5 years ago

Roooo,
Excellent tutoriel.
J'attends tellement d'en voir un sur un thème grand classique qu'est le jeu de plateforme comme un Mario like. Pour une approche de la gestion du comportement du personnage (saut, gravité, power-up, etc), des ennemis, du début et fin d'un niveau, gestion d'un menu, d'une sauvegarde, d'une bande son, des effets sonores. J'avoue que j'attendais avec impatience ce genres de tutoriels "musclés" dans l'Académie, qui soit à la hauteur d'une gamebuino Meta :)... Arf, si le cœur vous en dit !

chris-scientist

5 years ago

@Max Content d'apprendre que tu aime le tutoriel ! Pour l'instant j'ai un projet qui est de concevoir un framework pour la META afin de réaliser des Sokoban-like... et je dois avouer que je ne suis plus vraiment actif sur ce sujet en ce moment (mais j'aimerai bien le finir)...

jicehel

NEW 5 years ago

Argh, je te dirais bien que j'en ferais bien un mais vu déjà le peu de temps que j'ai et ce que je me suis mis dans la to do liste, je passe mon tour pour le moment. En plus maintenant, on a plusieurs rédacteur de tuto. D'ailleurs Max, même si tu débute, tu peux prendre un sujet qui n'existe pas et te lancer. C'est très formateur. Tu trouves assez facilement des réponses sur le net pour faire les choses. Il faut les adapter et si tu butes sur quelque chose, tu demandes, tu comprends et tu continues l'écriture de ton article pour les autres. Il faut juste ne pas prendre un sujet trop ambitieux au départ. 

Tu peux regarder un code à adapter légèrement: https://openclassrooms.com/forum/sujet/gestion-collision-et-deplacement-de-mario et lire des tutos super bien fait et ce tuto: https://jeux.developpez.com/tutoriels/tile-mapping-construction-niveau/simple-personnage/

C'est a adapter mais ça montre les principes. Il y a plein d'autres tutos de ce style en cherchant un peu sur la toile. Le fait d'écrire et d'organiser, je trouve que ça permet de progresser plus vite, mais c'est mon point de vue. Je pense que chris-scientist a éprouvé la même chose et Steph aussi d'après les commentaires que j'ai lu. A toi de voir ou d'attendre qu'on le fasse  ;)

Max

5 years ago

Merci pour les liens et les conseils :)

Mais j'avoue qu'au prix et ce pourquoi la console est mise en avant (apprendre à coder du jeu), on s'attend à plus que d'être livré à soi-même et avoir huit tutoriels. Pour moi l'académie telle qu'elle est là, n'est qu'une petite ébauche. Et très franchement j'ai l'impression d'être loin du projet soutenu sur Kickstarter. Si apprendre à programmer du jeu s'arrête au casse-brique, alors je n'ai pas tout saisi...
Chercher, essayer, se planter, recommencer est un bon apprentissage qui, toutefois, a ses limites. Mais prétexter une "méthode" pédagogique pour en faire le moins possible, non... je n'ai pas participé à Kickstarter pour ça...

La goutte d'eau qui fait déborder le vase c'est d'être tombé sur un article qui annonce qu'ils ont en projet une console à monter soi-même pour 2019, et de l'autre côté le dernier tutoriel date de 4 mois pour la META... c'est inachevé.

(c'est un coup de gueule qui n'est pas lancé gratuitement, je le dis parce que ce projet me plait toujours autant qu'à la première heure, et j'écris tout ça comme une critique un peu dure mais dans l'espoir qu'elle soit constructive ;) )

Max

NEW 5 years ago

jicehel jicehel

Merci pour les liens et les conseils :)

Mais j'avoue qu'au prix et ce pourquoi la console est mise en avant (apprendre à coder du jeu), on s'attend à plus que d'être livré à soi-même et avoir huit tutoriels. Pour moi l'académie telle qu'elle est là, n'est qu'une petite ébauche. Et très franchement j'ai l'impression d'être loin du projet soutenu sur Kickstarter. Si apprendre à programmer du jeu s'arrête au casse-brique, alors je n'ai pas tout saisi...
Chercher, essayer, se planter, recommencer est un bon apprentissage qui, toutefois, a ses limites. Mais prétexter une "méthode" pédagogique pour en faire le moins possible, non... je n'ai pas participé à Kickstarter pour ça...

La goutte d'eau qui fait déborder le vase c'est d'être tombé sur un article qui annonce qu'ils ont en projet une console à monter soi-même pour 2019, et de l'autre côté le dernier tutoriel date de 4 mois pour la META... c'est inachevé.

(c'est un coup de gueule qui n'est pas lancé gratuitement, je le dis parce que ce projet me plait toujours autant qu'à la première heure, et j'écris tout ça comme une critique un peu dure mais dans l'espoir qu'elle soit constructive ;) )

Steph

5 years ago

Max, je préfère te répondre en ouvrant une discussion plus large sur le sujet que tu évoques, qui sort du cadre de Sokoban vs POO et qui donc n'a rien à faire ici.

Ma réponse est ici.

jicehel

NEW 5 years ago

Oui, je comprends ton point de vue et je le partage en partie sur la partie Académie que l'on pourrait voir s'enrichir plus rapidement en français et en anglais. Après, on a une petite communauté avec des volontaires prêt à se retrousser les manches et à donner un coup de main et à faire des essais, créer des programmes et pousser la machine un peu comme Sorunome, Aoneil, Steph et on a des programmeurs super mais qui n'ont malheureusement pas assez de temps pour développer plus sur la META comme Eriban, SiegfriedCross ou STUDIOCRAFTapps. Après il y a pas mal d'atelier organisé à Saint-Etienne mais bon ça ne concerne qu'une partie des utilisateurs de la META.

Donc pour ton coup de gueule, je suis partagé en 2: d'une part c'est vrai que par rapport au Kickstarter, on pourrait s'attendre à un enrichissement plus régulier (peut être 2 tutos par mois) et d'autre part, on peut se prendre des sujets et travailler dessus. On se forme et on aide les autres à se former. On est tous bons dans quelque chose et on progresser en cherchant et en se plantant et en s'aidant les uns les autres. C'est vrai que ça marche bien (c'est ce que j'ai fais aussi de mon côté) mais dans ce cas, c'est vrai aussi que l'on peut attendre de l'équipe d'Aurélien qu'elle participe plus dans les réponse ou sur leur capitalisation dans une base de connaissances dans l'Académie avec les problèmes les plus fréquents rencontrés et leur solutions, des tutos, des exemples, qui sait même pourquoi pas des collections de ressources libres faites par l'équipe ou les Gamebuinosiens. Voilà, c'est mon avis et ma réponse à ton coup de gueule  ;)  

Steph

NEW 5 years ago

Max Max

Max, je préfère te répondre en ouvrant une discussion plus large sur le sujet que tu évoques, qui sort du cadre de Sokoban vs POO et qui donc n'a rien à faire ici.

Ma réponse est ici.

chris-scientist

NEW 5 years ago

Max Max

@Max Content d'apprendre que tu aime le tutoriel ! Pour l'instant j'ai un projet qui est de concevoir un framework pour la META afin de réaliser des Sokoban-like... et je dois avouer que je ne suis plus vraiment actif sur ce sujet en ce moment (mais j'aimerai bien le finir)...

Codnpix

NEW 5 years ago

Bonjour, 

enfin arrivé au bout !

Merci beaucoup pour ce gros travail à travers lequel j'ai vraiment appris beaucoup de choses, des astuces algorithmiques et une belle occasion d'accumuler de la pratique en POO/MVC/C++.

Sur l'ensemble j'ai trouvé qu'il était parfois difficile de maîtriser vraiment le fil du raisonnement. J'ai finalement assez peu réussi à utiliser les guides en pseudo-code pour créer mon propre code. Mais au fil du tutoriel j'ai petit à petit réussi à faire les liens entre les choses et saisir l'intelligence du programme et c'était assez satisfaisant.

J'ai trouvé la première partie de conception très intéressante. Je pense qu'elle gagnerait peut-être à être un peu plus dévoilée. J'imagine qu'a priori tu es passé par des étapes préliminaires avant de pouvoir générer un diagramme de classes (ou alors c'est peut-être possible de l'imaginer directement avec l'expérience...), et je pense que ce serait également bénéfique de profiter du raisonnement de départ qui a permis d'architecturer l'ensemble du programme. Je crois que ça rendrait l'évolution dans la suite du tutoriel plus limpide.

Mais ce n'est qu'une petite critique secondaire. Dans l'ensemble j'ai vraiment beaucoup apprécié le tuto et j'ai appris plein de trucs donc super ;).

chris-scientist

5 years ago

Merci Codnpix pour ton retour.

Pour réaliser ce tutoriels j'ai d'abord écrit tout le code, puis alors j'ai fait le diagramme de classes à partir du code. J'ai utilisé ce support pour montrer une vue d'ensemble du code.

J'aurai pu faire un diagramme de classes dès le départ mais il aurait sûrement évoluer au fur et à mesure de l'avancé du projet.

jicehel

NEW 5 years ago

Codnpix merci pour lui pour le retour. C'et super important. Si tu peux essayes de proposer un bout de tuto à insérer ou pour en remplacer une partie, ça faciliterait le boulot de Chris pour voir s'il l'incorpore et ça permet d'avoir un retour sur ce qui est dur à comprendre (C'est toujours simple quand on sait faire.. ;) et je te rassure perso, j'ai beaucoup de mal pour le moment à réfléchir POO et ton approche / compléments pourront certainement m'être utile ainsi qu'à d'autres.)


Codnpix

5 years ago

Si tu peux essayes de proposer un bout de tuto à insérer ou pour en remplacer une partie

Je ne suis pas sûr de pouvoir prendre la responsabilité d'imaginer moi même le raisonnement qu'il y avait à la base de ce tutoriel là (je m'en suis fait mon idée, mais il reste quelques zones d'ombres)

Par contre je vais me mettre certainement à travailler très bientôt sur un projet de jeu plus personnel qui apriori sera programmé en POO et sur une base de MVC, et à ce moment là je rédigerai avec plaisir un tutoriel pour expliquer ce que j'aurai fait :).