Space Invaders est un jeu de tir spatial fixe en deux dimensions (2D). Le joueur contrôle un vaisseau spatial muni d'un canon laser qu'il peut déplacer horizontalement, au bas de l'écran. Dans les airs, des rangées d'aliens (ennemis) se déplacent latéralement tout en se rapprochant progressivement du sol et en lançant des missiles. L'objectif est de détruire avec le canon laser les vagues ennemies, qui se composent de cinq rangées de onze aliens chacune, avant qu'elles n'atteignent le bas de l'écran. Le joueur gagne des points à chaque fois qu'il détruit un envahisseur. Le jeu n'autorise qu'un tir à la fois et permet d'annuler ceux des ennemis en tirant dessus. La vitesse et la musique s'accélèrent au fur et à mesure que le nombre d'aliens diminue. L'élimination totale de ces derniers amène une nouvelle vague ennemie plus difficile, et ce indéfiniment. Le jeu ne se termine que lorsque le joueur perd, ce qui en fait le premier jeu sans fin. Les aliens tentent de détruire le canon en tirant dessus pendant qu'ils s'approchent du bas de l'écran. S'ils l'atteignent ou arrivent jusqu'au sol, ils ont réussi leur invasion et le jeu est fini. De temps en temps, un vaisseau spatial apparait tout en haut de l'écran et fait gagner des points bonus s'il est détruit. Quatre bâtiments destructibles permettent au joueur de se protéger des tirs ennemis. Ces défenses se désintègrent progressivement sous l'effet des projectiles adverses et de ceux du joueur. Le nombre de bâtiments n'est pas le même d'une version à l'autre.
Pour lancer le jeu, il suffit de télécharger le dépôt sur votre machine (en zip, il faut le déziper sinon en clonant
le repository), installer le jre 1.8 si ce n'est pas déjà fait. Enfin lancer le fichier launch.bat
.
- Semaine n°1 : du 23 au 27 février
- Semaine n°2 : du 30 février au 3 avril
- Semaine n°3 : du 6 au 10 avril
- Semaine n°4 : du 13 au 17 avril
- Semaine n°5 : du 20 au 24 avril
- Semaine n°6 : du 27 avril au 1er mai
- Glossaire
- Annexes
-
Story n°1.1 : Créer un espace de jeu.
Un espace de jeu est créé aux dimensions données (2D). Cet espace de jeu est vide. -
Story n°1.2 : Positionner un nouveau vaisseau dans l’espace de jeu.
Un nouveau vaisseau est créé. Le vaisseau est positionné aux coordonnées transmises. Si un nouveau vaisseau essaye d’être positionné en dehors des limites de l’espace jeu, alors une exception devra être levée. Contraintes : La position souhaitée est transmise par ses coordonnées x et y. Le coin supérieur gauche de l’espace jeu (point en haut à gauche) a pour coordonnées (0,0). La taille du vaisseau est réduite pour l'instant à son minimum (1 seul point). -
Story n°1.3 : Déplacer le vaisseau vers la droite dans l'espace de jeu.
Le vaisseau se déplace d'un pas vers la droite. Si le vaisseau se trouve sur la bordure droite de l'espace de jeu, le vaisseau doit rester immobile. -
Story n°1.4 : Déplacer le vaisseau vers la gauche dans l'espace de jeu.
Le vaisseau se déplace d'un pas vers la gauche. Si le vaisseau se trouve sur la bordure gauche de l'espace de jeu, le vaisseau doit rester immobile.
Aucune
(généré à l’aide de Source Code Word Cloud Generator avec la liste JavaBlacklist.txt tous les deux fournis par Isabelle Blasquez)
Aucune
Pour pouvoir, mettre en place les tests, il a été nécessaire d’ajouter une fonctionnalité supplémentaire qui permet de représenter l’espace de jeu dans une chaîne ASCII.
-
Story n°2.1 : Positionner un nouveau vaisseau avec une dimension donnée.
Un nouveau vaisseau est créé aux dimensions données (2D). Ce vaisseau est positionné aux coordonnées transmises. -
Story n°2.2 : Faire en sorte qu'il soit impossible de positionner un nouveau vaisseau qui déborde de l'espace de jeu.
Si un nouveau vaisseau essaye d’être positionné en dehors des limites de l’espace jeu, alors une exception est levée. Si une partie du vaisseau créé est en dehors des limites de l'espace de jeu, alors une exception est levée. Contraintes : La position souhaitée est transmise par ses coordonnées x et y. Le coin inférieur gauche du vaisseau correspond a l'origine du vaisseau. -
Story n°2.3 : Déplacer un vaisseau vers la droite en tenant compte de sa dimension.
Le vaisseau se déplace d'un pas vers la droite. Refactoring de la Story 1.3 en prenant en compte la largeur du vaisseau. Si le bord droit du vaisseau se trouve sur la bordure droite de l'espace de jeu, le vaisseau doit rester immobile. -
Story n°2.4 : Déplacer un vaisseau vers la droite en tenant compte de sa dimension.
Le vaisseau se déplace d'un pas vers la gauche. Refactoring de la Story 1.4 en prenant en compte la largeur du vaisseau. Si le bord gauche du vaisseau se trouve sur la bordure gauche de l'espace de jeu, le vaisseau doit rester immobile. -
Story n°2.5 : Refactoring.
Création des classesPosition
etDimension
. Implémentation de ces classes dans les classesSpaceInvaders
etVaisseau
.
-
Story n°3.1 : Comprendre ce qu'est la vitesse dans notre application et faire un choix de conception.
Ajout de la définition de la vitesse au glossaire. -
Story n°3.2 : Ajouter la
vitesse
auVaisseau
sans régression de comportement.
Implémentation d'un attributvitesse
dans la classeVaisseau
. Refactoring des méthodes de la classe pour implémenter la vitesse. -
Story n°3.3 : Régler la vitesse du vaisseau.
Création d'un nouveau constructeur en surcharge de la classeVaisseau
qui a la signature :Vaisseau(Dimension, Position, int)
. -
Story n°3.4 : Faire en sorte que le déplacement se fasse correctement pour une vitesse quelconque.
Refactoring de la méthodepositionnerUnNouveauVaisseau
de la classeSpaceInvaders
pour ajouter la vitesse à sa signature. refactoring de la classeSpaceInvadersTest
pour inclure la vitesse dans tous les tests. -
Story n°3.5 : Refactoring.
Refactoring de la méthodeinitialiserJeu
de la classeSpaceInvaders
. Implémentation de la constanteVAISSEAU_VITESSE
dans la classeConstante
Aucune
(généré à l’aide de Source Code Word Cloud Generator avec la liste JavaBlacklist.txt tous les deux fournis par Isabelle Blasquez)
Aucune
Pour pouvoir mettre en place le moteur graphique, il a été nécessaire d'implémenter une API dans notre code. Le moteur graphique se trouve dans le package fr.unilim.iut.spaceinvaders.moteurjeu
. On considère ce code comme élaboré en TDD.
-
Story n°4.1 : Comprendre ce qu'est un missile et refactorer.
Création d'une superclasseSprite
. Ajout des termes en lien avec le sprite au glossaire. Refactoring des classesVaisseau
etSprite
. -
Story n°4.2 : Comprendre ce que signifie tirer un missile depuis le vaisseau.
Analyse de la fonctionnalité grâce au diagramme de séquence disponible ici -
Story n°4.3 : Tirer un missile.
Un nouveau missile est créé.
Il se positionne au-dessus et centré par rapport au vaisseau.
Le joueur ne peut créer qu'un missile à la fois. Tant qu'il y en a un dans l'espace de jeu, il ne peut s'en créer de nouveau.
Le missile créé ne peut dépasser la largeur du vaisseau (simple logique) et il ne peut pas non plus dépasser la hauteur de l'espace de jeu, sinon une exception est levée.
Création d'une classe de testsVaisseauTest
. -
Story n°4.4 : Faire déplacer le missile à la verticale de manière autonome.
Création d'une énumérationDirection
permettant de réorganiser la disposition de l'espace de jeu.
Refactoring de la classe Sprite.
Refactoring de la méthodedeplacerMissile
afin qu'elle lève une exception si le missile touche le haut de l'espace de jeu.
-
Story n°5.1 : Créer un envahisseur.
Création de la classeEnvahisseur
qui hérite de la classeSprite
.
Ajout d'un attribut envahisseur à la classeSpaceInvaders
. -
Story n°5.2 : Positionner un nouvel envahisseur sur l'espace de jeu.
Un nouvel envahisseur est créé aux dimensions et a la position donnée.
S'il est positionné, complètement ou partiellement a l'exterieur de l'espace de jeu, une exception est levée.
Le coin inférieur gauche correspond a l'origine de l'envahisseur car c'est un sprite. -
Story n°5.3 : Déplacer le nouvel envahisseur sur l'espace de jeu (à droite et a gauche).
Comme pour le vaisseau, le vaisseau reste immobile s'il est au bord de l'espace de jeu (à droite et a gauche). -
Story n°5.4 : Faire en sorte que l'envahisseur fasse des aller-retours entre la droite et la gauche.
Implémentation d'une nouvelle méthodevoid deplacerEnvahisseur()
qui vérifie si l'envahisseur se trouve sur un bord ou pas et qui change sa direction si besoin.
Aucune
(généré à l’aide de Source Code Word Cloud Generator avec la liste JavaBlacklist.txt tous les deux fournis par Isabelle Blasquez)
Détection du missile en haut de l'espace de jeu à cause des axes inversés.
Refactoring de la classe DessinSpaceInvaders
pour ajouter le missile et ajout des constantes MISSILE_LONGUEUR
, MISSILE_HAUTEUR
et MISSILE_VITESSE
à la classe Constantes
.
Refactoring de la classe DessinSpaceInvaders
pour ajouter l'envahisseur et ajout des constantes ENVAHISSEUR_LONGUEUR
, ENVAHISSEUR_HAUTEUR
et ENVAHISSEUR_VITESSE
à la classe Constantes
.
-
Story n°6.1 : Comprendre ce qu'est une collision.
Création d'une classeCollision
avec une méthodedetecterCollision
.
Ajout du terme 'Collision' au glossaire.
Refactoring de la classeSpaceInvaders
. -
Story n°6.2 : Imaginer des situations à tester.
La collision peut s'effectuer par les 4 cotés car on considère les sprites comme des rectangles. -
Story n°6.3 : Comprendre ce que l'on considère comme une collision.
Création des différents tests dans la classe de testCollisionTest
à partir des exemples de la story 6.2:- collision par le bas
- collision par le haut
- collision par la droite
- collision par la gauche
-
Story n°6.4 : Implémentation des nouveautés au moteur graphique.
Ajout dans la méthodeevoluer()
d'une nouvelle condition pour vérifier les collisions.
-
Story n°7.1 : Réfléchir à ce l'on considère comme la fin de partie.
On considère ici que la partie est terminée lorsqu'un missile percute l'envahisseur.
Ajout du terme 'Fin de partie' au glossaire. -
Story n°7.2 : Tests Implémentations de tests pour vérifier la fin de la partie.
-
Story n°7.2 : Implémenter la fin de partie. Refactoring de la fin de partie dans la méthode
evoluer()
.
-
Story n°8.1 : Refactoring de la classe SpaceInvaders.
L'attributmissile
de la classeSpaceInvaders
devient donc une liste d'objets de la classeMissile
.
La classeDessinSpaceInvaders
implémente maintenant les changements du type.
Une méthodevoid supprimerMissilesHorsDeEspaceDeJeu()
est créée pour supprimer LES missiles hors de l'espace de jeu. -
Story n°8.2 : Tests.
Mise en place de tests pour vérifier que deux missiles ne se chevauchent pas. -
Story n°8.2 : Éviter que deux missiles se chevauchent.
Création d'une constanteTEMPS_ENTRE_DEUX_MISSILES
qui instaure un cooldown entre deux tirs.
Implémentation du cooldown dans la méthodevoid tirerUnMissileDepuisLeVaisseau(Dimension, int)
avec l'instructionSystem.currentTimeMillis()
qui mesure le cooldown.
Aucune
(généré à l’aide de Source Code Word Cloud Generator avec la liste JavaBlacklist.txt tous les deux fournis par Isabelle Blasquez)
Detection de la collision entre deux sprites par manque d'indications.
Implémentation de la Liste de missiles.
aucune.
-
Story n°9.1 : Déterminer ce qu'est une ligne d'envahisseurs.
Une ligne d'envahisseurs correspond a l'ajout sur l'axe horizontal d'envahisseurs identiques tous séparés par une distance correspondant à la moitié de la longueur de l'envahisseur original. -
Story n°9.2 : Tests.
Mise en place de tests qui prennent en compte la taille de la ligne d'envahisseurs.
Tests aux limites (gauche et droite).
Tests de demi-tour appliqué à la ligne et non a chaque envahisseur.
Test de collision pour la suppression que de l'envahisseur touché. -
Story n°9.3 : Ajout de contenu.
Transformation de l'attributenvahisseur
enenvahisseurs
de typeListe<Envahisseurs>
.
Ajout de la méthodepositionnerUneNouvelleLigneEnvahisseurs(Position, Envahisseur, int)
qui ajoute une ligne d'envahisseurs séparés par la moitié de la longueur d'un envahisseur.
Refactoring des méthodes des classesSpaceInvaders
etDessinSpaceInvaders
pour implémenter la liste d'envahisseurs. -
Story n°9.4 : Constantes Ajout des constantes
ENVAHISSEUR_POSITION_X
,ENVAHISSEUR_POSITION_Y
etENVHISSEUR_PARLIGNE
-
Story n°10.1 : Reflexion.
Le score est augmenté de 20 a chaque fois qu'un envahisseur est tué.
La valeur de 20 a été choisie pour avoir une marge plus grande pour choisir les points à attribuer au joueur quand il tirera sur les missiles ennemis ou autres. -
Story n°10.2 : Tests.
Ajout d'un test qui vérifie que le sore augmente bien de 20 quand un missile percute un ennemi. -
Story n°10.3 : Ajouts.
Ajout d'un attributscore
à la classeSpaceInvaders
qui est mis a 0 lors de la création du jeu. -
Story n°10.4 : Refactoring.
Révision de la classeDessinSpaceInvaders
pour ajouter l'affichage du score en haut à gauche.
-
Story n°11.1 : Reflexion.
Les missiles tirent aléatoirement donc il faut implémenter une valeur aléatoire.
Si un missile touche le vaisseau, la partie se termine.
Il faut donc penser que si on tue tous les envahisseurs, il ne faut pas gagner le jeu, mais rajouter des envahisseurs au jeu pour le rendre infini. -
Story n°11.2 : Tests.
Ajout de tests pour vérifier la position des missiles à leur création.
Ajout de tests pour vérifier le positionnement de la ligne d'envahisseurs à sa création car non fait à la fonctionnalité précédente. -
Story n°11.3 : Ajouts.
Ajout de 2 classes :MissileEnvahisseur
etMissileVaisseau
qui héritent toutes les deux de la classeMissile
. Ces 2 nouvelles classes sont indispensables à mon sens pour différencier les missiles afin que dans le futur quand on implémentera plusieurs lignes d'envahisseurs les envahisseurs ne se tirent pas les uns sur les autres.
On ajoute les méthodes nécessaires au tir de missiles depuis un ennemi dans la classeSpaceInvaders
.
On ajoute aussi à la classeDessinSpaceInvaders
une méthode pour dessiner les missiles ennemis d'une couleur différente des missiles alliés.
On modifie aussi les méthodes de la classePersonnage
pour introduire le tir des ennemis. -
Story n°11.4 : Refactoring.
Refactoring de la classeSpaceInvaders
pour simplifier les méthodes notamment la méthodeevoluer
dont on a extrait des méthodes.
Refactoring des classes de test pour être à jour avec les dernières modifications de refactoring pour ne plus utiliser la méthodeevoluer
.
Refactoring du glossaire pour correspondre aux fonctionnalités actuelles.
Aucune
(généré à l’aide de Source Code Word Cloud Generator avec la liste JavaBlacklist.txt tous les deux fournis par Isabelle Blasquez)
Aucune
Aucune
Modification de l'affichage des ennemis et du vaisseau pour qu'ils paraissent plus pixelisés.
Cette mise a jour est purement graphique et n'implémente pas de fonctionnalités.
Elle corrige quand même une petite erreur de codage qui faisait faire demi-tour à la ligne d'envahisseurs dans certaines
conditions.
Fonctionnalité n°12 : Les ennemis apparaissent a l'infini et descendent dans l'espace de jeu (:white_check_mark:)
-
Story n°12.1 : Reflexion.
Les envahisseurs se déplacent de gauche à droite. Il faut donc détecter un aller-retour sur 2 afin de faire baisser la ligne d'envahisseurs.
Il est décidé arbitrairement que a chaque fois que la ligne descend, elle descend de la hauteur d'un envahisseur. -
Story n°12.2 : Tests.
Plusieurs tests sont mis en place tout d'abord pour être a jour sur les tests nécessaires à la collision entre un missile du vaisseau et un envahisseur mais aussi entre deux missiles.
De plus, un test pour vérifier que le vaisseau descend de sa hauteur lorsqu'il a effectué un aller-retour. -
Story n°12.3 : Ajouts.
Ajout d'un attributdistanceParcourue
à la classeSpaceinvaders
.
Ajout des méthodesdeplacerEnvahisseursApresAllerRetour()
etdetecterCollisionMissileMissile()
pour coïncider avec les nouveaux tests.
Ajout de getter et setter au nouvel attribut. -
Story n°12.4 : Refactoring.
Refactoring des méthodesevoluer()
etdeplacerEnvahisseurs()
pour simplifier les méthodes et ajouter la descente des envahisseurs ainsi que l'apparition infinie de lignes d'envahisseurs.
Aucune
(généré à l’aide de Source Code Word Cloud Generator avec la liste JavaBlacklist.txt tous les deux fournis par Isabelle Blasquez)
Aucune
Aucune
-
Vaisseau : Véhicule commandé par le joueur, pouvant se déplacer de droite à gauche et ayant la possibilité de lancer des missiles destinés à détruire le(s) envahisseurs.
-
Envahisseur : Ennemi qui apparaît à l'écran, se déplace automatiquement de droite à gauche et qui doit être détruit par un missile lancé depuis le vaisseau du joueur. Il tire des missiles aléatoirement. Une fois qu'il a effectué un aller-retour, il descend d'un cran et continue son déplacement.
-
Missile : Projectile envoyé à la verticale par le vaisseau vers l'envahisseur dans le but de le détruire. Mais aussi depuis un envahisseur verticalement vers le bas de l'ecran dans le but de détruire le vaisseau.
-
Immobile : Aucun déplacement, aucune exception levée : le sprite reste juste à sa position actuelle.
-
Vitesse : Grandeur physique associée aux différents sprites. Elle correspond à la distance parcourue au cours d'un déplacement.
-
Personnage : Être fictif et virtuel, contrôlé ou non par le joueur, qui apparaît dans un jeu vidéo.
-
Sprite : Élément graphique qui peut se déplacer sur l'ecran. Identifie les personnages et les objets qui se superposent au fond d'ecran et qui se déplacent.
-
Collision : Une collision est détectée lorsqu'un sprite est placé à la meme place su'un autre sprite.
-
Fin de partie : La fin de partie correspond à la collision entre un missile de l'envahisseur et le vaisseau.
-
Cooldown : Terme correspondant au temps minimal entre deux actions.
-
❌ : Fonctionnalité non ou partiellement implémentée.
-
✅ : Fonctionnalité implémentée complètement.
Créé par Jean Laurent en première année de DUT Informatique à Limoges pendant l'année universitaire 2019-2020. Projet proposé par Isabelle Blasquez.