Tetris LIF13 Printemps 2014 SAAKYAN Aram, FAURE Adrien

Transcription

Tetris LIF13 Printemps 2014 SAAKYAN Aram, FAURE Adrien
Tetris
LIF13 Printemps 2014
SAAKYAN Aram, FAURE Adrien
Table des matières
1 Présentation du projet
1.1 Description . . . . . . .
1.2 Objectifs . . . . . . . . .
1.3 Choix de développement
1.4 Difficultés rencontrées .
1.5 Liste des fonctionnalités
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
2
2
3
3
2 Diagrammes UML
2.1 Diagramme de classe du modèle . . .
2.2 Diagramme de séquence d’une partie
2.3 Diagramme de cas d’utilisation . . .
2.4 Diagramme de séquence . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
5
5
6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3 Conclusion
.
.
.
.
.
.
.
.
.
.
7
1
Chapitre 1
Présentation du projet
1.1
Description
En 1985 Alexey Pazhitnov, s’inspira du casse-tête appelé pentomino pour
inventer le célèbre Tetris. Notre projet reprend les fondamentaux de ce jeu, tout
en ajoutant quelques features modernes. Le jeu consiste à diriger une pièce (aussi
appelée tetromino) en mouvement constant vers le bas dans une grille de jeu.
Le tetromino peut être tourné (à 90°) ou déplacé (à gauche ou à droite) par
le joueur. Le but du jeu étant de remplir des lignes de la grille en posant les
tetrominos, afin d’augmenter son score. Le jeu s’arrête si on ne peut plus insérer
de pièce en haut de la grille.
1.2
Objectifs
Le projet nous demandait de réaliser un tetris en Langage Java, respectant le
modèle Objet et implémentant le design-pattern MVC (Model-View-Controler).
1.3
Choix de développement
Afin de respecter au mieux le modèle objet, nos classes sont des héritages
de classe directement fournis par java.util, par exemple nos pieces sont des extends de LinkedList, notre vue est un extends de JFrame, ainsi nous manipulons
directement nos classes selon le modèle objet.
Le but du jeu est de remplir des lignes pour les supprimer et augmenter
son score, nous avons donc pensé à un moyen de mettre à jour la grille de jeu
facilement. Ainsi celle-ci est implementé par une liste de lignes. Ce choix nous
permet de faire, avec peu de calcul une mise à jour, et de plus uniquement quand
c’est nécessaire.
Plusieurs améliorations ont été apporté au tetris, afin d’améliorer la durée de
vie et le plaisir de jeu. Ces améliorations ont été choisi parmi les features les
plus célèbres de tetris, notamment le ghost, l’affichage de la pièce suivante, ainsi
que la possibilité de verrouiller une pièce pour la réutiliser plus tard.
2
1.4
Difficultés rencontrées
La plus grande difficulté de ce projet, a été la structuration MVC de la façon
la plus générique possible. En effet, même si java propose beaucoup de solutions,
notamment la mise en place facile du pattern Observable/Observer utilisé entre
le modèle et la vue. Ainsi que l’interface Listener permettant au contrôleur de
s’enregistrer au près de la vue. Malheureusement, malgré ces solutions, la vue
et le/les contrôleur(s) ne sont pas totalement indépendants. Même si le modèle,
quand à lui, est une entité souveraine.
Les rotations avec des pièces ayant une coordonnée en [x=0] présentaient une
source d’erreur. Pour palier à ce problème, la largeur de la grille a été agrandi de
un et toutes les lignes sont remplies en [x=0] mais ne sont pas affichées. Ainsi les
rotations sont possibles de partout sur la grille. Le mode torus, a été implémenté
en surchargeant quelques fonctions (notament les fonctions de collisions et de
déplacements) malheureusement, ce mode rend les calculs de rotations beaucoup
plus difficile. Le projet à donc été avorté, même si il est possible de l’activer en
modifiant le code.
1.5
Liste des fonctionnalités
– Possibilité de lancer la partie et de mettre le jeu en pause.
– Utilisation des touches directionnelles pour deplacer la pièce à droite et à
gauche.
– Touche directionnelle bas pour accélérer la vitesse de la pièce courante.
– Touche directionnelle haut pour faire une rotation de la pièce à 90° dans
le sens des aiguilles d’une montre.
– Touche espace pour poser la pièce courante.
– Affichage d’un fantome qui renseigne l’emplacement de la pièce si on la
laisse tomber (peut être enlevé dans le menu).
– Affichage d’aucune à trois pièces suivantes (option à définir dans le menu).
– Animation de fin quand la partie est finie.
– Augmentation de la vitesse de jeu à mesure que le joueur complète des
lignes (cf : niveau de jeu).
– Possibilité de consulter son score dans la partie, de plus le score augmente
plus fortement selon le nombre de lignes complétées d’un seul coup et le
niveau actuel.
– Possibilité de sauvegarder la pièce courante (case hold en haut à gauche)
et de la ressortir à un meilleur moment en utilisant la touche entrée.
3
Chapitre 2
Diagrammes UML
2.1
Diagramme de classe du modèle
Voici le diagramme de classe de notre modèle, il représente la partie la plus
indépendante de notre projet. La classe principale Jeu, est la classe maîtresse qui
met en relation chacunes des instances nécessaires et les manipule afin de gérer
les collisions entre la grille et la pièce courante, les calcules de score, et met à
jour les lignes pleines si nécessaire. Il est également capable d’envoyer différentes
notifications grâce à l’héritage Observable, et possède sa propre fonction run()
executable dans un thread grâce au type de l’interface Runnable.
Diagramme de classe du model
Model
<<interface>>
Runnable
LinkedList<Point>
<<abstract>>
Thread
Observable
1
Piece
+Piece(t:Forme,p:Point)
+construirePiece(p:Point): void
+rotationPiece(): void
+getNextPosRotation(): LinkedList<Point>
+deplacer(m:Mouvement): void
+getPosition(): LinkedList<Point>
+getNextPosition(m:Mouvement): LinkedList<Point>
+getNextPosPiece(m:Mouvement): Piece
<<enumeration>>
Forme
-id: int
-couleur: Color
+getRandom(): Forme
<<enumeration>>
Mouvement
Grille
Jeu
$ COS_: double
$ SIN_: double
-center: Point
-forme: Forme
1,n
-refresh: boolean
-HAUTEUR: int
-LARGEUR: int
-score: int
-intLevel: int
-hold: int
-nombresLignesCompletees: int
-play: boolean
-pause: boolean
-accelerer: boolean
-swap: boolean
-fluidite: boolean
1
+Jeu()
+lancerPartie(): void
+nouvellePartie(): void
+run(): void
+pieceCouranteNew(): boolean
+tenirPiece(): void
+vitesse(): void
+vitesse (x:int): void
+resume(): void
+pause(): void
+poserPiece(): void
+ViderLignePleine(): int
+ajouterPieceCouranteGrille(): void
+<<synchronized>> deplacerCourante(m:Mouvement): boolean
+<<synchronized>> tournerCourante(): boolean
+fonctionScore(x:int): void
+getThread(): Thread
+getGrilleLargeur(): int
+getGrilleHauteur(): int
+getGrille(): Grille
+getFormeCourante(): Forme
+getPosCourante(): LinkedList<Point>
+getPieceCourante(): Piece
+getPieceHold(): Piece
+getPause(): boolean
+getScore(): int
+<<synchronized>> setPause(b:boolean): void
+getListeSuivante(): LinkedList<Piece>
+getPlay(): boolean
+setPlay(b:boolean): void
+setAcceleration(b:boolean): void
4
+Grille(largeur:int,hauteur:int)
+clearLigne(): int
+ifPositionValide(p:Point): boolean
+ifPositionValide(list:LinkedList<Point>): boolean
+setCAse(p:Piece): void
+getLargeur(): int
+getHauteur(): int
+getCase(): Case
+getLigne(): Ligne
+ifRefresh(): boolean
1,n
Ligne
-tailleMax: int
-nbElements: int
-pleine: boolean
+Ligne(Tm:int)
+add(e:Case,x:int): boolean
+estPleine(): boolean
1,n
Case
-neant: boolean
-couleur: Color
+Case()
+Case(b:boolean)
+Case(b:boolean,f:Color)
+getNeant(): boolean
+getColor(): Color
ArrayList
2.2
Diagramme de séquence d’une partie
Le diagramme d’activités complet du jeu.
[au moin une migne est pleine]
Animation Fin
vider ligne pleine
placer piece courante
Fin Partie
[else]
reinitialisation partie
[nouvelle position valide]
[else]
appliquer position basse
[else]
[temps+]
[Position valide]
Lancer partie
[else]
Placer piece position courante
recuperer piece suivante
calculer positon basse
ne rien faire
[action clavier]
tester validité position
[deja fait avec cette piece]
[else]
[aucune piece sauvegardé]
[espace]
[entrée]
poser piece
appliquer bas
[droite/gauche]
[rotation]
[else]
[position valide]
calculer
deplacer droite/gauche
demander prochaine position
recuper piece sauvegarder
sauvergarde piece
[ok]
[!ok]
appliquer mouvement
ne rien faire
positioner haut grille
2.3
Diagramme de cas d’utilisation
Voici la liste de fonctionnalités sous forme d’un diagramme d’utilisation.
Fonctionnalités
Consulter Score/Niveau
Lancer Partie
Afficher Aide
Tenir pièce
regarde
bouton
menu
changer le nombre de pièces suivantes à afficher
action clavier
menu
action clavier
Joueur
Déplacer pièce
action clavier
Poser Pièce
action clavier
bouton
menu
Tourner pièce
Mettre/Enlever pause
afficher/enlever fantôme
5
2.4
Diagramme de séquence
Voici un diagramme de séquence de l’action poser pièce. Nous avons choisi
ce diagramme afin de montrer l’architecture MVC. En effet, on remarque que
le joueur grâce à un contrôleur de type KeyControler influe sur le model (ici
le Jeu). Le jeu quand à lui, applique les actions commandées par le contrôleur
et notifie la vue que des changements ont eu lieu. Celle-ci se met à jour pour
informer le joueur.
Diagramme de séquence pour l’action poser pièce.
:KeyControler
PieceCourante:Piece
:Jeu
:vueSwing
:Grille
Joueur
Touche Espace
poserPiece()
while(mouvement possible)
deplacerCourante(Mouvement.Bas)
notification
ajouterPieceCouranteGrille()
retour visuel()
notification
retour visuel()
pieceCouranteNew()
notification
retour visuel()
6
PieceCourante : Piece
Chapitre 3
Conclusion
Nous aurions voulu apporter plusieurs modifications sur ce projet, et nous
pensions avoir encore quelques temps après la présentation voilà pourquoi nous
tenions à vous informer des modifications qui auraient été apportées.
– Fonction de sauvegarde rapide, c’est à dire reprendre l’état d’une grille au
moment où le joueur aurait sauvegardé de façon dynamique afin d’augmenter
son score au plus haut dans une même partie.
– Utilisation de fichier xml pour sauvegarder une configuration ( touche
préférée du joueur ). Ainsi qu’un tableau des scores.
– Ajout de pièce bonus, par exemple des pièces qui explosent, des pièces
aimantés, une pièce space-invader qui peut tirer sur la grille afin de faire
la place et d’augmenter le score.
– Ajout d’un fond sonore.
Si nous avions eu plus de temps, il aurait été intérressant grâce à une utilisation
plus poussée du multithreading de faire un mode affrontement où deux joueurs
doivent faire des lignes le plus vite possible, de plus si un joueur fait une ligne
des cases aléatoires apparraissent chez l’adversaire.
7