IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

Collision javafx jeux


Sujet :

JavaFX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Lycéen(seconde)
    Inscrit en
    Octobre 2018
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen(seconde)

    Informations forums :
    Inscription : Octobre 2018
    Messages : 32
    Par défaut Collision javafx / Binding
    Bonjour,

    J'ai commencé mon jeux en javafx et je suis en ce moment entrain de créer les collisions 2D, le personnage qui peut se déplacer étant un cercle, j'ai décidé de créer un carré invisible autour du cercle, j'ai décidé de relier grâce au binding les 4 cotés du carré au cercle pour faire en sorte que quand le joueur déplace le cercle qui est le personnage, que le carré reste autour du cercle. Puis après je vais créer des conditions Shapes, si le coté en haut du carré touche un mur, ... . J'aimerais que vous m'aidiez pour le binding car je ne sais pas comment faire, j'ai regardé des tutos mais je n'y arrive pas. Merci de bien vouloir m'aider.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par nanny33 Voir le message
    Bonjour,

    J'ai commencé mon jeux en javafx et je suis en ce moment entrain de créer les collisions 2D, le personnage qui peut se déplacer étant un cercle, j'ai décidé de créer un carré invisible autour du cercle,
    Mais ça existe déjà... tous les nœuds disposent d'une boite englobante qui fait déjà ça : getBoundsInLocal() ou getBoundsInParent(). Sans parler du fait bien sur que les formes géométriques disposent également de méthodes pour tester les intersections et l'appartenance : intersects() et contains().

    j'ai décidé de relier grâce au binding les 4 cotés du carré au cercle pour faire en sorte que quand le joueur déplace le cercle qui est le personnage, que le carré reste autour du cercle.
    Ca sert a rien, voir plus haut. Les valeurs de la boite englobante sont automatiquement mises a jour.

    Puis après je vais créer des conditions Shapes, si le coté en haut du carré touche un mur, ... . J'aimerais que vous m'aidiez pour le binding car je ne sais pas comment faire, j'ai regardé des tutos mais je n'y arrive pas. Merci de bien vouloir m'aider.
    Après si, dans ton jeu, tu veux afficher un carre autour (par exemple si tu passes en mode debug/developpeur) la oui le binding peut aider mais c'est pas oblige tu peux aussi effectuer son positionnement a la main. Sinon un truc du genre devrait faire l'affaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    circleBox.widthProperty.bind(Bindings.mult(circle.radiusProperty(), 2));
    circleBox.heightProperty.bind(circleBox.widthProperty());
    circleBox.layoutXProperty().bind(circle.layoutXProperty());
    circleBox.layoutYProperty().bind(circle.layoutYProperty());
    // Ou
    circleBox.layoutXProperty().bind(Bindings.subtract(circle.centerXProperty(), circle.RadiusProperty());
    circleBox.layoutYProperty().bind(Bindings.subtract(circle.centerYProperty(), circle.RadiusProperty());
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre averti
    Homme Profil pro
    Lycéen(seconde)
    Inscrit en
    Octobre 2018
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen(seconde)

    Informations forums :
    Inscription : Octobre 2018
    Messages : 32
    Par défaut
    D'accord, merci pour votre réponse, comment faire pour les collisions sans utiliser le binding comme vous l'avez dit auparavant? Et pour le binding, je comprend le code mais je ne vois pas ce que c'est circleBox , pour le circle, je le remplacerai donc pour le nom que j'ai donné cercle qui s'appelle c ?

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Tu as 2 soucis distinct :
    • Connaître la boite englobante du cercle. getBoundsInLocal() ou getBoundsInParent().
    • Pour des besoins de débogage visuel afficher un carre autour du cercles. circleBox est un carre qui s'affiche autour du cercle.


    Quand au calcul de collision, voir par exemple ici : Checking Collision of Shapes with JavaFX sur StackOverflow.

    Comme indiqué a la fin de la réponse de jewelsea, pour un vrai jeu qui serait base sur le concept de la bouche de jeu (faisable en JavaFX avec un AnimationTimer), c'est plus efficace de tester les collisions durant chaque boucle du timer plutôt que lorsqu'un sprite se déplace.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Membre averti
    Homme Profil pro
    Lycéen(seconde)
    Inscrit en
    Octobre 2018
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen(seconde)

    Informations forums :
    Inscription : Octobre 2018
    Messages : 32
    Par défaut
    D'accord merci, je vais essayer de regarder ceci en détail

  6. #6
    Membre averti
    Homme Profil pro
    Lycéen(seconde)
    Inscrit en
    Octobre 2018
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen(seconde)

    Informations forums :
    Inscription : Octobre 2018
    Messages : 32
    Par défaut
    Je n'est pas trés bien compris le principe car je ne connais pas vraiment les arraylist ..., pouvais vous me faire un exemple de code de collision stp en expliquant si vous pouvais bien sur . mr

  7. #7
    Membre averti
    Homme Profil pro
    Lycéen(seconde)
    Inscrit en
    Octobre 2018
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen(seconde)

    Informations forums :
    Inscription : Octobre 2018
    Messages : 32
    Par défaut Collision javafx jeux
    Bonjour, j'ai 16 ans et je suis entrant de faire un jeux complet un système de magasin de skins ..., il me reste plus que les collisions à mettre et le jeux est fini, dans mon jeux, des Circle ennemies rebondissent sur les murs et le personnage principal est un Circle plus petit, le but étant de rester le plus longtemps en vie sans toucher les ennemies cercles, pourvez vous m'aider svp mr.

  8. #8
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Tu as déjà posé exactement la même question il y a 3 mois . Allez hop, fusion !
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  9. #9
    Membre averti
    Homme Profil pro
    Lycéen(seconde)
    Inscrit en
    Octobre 2018
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen(seconde)

    Informations forums :
    Inscription : Octobre 2018
    Messages : 32
    Par défaut
    Bonjour,
    dans mon jeux, il y a un Cercle c qui est le personnage principal qui se déplace avec les touches du clavier, j'ai crée un Group CircleBox qui contient touts les cercles ennemies qui rebondissent sur les murs et que le joueur doit esquiver, il manque les collision entre le group et le cercle si il y a, j'ai trouvé comment faire pour les collisions entre 2 cercles et j'ai trouvé ceci : (je sais pas ce qu'il faut mettre à la place des C1.rayon .. (rappel : C1 et C2 sont deux cercle testé par la collision, dans mon jeux, ca sera le cercle c et les ennemies CircleBox)) pouvez vous me dire svp* *:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int d2 = (C1.x-C2.x)*(C1.x-C2.x) + (C1.y-C2.y)*(C1.y-C2.y);
      if (d2 > (C1.rayon + C2.rayon)*(C1.rayon + C2.rayon))
        System.out.println("Collision");
      else
         System.out.println("Pas collision");
    }

  10. #10
    Membre averti
    Homme Profil pro
    Lycéen(seconde)
    Inscrit en
    Octobre 2018
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen(seconde)

    Informations forums :
    Inscription : Octobre 2018
    Messages : 32
    Par défaut
    J'ai fais ceci mais dans la console, il y a toujours écrit"collision" même quand il n'y a pas collision :



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //Collision :
     
    //Balle 1 : ennemie
    double d2 = (c.getLayoutX()-balle1.getLayoutX())*(c.getLayoutX()-balle1.getLayoutX()) + (c.getLayoutY()-balle1.getLayoutY())*(c.getLayoutY()-balle1.getLayoutY());
     
    if (d2 > (c.getRadius() + balle1.getRadius())*(c.getRadius() + balle1.getRadius()))
        System.out.println("Collision");
    else
        System.out.println("Pas collision");

  11. #11
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Bon alors une petite démo vaut peut-être mieux qu'un long discour. Attention cependant, pour faire court cette démo repose sur plusieurs principes que tu ne maîtrise peut-être pas encore complètement :

    • Le code est au format JDK 9-12, je rappelle que pour les JDK les plus anciens, il suffit de remplacer le mot-clé var par le type approprié.
    • La méthode stream() n'existe pas sur la classe Optional dans le JDK8, le code a utiliser devrait être :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      Optional.ofNullable(Main.class.getResource("styles.css"))
          .ifPresent(url -> scene.getStylesheets().add(url.toExternalForm()));
      et pour le JDK7 c'est carrement la classe Optional qui n'existe pas, donc le code devient :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      final URL url = Main.class.getResource("styles.css");
      if (url != null) {
          scene.getStylesheets().add(url.toExternalForm());
      }
    • L'utilisation d'une feuille de style externe (CSS) histoire de mettre hors du code tout ce qui est décoration graphique, couleur de remplissage, de bordure, épaisseur du trait, etc.
    • L'utilisation d'une pseudo classe qui permet de changer rapidement le style des formes.
    • J'ai aussi affiché 2 rectangles qui représentent les boites englobantes de chaque cercles. Pour faciliter la lecture du code je les ai bindé sur les boites englobantes des cercles dans le repère de leur parent.
    • Une TranslateTransition sert a animer le cercle c1 qui va passer sur le cercle c2. Cette animation change uniquement les valeurs de translateX et translateY et donc elle ne touche jamais layoutX, layoutY, centerX ou centerY (c'est important pour la suite, ca veut dire qu'en fait on ne peut pas se reposer sur ces valeurs pour les tests de collision).
    • Un AnimationTimer pour tester les collisions a 60FPS, ce calcul a donc lieu tous les 1/60eme de seconde :
      • Comme dit juste au-dessus a cause de notre transition, on ne peut pas vraiment se fier aux valeurs layoutX, layoutY, centerX ou centerY de c1 donc on va utiliser boundInParent qui est la boite englobante dans le parent lorsque toutes les transformations ont été appliquées).
      • Notre premier test vérifie sur les boites englobantes de c1 et c2 s'intersectent. Si c'est le cas on remplira le rectangle autour de c1 en orange.
      • Notre second test est plus précis : on va vérifier si la distance entre les centre des boites englobantes de c1 et c2 est inférieure a la somme de leurs rayons. Si c'est le cas on laisse le rectangle autour de c1 vide mais on remplira c1 en rouge. Pour la même raison (notre transition modifie d'autres valeurs), on ne teste pas le centre de c1 et c2 mais le centre de la boite englobante dans le parent lorsque toutes les transformations ont été appliquées.

        Note : ce test ici suppose que c1 et c2 n'ont pas subi de transformation qui ont change leur forme donc je peux utiliser le rayon tel quel (getRadius). Si des transformations modifiant la forme ont lieu (ex: mise a l’échelle, déformation, etc.) le calcul devient plus complexe et il faut bien sur tenir compte de ces déformations si on veut des calculs de collision plus juste.



    styles.css
    Code CSS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    .c1 {
        -fx-fill: null;
        -fx-fill: null;
        -fx-stroke: red;
        -fx-stroke-width: 1px;
    }
    .c1:collision {
        -fx-fill: red;
    }
    .c2 {
        -fx-fill: null;
        -fx-stroke: blue;
        -fx-stroke-width: 1px;
    }
    .bounds1 {
        -fx-fill: null;
        -fx-stroke: darkorange;
        -fx-stroke-width: 1px;
        -fx-stroke-dash-array: 5 5;
    }
    .bounds1:collision {
        -fx-fill: darkorange;
    }
    .bounds2 {
        -fx-fill: null;
        -fx-stroke: darkcyan;
        -fx-stroke-width: 1px;
        -fx-stroke-dash-array: 5 5;
    }

    Main.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    package collisions;
     
    import javafx.animation.AnimationTimer;
    import javafx.animation.Interpolator;
    import javafx.animation.TranslateTransition;
    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.css.PseudoClass;
    import javafx.geometry.Point2D;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.util.Duration;
     
    import java.net.URL;
    import java.util.Optional;
     
    public final class Main extends Application {
     
        private static final PseudoClass COLLISION_PSEUDO_CLASS = PseudoClass.getPseudoClass("collision");
     
        @Override
        public void start(final Stage stage) throws Exception {
            // Les cercles.
            final var c1 = new Circle(20, 20, 15);
            c1.getStyleClass().add("c1");
            final var c2 = new Circle(250, 250, 50);
            c2.getStyleClass().add("c2");
            // Les boites englobantes des cercles.
            final var bounds1 = new Rectangle();
            bounds1.getStyleClass().add("bounds1");
            bounds1.xProperty().bind(Bindings.selectDouble(c1.boundsInParentProperty(), "minX"));
            bounds1.yProperty().bind(Bindings.selectDouble(c1.boundsInParentProperty(), "minY"));
            bounds1.widthProperty().bind(Bindings.selectDouble(c1.boundsInParentProperty(), "width"));
            bounds1.heightProperty().bind(Bindings.selectDouble(c1.boundsInParentProperty(), "height"));
            final var bounds2 = new Rectangle();
            bounds2.getStyleClass().add("bounds2");
            bounds2.xProperty().bind(Bindings.selectDouble(c2.boundsInParentProperty(), "minX"));
            bounds2.yProperty().bind(Bindings.selectDouble(c2.boundsInParentProperty(), "minY"));
            bounds2.widthProperty().bind(Bindings.selectDouble(c2.boundsInParentProperty(), "width"));
            bounds2.heightProperty().bind(Bindings.selectDouble(c2.boundsInParentProperty(), "height"));
            // Montage de l'UI.
            final var root = new Pane();
            root.getChildren().addAll(bounds1, bounds2);
            root.getChildren().addAll(c1, c2);
            final var scene = new Scene(root, 500, 500);
            Optional.ofNullable(Main.class.getResource("styles.css"))
                    .stream()
                    .map(URL::toExternalForm)
                    .forEach(scene.getStylesheets()::add);
            stage.setScene(scene);
            stage.setResizable(false);
            stage.show();
            // Collision.
            final var worldClock = new AnimationTimer() {
     
                @Override
                public void handle(long l) {
                    final var b1 = c1.getBoundsInParent();
                    final var b2 = c2.getBoundsInParent();
                    boolean colorBound = false;
                    boolean colorShape = false;
                    if (b1.intersects(b2)) {
                        colorBound = true;
                        final var center1 = new Point2D(b1.getCenterX(), b1.getCenterY());
                        final double distance = center1.distance(b2.getCenterX(), b2.getCenterY());
                        if (distance < c1.getRadius() + c2.getRadius()) {
                            colorBound = false;
                            colorShape = true;
                        }
                    }
                    bounds1.pseudoClassStateChanged(COLLISION_PSEUDO_CLASS, colorBound);
                    c1.pseudoClassStateChanged(COLLISION_PSEUDO_CLASS, colorShape);
                }
            };
            worldClock.start();
            // Animation.
            final var animation = new TranslateTransition(Duration.seconds(10), c1);
            animation.setInterpolator(Interpolator.LINEAR);
            animation.setCycleCount(TranslateTransition.INDEFINITE);
            animation.setAutoReverse(true);
            animation.setToX(500 - 2 * 15 - 20);
            animation.setToY(500 - 2 * 15 - 20);
            animation.play();
        }
    }
    La leçon a retenir ici est qu'il te faut faire extrêmement attention a comment tu vas positionner, faire bouger ou animer et surtout transformer tes objets a l’écran. Un bon calcul de collision doit tenir compte de ces transformations pour être précis. CEPENDANT, si les transformations sont trop complexes, le calcul peut devenir impossible ou trop coûteux en temps CPU donc rester sur une base simplifiée (ex: les boites englobantes) peut mener a un calcul rapide et peu coûteux mais moins précis.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

Discussions similaires

  1. [Flash] jeux flash: formules de collision 2d
    Par flasheur dans le forum Contribuez
    Réponses: 0
    Dernier message: 10/02/2011, 15h04
  2. [Sources] formules de collision 2d pour les jeux flash
    Par flasheur dans le forum Contribuez
    Réponses: 0
    Dernier message: 10/02/2011, 13h41
  3. [Jeux] Gestion des collisions et des déplacements
    Par Psycadi dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 05/07/2010, 10h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo