CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[Java] Début d'un petit jeu

Chnapy
Chnapy
Niveau 10
29 mars 2014 à 15:36:04

Hellow :)

Je suis en plein dans l'apprentissage de Java et j'ai commencé à faire un petit jeu 2D histoire de m'entrainer.

Pour le moment le jeu se présente ainsi :
La map est sous forme de grille, et le héros se déplace sur cette grille. Et... c'est tout pour le moment :-d
Une image vaut mieux que des mots : https://image.noelshack.com/fichiers/2014/13/1396103012-testjeuscreen.png
Sur cette image, le cercle rouge est le héros, les tiles (= carrés) bleus sont traversables, les tiles gris ne sont pas traversables.
Le joueur se déplace avec ZQSD en suivant le modèle de la grille (4 directions).

Bref, si je vous présente tout ça c'est parce que j'aimerai votre avis sur le code du jeu, si je pars pas dans une mauvaise direction :question:
C'est le premier programme que je fais avec JavaFX, je connais encore trop peu le framework.

J'ai fait un petit diagramme de classe : https://image.noelshack.com/fichiers/2014/13/1396103297-diaclasse.png

Pour ceux qui ont la flemme de dl/compiler les .java,
Vous pouvez "tester" le jeu ici : http://www.survivordie.url.ph/TestJeu.html (nécessite une version de Java JRE à jour)
Télécharger le .jar ici : http://www.survivordie.url.ph/TestJeu/TestJeu.jar

Les fichiers sources (.java) : https://www.dropbox.com/s/tyfwcmfu37xof3a/TestJeuSources.rar
Je pense avoir bien commenté.

Merci d'avance pour vos avis :)

Chnapy
Chnapy
Niveau 10
29 mars 2014 à 21:27:56

J'ai modifié mon code ainsi que mon diagramme.
Les liens restent bon, sauf pour le diagramme : https://image.noelshack.com/fichiers/2014/13/1396124702-diaclasse.png et pour les fichiers sources : https://www.dropbox.com/s/s/q3ue9fbrhbrh08f/testjeu.rar

J'aimerai avoir vos avis :-)

vive_cod4
vive_cod4
Niveau 9
30 mars 2014 à 00:22:55

Je sais pas si c'est le rendu du logiciel pour ton diagramme de classes ou si c'est toi, mais je rêve ou je vois de l'héritage dans tout les sens ? (je me réfère à UML 2.0)

Bon en dépit de ça, tu devrais mettre des associations-aggrégation-composition avec des cardinalités et navigabilité entre tes objets, car c'est vraiment pas visible de juste écrire le type d'une variable s'il s'agit d'une classe que tu as crées.

Ensuite dans les classes "à droites", tout le monde a un attribut héros et map. On arrive avec ça au point suivant, qu'il faudrait, à mon humble avis bien séparer ta conception en classe entité, controller et interface. Enfin bon, il n'existe pas qu'une solution.

Je pense que je vais m'arrêter à ce niveau pour l'instant, rien qu'avec ma première remarque ça sera déjà plus visible. Sinon en vrac :

tiles : TILESIZE static je suppose ? C'est souligné et oublie pas le public
Classe Personnage, classe abstraite ? -> Nom en italique. En passant elle est un peu useless ta classe personnage. Faudrait déporter une partie des méthodes de Heros dedans. Après c'est bizarre d'avoir des attributs rect, circ etc dans ta classe personnage, c'est quoi, ta forme de collision ? Dans ce cas rond (joueur ?) tu le mets dans le heros par exemple. J'arrête là.

Je pense que ça vaudrait la peine que tu vois quelques diagrammes de classes (la théorie aussi) pour te donner des idées, surtout si tu en trouves pour des petits jeux :) ça te donnera une idée de comment font les autres. Je peux t'en refourguer quelques un concernant des jeux si tu trouves pas.

Je suis sûr que d'autres personnes te donneront des remarques plus approfondies sur ton architecture qu'avec mon coup d'oeil "superficiel"

Chnapy
Chnapy
Niveau 10
30 mars 2014 à 12:57:16

Merci pour tous ces conseil :)

Pour le diagramme j'ai vu que brièvement en cours comment en faire, les flèches ne sont là que pour indiquer les relations entre chaque classe.
"tu devrais mettre des associations-aggrégation-composition avec des cardinalités et navigabilité entre tes objets"
Je comprends pas tous ces mots compliqués :rouge:

Pour les attributs héros et map, ce sont ceux créés dans la classe Jeu qui sont passés en arguments lors de la création des objets. "il faudrait, à mon humble avis bien séparer ta conception en classe entité, controller et interface." Je comprends pas non plus :-(
J'utilise TILESIZE comme une constante, via un final static int.
Pour rect et circ ce sont juste ce que l'on voit du personnage à l'écran. Dans le cas du héros c'est un cercle, dans celui des ennemis c'est un carré. La collision est gérée dans la classe Collision via un objet de type BoundingBox.

D'ailleurs je viens de remarquer que mon diagramme est incomplet, il manque entre autre la classe Ennemi :honte:
Pas étonnant qu'il soit aussi peu compréhensible.

Je veux bien voir des exemples de diagramme de classe si ça ne te gêne pas, les quelques un que je trouve sur le net représente d'autres langages ou sont vraiment complexes.

Je vais arranger mon diagramme et me renseigner sur ces nouveaux termes :-d

Chnapy
Chnapy
Niveau 10
30 mars 2014 à 13:36:22

Hum dans mon diagramme je suis pas sûr de savoir quel type de flèche utiliser pour indiquer une relation entre 2 classes (pour dire, la classe A utilise la classe B).
C'est bien "Dépendances" ?

J'utilise Dia comme logiciel.

vive_cod4
vive_cod4
Niveau 9
30 mars 2014 à 13:42:06

Justement, les relations entre les classes se font avec des associations-aggrégation-compositions :) La ce que tu as fait c'est de l'héritage partout (certaines flèches ont du sens comme héros et personnage).

Sinon en effet, ta classe ennemi est manquante.

Je pense bien que ton TILESIZE est static final, mais c'est pas ce que je vois dans ton diagramme de classe.

Pour finir, le but d'UML est de proposer des schémas indépendant du language d'implémentation. Donc ton diagramme de classe doit être facilement compréhensible par qqun qui ne fait pas de Java. Typiquement ceux que je peux te passer sont 1 C++ et 1 Java, mais tu es censé comprendre les 2.

Je t'enverrais le plus simple un peu plus tard

vive_cod4
vive_cod4
Niveau 9
30 mars 2014 à 13:43:39

je viens de trouver ça https://www.lri.fr/~longuet/Enseignements/12-13/Inge3-UML/Inge3-DiagClasses.pdf sur les diagrammes de classes, ça devrait te donner une base

vive_cod4
vive_cod4
Niveau 9
30 mars 2014 à 13:46:43

Une dépendance c'est une relation faible dans le sens que tu dis que ta classe A va utiliser la classe B à un certain moment et tu n'aurais pas d'objet de la classe B comme attribut mais seulement soit dans un paramètre d'une fonction ou dans une variable locale

Chnapy
Chnapy
Niveau 10
30 mars 2014 à 14:53:50

Encore merci pour tous ces conseils :-)

Alors j'ai suivi tout ce que tu m'as dis + le lien.
Ça donne ça : https://image.noelshack.com/fichiers/2014/13/1396183229-diaclasse.png
Pour ce qui est des classes je pense n'avoir rien oublié. Par contre pour les relations j'ai préféré me contenté des agrégations, pour le moment.
Je me suis dis, lorsque dans une classe j'ai ça (en gros) :

public class ClasseA {
ClasseB nomClasse = new ClasseB();
}

Ça donne une relation d'agrégation. Ensuite, pour savoir si c'est une agrégation faible ou une composition j'ai pris exemple sur l'exemple donné par le pdf (pièce-mur-brique).

J'ai pas osé mettre les associations. A vrai dire je ne sais pas vraiment quand est-ce qu'il faut les appliquer.
Par exemple, si j'appelle une fonction de la classe Grille depuis la classe Jeu, je présume que je dois associer les deux classes.
Mais si j'appelle une méthode de la classe Vue avec en argument un objet de type Grille, je devrai associer Grille et Vue ? Si c'est le cas ça va vite devenir illisible :-(

Enfin, je comprends pas vraiment ce qu'est qu'une "interface". D'après le pdf ça semble être une classe qui partage ses fonctions :question:

vive_cod4
vive_cod4
Niveau 9
30 mars 2014 à 20:27:36

public class ClasseA {
ClasseB nomClasse = new ClasseB();
}

ça donne une association unidirectionnel (voir classeB si bidirectionnel).

On va rester simple pour commencer. Ne met que des associations (ligne normal) et précise la navigabilité.Une aggrégation-composition ne s'utilise pas pour du 1-1. Après pour le 1-n ça dépend de la relation, donc reste que du association pour le moment.

Ensuite je vois toujours des objets de classe dans des attributs comme dans Clavier. Il faudrait pour cette classe faire une association entre Clavier et Grille et Clavier Heros (indépendamment du sens de la conception).

Je prends la classe personnage. Pourquoi as-tu un attribut Grille ? Lorsque tu bouges, tu mets à jour la position de ton personnage et tu notifies ta classe Jeu qui va le déplacer.

Ensuite, tu as un attribut circ et rect.Avant du m'a dit que circ c'est joueur et rec ennemi (ou l'inverse mais on s'en fout). Pourquoi ne pas faire un attribut shape de type Shape par exemple et de le définir comme cercle dans héro et rect dans ennmi (circ EST un Shape).

Après je vois afficherHeros, afficherEnnemi. Pourquoi ne pas en faire une méthode abstraite et forcer la redéfinition de cette méthode ? (but de l'abtrait). Est-ce que tes ennemis bougent ? Je vois movX, movY mais que des méthodes move dans hero. Normal ? Si non, tu déplaces ces méthodes dans la classe Personnage.

TestJeu n'a qu'une dépendance vers Jeu je suppose, en tout cas pas une relation 1 - 1..* (à moins que c'est normal dans ton cas).

Ta classe Jeu c'est la classe qui gère le gros morceau. Pourquoi dans la classe Clavier (qui gère les I/O) tu as un attribut Grille et Heros ? Tu devrais notifier la classe Jeu qu'une touche a été appuyé (et dire laquelle) puis c'est la classe Jeu qui va bouger ton personnage. Une raison particulière de ton attribut clavier en protected ? (même remarque qu'avant, faut virer l'attribut mais laisser une association (je le dis pas à chaque fois, mais pense-y))

Pour ta classe vue, il te faudrait une relation 1 - * avec les ennemis, je ne la vois pas (j'ai laissé association pour faire simple)

Ta grille, pourquoi relation 1* - 1* avec classe Jeu ? A mon humbe avis, la grille est en relation avec la Vue.

Voici un premier passage. Tu as remarqué que je n'ai rien dit sur Collision car tout dépend de comment tu le fais mais je n'ai pas fait de jeu avec des Tiles dont préfère ne pas me prononcer.

Après le défi des diagrammes de classes, c'est de le rendre lisible. Donc faudra sûrement réorganiser la disposition de tes classes. Tu peux aussi tracer les relations à la "souris" pour rendre plus beau. Tu comprendras d'ici peu quand je t'enverrai par MP.

Une interface, ça sert à combler le "problème" des héritages multiples à mon sens. Dis toi que c'est une classe non instantiable, qui ne possède que des prototypes de méthodes. Quand tu implémentes une ou plusieurs interfaces à la fois, tu dois implémenter toutes les méthodes définies. Une interface joue aussi le rôle de "l'héritage" dans le sens que si ta classe A implémente l'interface I, alors A est un I.

BeslSmasher
BeslSmasher
Niveau 10
31 mars 2014 à 19:28:42

Sympa le site qui place pas directement l'applet Java, mais qui cherche à détecter si t'as Java activé ou pas. C'est con, parce qu'avec IcedTea sur Linux je peux pas accéder au jeu :(

Chnapy
Chnapy
Niveau 10
31 mars 2014 à 21:18:53

BeslSmasher => J'ai pas testé sur Linux, dommage que ça marche pas, je vais me renseigner pour arranger ça ! Tu peux accéder directement au .jar sur ce lien : http://survivordie.url.ph/TestJeu/TestJeu.jar

Alors pour le diagramme j'en suis à la : https://image.noelshack.com/fichiers/2014/14/1396293434-diaclasse.png
Je suis vraiment pas sûr de ce que j'ai fait. J'ai essayé suivre scrupuleusement tes conseils :)

J'en ai profité pour alléger le code en virant des trucs inutile. Notamment dans Vue où map, heros, pnj sont passés en arguments lors de l'appel des méthodes au lieu de les mettre dans le constructeur.
Pour Clavier map ne sert à rien en fait. J'ai retiré les méthodes moveHeros() et stopHeros() pour les inclure directement dans le constructeur, ce qui donne ceci :

public Clavier(final Heros heros) {

// Evenement : touche pressée
this.setOnKeyPressed(new EventHandler<KeyEvent>(){
@Override
public void handle(KeyEvent ke){
heros.moveHeros(ke.getText().toUpperCase().charAt(
0));

}
});

// Evenement : touche relachée
this.setOnKeyReleased(new EventHandler<KeyEvent>(){
@Override
public void handle(KeyEvent ke){
heros.stopHeros(ke.getText().toUpperCase().charAt(
0));

}
});
}

La classe Ennemi est vide pour le moment, je la remplierai plus tard :)

"Je prends la classe personnage. Pourquoi as-tu un attribut Grille ?"
:d) On peut s'en passer en effet :-)))

"Pourquoi ne pas faire un attribut shape de type Shape par exemple"
:d) Je connaissais pas, c'est pratique en effet :-) Par contre pour régler la taille (width/height ou radius) je suis obligé de convertir en rectangle/cercle, comme ça : ((Rectangle)forme).setWidth(width);
Ça gène en rien l'exécution du programme, mais je me demande s'il y a pas "plus propre".

"Après je vois afficherHeros, afficherEnnemi. Pourquoi ne pas en faire une méthode abstraite et forcer la redéfinition de cette méthode ?"
:d) Je vois pas trop comment faire, j'ai jamais fait de méthode abstraite :rouge: mais je vais me renseigner.
"Est-ce que tes ennemis bougent ? Je vois movX, movY mais que des méthodes move dans hero. Normal ?"
:d) Je vais en mettre dans Ennemi, mais elles seront différentes de celle de Heros.

"TestJeu n'a qu'une dépendance vers Jeu je suppose, en tout cas pas une relation 1 - 1..* (à moins que c'est normal dans ton cas)."
:d) Erreur :rouge:

"Pourquoi dans la classe Clavier (qui gère les I/O) tu as un attribut Grille et Heros ?"
:d) Corrigé :)

"Une raison particulière de ton attribut clavier en protected ?"
:d) Dans TestJeu (la classe main) pour garder le focus j'utilise : partieTest.clavier.requestFocus(); ce qui nécessite de mettre protected ou d'utiliser un getter. Je devrais utiliser un getter ?

Actuellement Collision n'est utilisé que par Personnage (ainsi que ses enfants). Je compte utiliser le même système pour Tile (pour le moment il ne possède que l'attribut) plus tard.
Collision représente la Hitbox (via la BoundingBox) des personnages. Il permet également de détecter les collisions avec d'autre Collision ou encore avec une ArrayList de Personnage.
Avec les Tiles ce sera plutôt simple étant donné leur absence de mouvement. Je leur appliquerait un objet Collision possédant une position et une taille égale à celles du Tile.
L'attribut solid du Tile déterminera si le joueur peut traverser ou non le tile.

J'ai remplacé l'ArrayList d'ennemis par une ArrayList de pnj (= Personnage). Pour le moment j'ai que des ennemis comme personnages non joueurs, mais si dans l'avenir je compte rajouter une classe (Amis ?) ça sera plus pratique je pense.

Le diagramme perd en lisibilité déjà, ça me fait peur sachant que le programme est encore à un stade primaire :peur:
D'ailleurs je me demande si le programme que j'utilise (Dia) est bon. Ce qui m'agace particulièrement c'est lorsque je veux placer plusieurs associations sur le même coté d'une classe (exemple : Heros > Personnage et Ennemi > Personnage) il me place les flèches au même endroit ... Obligé de la jouer manuellement.

J'ai vu les interfaces ce matin en cours :rire2:
J'avoue ne pas avoir trouvé une réelle utilité, hormis se rajouter des contrainte. Je sais qu'il y en a (sinon pourquoi ça existerait ...) mais je vois pas :(

Encore merci pour ton aide en tout cas, j'apprécie beaucoup ! :-)))

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment