Processing - Problèmes de hitbox
Répondre à la discussion
Affichage des résultats 1 à 14 sur 14

Processing - Problèmes de hitbox



  1. #1
    invite70e74265

    Processing - Problèmes de hitbox


    ------

    Bonjour,

    Je travaille actuellement sur un projet avec un ami pour notre bac d'ISN, notre but est de créer un programme sous Processing permettant de se déplacer en vue à la première personne dans un environnement fermé que mon camarade a créé.

    Pour ma part, je dois m'occuper des collisions, la caméra ne doit pas pouvoir traverser les murs, le problème c'est que je ne trouve pas comment m'y prendre! La caméra est gérée par la bibliothèque Queasycam, donc pour ceux qui ne connaissent pas, elle gère toute la partie vue FPS et déplacement. J'ai beau chercher je ne vois vraiment pas comment faire pour que la caméra se heurte aux murs au lieu de les traverser.

    Je cherche également à la "bloquer" en hauteur, c'est-à-dire l'empêcher de monter ou de descendre, comme il y aurait dans n'importe quel jeu en vue première personne.

    Nous travaillons évidemment en 3D, l'environnement est plus ou moins terminé (ce n'est plus qu'une histoire de textures maintenant). Les murs ont été créés à l'aide de la commande vertex, si ça peut aider.

    Merci d'avance pour vos réponses!

    -----

  2. #2
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Citation Envoyé par Edahel Voir le message
    La caméra est gérée par la bibliothèque Queasycam, donc pour ceux qui ne connaissent pas, elle gère toute la partie vue FPS et déplacement. J'ai beau chercher je ne vois vraiment pas comment faire pour que la caméra se heurte aux murs au lieu de les traverser.
    Je viens d'aller jeter un oeil à Queasycam.
    Les sources sont ici : https://github.com/jrc03c/queasycam
    (Aller voir dans /src/template/QueasyCam.java pour le détail de la classe Queasycam)

    Si je ne m'abuse, le joueur (éventuellement, si elle a été employée, la classe Player) et la caméra (la classe Queasycam) sont deux entités séparées.
    Il n'y a pas de lien entre ces deux entités, et même aucune nécéssité de faire appel à une classe Player.

    Bien sûr, et c'est probablement ce que vous avez fait (et je me place dans ce cas de figure pour vous répondre) vous pouvez assimiler la caméra au joueur, ce qui fait que vous n'avez pas besoin d'afficher le joueur (et qui fait que vous ne pourrez pas éventuellement créer de vue plus tard à la 3eme personne, mais ce n'est pas un problème si vous n'en avez pas besoin).

    Déplacer la caméra revient donc à déplacer le joueur (.position).
    Tourner la caméra revient donc à tourner le joueur (autour de l'axe vertical y (.pan) et autour de l'axe horizontal z (.tilt)).
    A noter que la caméra doit être positionnée à l'endroit où doivent se trouver les yeux du joueur.

    A noter également, que si vous voulez gérer le déplacement et la rotation de la caméra en employant le code inclus dans la classe Queasycam, vous devez spécifier .controllable=true (ce qui vous oblige à employer les touches a,d,w,s pour les déplacements et q,e pour la variation de la vitesse de déplacement).

    Donc, pour empêcher le "joueur-caméra" d'entrer en collision avec son environnement, il faut déjà définir la forme du joueur.
    De plus, il ne faut bien comprendre que la caméra, à la base, n'a pas d'épaisseur (ou quasiment mais c'est du détail)...
    Tout ce qui se trouve devant le plan du point de vue de la caméra est affichable (peut apparaitre sur l'écran, mais pas nécessairement), et tout ce qui se trouve derrière ce plan, n'est pas affichable (n'apparaitra jamais sur l'écran, bien que ce sera dessiné pour rien par la carte graphique, comme tout le reste qui ne rentre pas dans le cadre du point de vue),
    Donc si vous vérifiez simplement si la position de la caméra se trouve dans un "objet" (une forme définie par vos vertexs), vous allez avoir un problème :
    * Vous allez pouvoir placer les yeux du joueur (la position de la caméra) juste devant l'obstacle, mais si vous tournez ensuite le point de vue, le rectangle de vue peut intersecter la forme/obstacle (l'objet), ce qui vous permettra de voir à travers la forme....

    Donc pour éviter ça, vous devez définir une "zone de sécurité", plus large que le rectangle de votre point de vue, et devez tester la collision de cette forme avec les objets de l'environnement.
    Le rectangle de point de vue (la zone qui s'affiche sur l'écran) doit toujours être incluse dans la forme du joueur, quelle que soit la valeur de .pan et de .tilt.

    Le meilleur choix pour cette forme (rectangle, ellipse ou cylindre) dépend bien entendu de la forme de vos obstacles.

    Je cherche également à la "bloquer" en hauteur, c'est-à-dire l'empêcher de monter ou de descendre, comme il y aurait dans n'importe quel jeu en vue première personne.
    Je ne suis pas très sûr de comprendre.
    Empêcher la caméra de tomber à travers le sol ?
    Normalement, si aucun déplacement n'est commandé, la caméra n'est pas censée bouger.
    De base, la classe Queasycam est prévue pour faire avancer la caméra dans la direction du point de vue, mais ne gère pas sa chute en fonction de la gravité.

    A la limite, pour faire super simple, s'il n'est pas prévu de descendre dans des trous, de sauter ou de monter sur des objets (des caisses par exemple), vous pouvez corriger la position .position.y de la caméra à chaque tour.
    (Comme ça, vous pouvez regarder vers le bas, avancer vers cette direction, mais le joueur-camera ira moins vite s'il regarde vers le bas ou vers le haut)

    Les murs ont été créés à l'aide de la commande vertex, si ça peut aider.
    D'accord, mais ça ne donne pas la forme des objet du paysage.
    Il faut connaitre les formes des objets du paysage pour tester la collision avec la forme du joueur, sinon vous devez tester la collision de tous les vertex avec la forme du joueur-caméra à chaque tour (60 fois pas secondes en général...), ce qui peut éventuellement ralentir le jeu.

  3. #3
    invite70e74265

    Re : Processing - Problèmes de hitbox

    Bonjour, et déjà merci pour votre aide!

    Bien sûr, et c'est probablement ce que vous avez fait (et je me place dans ce cas de figure pour vous répondre) vous pouvez assimiler la caméra au joueur
    Effectivement, la caméra est considérée comme étant le joueur, mais je n'ai pas très bien compris, doit-on effectuer une commande spéciale pour que le programme lui-même le sache? Ou est-ce qu'on peut s'en passer?

    A noter également, que si vous voulez gérer le déplacement et la rotation de la caméra en employant le code inclus dans la classe Queasycam, vous devez spécifier .controllable=true (ce qui vous oblige à employer les touches a,d,w,s pour les déplacements et q,e pour la variation de la vitesse de déplacement).
    Je n'ai pas eu besoin d'utiliser cette commande, cela fonctionnait déjà auparavant. Je viens de tester avec et sans cam.controllable=true;, il n'y a aucune différence. De toute façon ce n'est pas ici qu'est mon problème, donc tant que ça marche, je vais pas me plaindre! x)

    Donc, pour empêcher le "joueur-caméra" d'entrer en collision avec son environnement, il faut déjà définir la forme du joueur. [...] Donc pour éviter ça, vous devez définir une "zone de sécurité", plus large que le rectangle de votre point de vue, et devez tester la collision de cette forme avec les objets de l'environnement. [...] vous pouvez corriger la position .position.y de la caméra à chaque tour.
    Très bien, c'est en effet ce que je cherchais à faire! Mais comment fait-on tout cela? C'est bien là mon problème!

    Je ne suis pas très sûr de comprendre.
    Empêcher la caméra de tomber à travers le sol ?
    Normalement, si aucun déplacement n'est commandé, la caméra n'est pas censée bouger.
    De base, la classe Queasycam est prévue pour faire avancer la caméra dans la direction du point de vue, mais ne gère pas sa chute en fonction de la gravité.
    La caméra ne tombe pas, mais elle se déplace en fonction de l'angle dans lequel on regarde. C'est à dire que si, avec la souris, on pointe le ciel et on avance, la caméra va s'envoler. Idem si on pointe par terre, la caméra va s'enfoncer dans le sol. C'est pourquoi j'aimerai la bloquer à une hauteur définie, pour qu'elle ne puisse pas se déplacer sur l'axe y (vertical donc), mais seulement sur les axes x et z. Evidemment, je veux quand même conserver la rotation autour de y, afin de pouvoir tourner la vue. Mais j'ai vu que vous aviez compris tout de même.

    D'accord, mais ça ne donne pas la forme des objet du paysage.
    Il faut connaitre les formes des objets du paysage pour tester la collision avec la forme du joueur, sinon vous devez tester la collision de tous les vertex avec la forme du joueur-caméra à chaque tour (60 fois pas secondes en général...), ce qui peut éventuellement ralentir le jeu.
    Ce sont des rectangles, plusieurs rectangles, mais ce qui me fait peur, c'est que le programme n'est pas censé savoir que c'en sont, étant donné qu'ils ont été créés par des enchainements de vertex.



    En tout cas, merci pour votre temps, j'espère ne pas trop déranger ^^" Je ne suis pas un dieu de la programmation, loin de là, donc c'est assez compliqué de comprendre comment faire certaines choses sans explications précises, j'ai compris ce que vous avez dit mais j'ai du mal justement à trouver comment réaliser ce que vous proposez.

  4. #4
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Citation Envoyé par Edahel Voir le message
    Effectivement, la caméra est considérée comme étant le joueur, mais je n'ai pas très bien compris, doit-on effectuer une commande spéciale pour que le programme lui-même le sache? Ou est-ce qu'on peut s'en passer?
    Il n'y a rien à faire de plus, puisque c'est vous-même qui avez choisi d'employer la caméra comme s'il s'agissait du joueur.

    Je n'ai pas eu besoin d'utiliser cette commande, cela fonctionnait déjà auparavant. Je viens de tester avec et sans cam.controllable=true;, il n'y a aucune différence. De toute façon ce n'est pas ici qu'est mon problème, donc tant que ça marche, je vais pas me plaindre! x)
    A méditer...
    C'est ce que j'en avais conclu en jetant un oeil au source de Queasycam.java :
    (J'ai mi en gras là où la souris et le clavier interviennent sur les propriétés de l'objet Queasycam)
    Code:
    public void draw(){
            if (!controllable) return;
            
            mouse = MouseInfo.getPointerInfo().getLocation();
            if (prevMouse == null) prevMouse = new Point(mouse.x, mouse.y);
            
            int w = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
            int h = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height;
            
            if (mouse.x < 1 && (mouse.x - prevMouse.x) < 0){
                robot.mouseMove(w-2, mouse.y);
                mouse.x = w-2;
                prevMouse.x = w-2;
            }
                    
            if (mouse.x > w-2 && (mouse.x - prevMouse.x) > 0){
                robot.mouseMove(2, mouse.y);
                mouse.x = 2;
                prevMouse.x = 2;
            }
            
            if (mouse.y < 1 && (mouse.y - prevMouse.y) < 0){
                robot.mouseMove(mouse.x, h-2);
                mouse.y = h-2;
                prevMouse.y = h-2;
            }
            
            if (mouse.y > h-1 && (mouse.y - prevMouse.y) > 0){
                robot.mouseMove(mouse.x, 2);
                mouse.y = 2;
                prevMouse.y = 2;
            }
            
            pan += PApplet.map(mouse.x - prevMouse.x, 0, applet.width, 0, PConstants.TWO_PI) * sensitivity;
            tilt += PApplet.map(mouse.y - prevMouse.y, 0, applet.height, 0, PConstants.PI) * sensitivity;
            tilt = clamp(tilt, -PConstants.PI/2.01f, PConstants.PI/2.01f);
            
            if (tilt == PConstants.PI/2) tilt += 0.001f;
    
            forward = new PVector(PApplet.cos(pan), PApplet.tan(tilt), PApplet.sin(pan));
            forward.normalize();
            right = new PVector(PApplet.cos(pan - PConstants.PI/2), 0, PApplet.sin(pan - PConstants.PI/2));
            
            target = PVector.add(position, forward);
            
            prevMouse = new Point(mouse.x, mouse.y);
            
            if (keys.containsKey('a') && keys.get('a')) velocity.add(PVector.mult(right, speed));
            if (keys.containsKey('d') && keys.get('d')) velocity.sub(PVector.mult(right, speed));
            if (keys.containsKey('w') && keys.get('w')) velocity.add(PVector.mult(forward, speed));
            if (keys.containsKey('s') && keys.get('s')) velocity.sub(PVector.mult(forward, speed));
            if (keys.containsKey('q') && keys.get('q')) velocity.add(PVector.mult(up, speed));
            if (keys.containsKey('e') && keys.get('e')) velocity.sub(PVector.mult(up, speed));
    
            velocity.mult(friction);
            position.add(velocity);
            center = PVector.add(position, forward);
            applet.camera(position.x, position.y, position.z, center.x, center.y, center.z, up.x, up.y, up.z);
        }
    Mais on peut laisser ça de côté (il y a peut-être quelque-chose qui m'échappe)

  5. A voir en vidéo sur Futura
  6. #5
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    On va commencer par régler ce problème (avant les collisions).
    Citation Envoyé par Edahel
    La caméra ne tombe pas, mais elle se déplace en fonction de l'angle dans lequel on regarde. C'est à dire que si, avec la souris, on pointe le ciel et on avance, la caméra va s'envoler. Idem si on pointe par terre, la caméra va s'enfoncer dans le sol. C'est pourquoi j'aimerai la bloquer à une hauteur définie, pour qu'elle ne puisse pas se déplacer sur l'axe y (vertical donc), mais seulement sur les axes x et z. Evidemment, je veux quand même conserver la rotation autour de y, afin de pouvoir tourner la vue. Mais j'ai vu que vous aviez compris tout de même.
    C'est un peu embêtant cette affaire...
    Si vous me dites que .controllable ne fonctionne pas, quelles sont les touches employées pour le déplacement ?
    (Juste pour essayer de comprendre)

    Sinon, il suffirait de changer le code java pour, soit "redresser" le vecteur velocity (en lui appliquant une rotation égale à - .pan, soit en mettant la valeur de velocity.y à 0 (cette deuxième option fera que si on regarde vers le bas ou vers le haut le joueur se déplacera moins vite).

    Ceci d'après le code suivant :
    Code:
    position.add(velocity);
    center = PVector.add(position, forward);
    applet.camera(position.x, position.y, position.z, center.x, center.y, center.z, up.x, up.y, up.z)
    Une manière plus propre de procéder serait de distinguer la caméra du joueur.
    Et dans ce cas, controllable=false doit au préalable fonctionner.

  7. #6
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Pour avancer quand même sur la question des collisions entre les "vertex" et le joueur.
    La première chose est de créer un rectangle qui défini la zone d'occupation du joueur.

    1 rectangle = 8 points (qu'on note ici Pn)

    Soit donc les quatre points du bas P1,P2,P3,P4, P1 étant le point gauche/arrière P2 le point gauche/avant, p3 le point droite/avant, p4 le point droite/arrière.
    Et de la même manière, les quatre points du haut P5,P6,P7,P8 (P5 se trouvant au dessus de P1, P6 au dessus de P2, etc)

    Pour définir la position de ces points, une méthode simple :
    On a le vecteur direction (normalisé) avant Va, le vecteur haut (normalisé) Vh, le vecteur gauche (normalisé) Vg.
    On a la position centrée du rectangle (Pc), qui correspond à la position en coordonnées Monde (c'est de cette manière que
    vous avez défini les coordonnées (et ça se discute, ça pourrait être la position (0.0.0)...))
    H est la hauteur du rectangle, L la largeur du rectangle, E l'épaisseur du rectangle.

    P1 vaut Pc + (-Va*E + Vg*L -Vh*H) * 0.5
    P2 vaut Pc + ( Va*E + Vg*L -Vh*H) * 0.5
    P3 vaut Pc + ( Va*E - Vg*L -Vh*H) * 0.5
    P4 vaut Pc + (-Va*E - Vg*L -Vh*H) * 0.5

    P5 vaut Pc + (-Va*E + Vg*L +Vh*H) * 0.5
    P6 vaut Pc + ( Va*E + Vg*L +Vh*H) * 0.5
    P7 vaut Pc + ( Va*E - Vg*L +Vh*H) * 0.5
    P8 vaut Pc + (-Va*E - Vg*L +Vh*H) * 0.5

    A noter que Vg peut être déduit du vecteur directionnel de la caméra, mais Va et Vh ne sont pas le vecteur avant et le vecteur haut de la caméra.
    Vh vaut (1,0,0), puisque le rectangle du joueur a sa base positionnée à plat, et Va peut être déduit du vecteur directionnel de la caméra (noté ici Vc), en admettant que y et z sont sur les axes à plat (sinon corriger).

    Va = Normalise (0, vc.y, vc.z), en admettant que x est sur l'axe correspondant à la hauteur, y et z sur les axes à plat (si ce n'est pas le cas, il suffit de corriger, l'indice à 0 dans la formule doit correspondre à la hauteur)

  8. #7
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Maintenant, pour savoir si un vertex intersecte le rectangle du joueur après déplacement.
    1 vertex = 3 points (qu'on note ici An).

    On examine les droites (A1-A2), (A2-A3), (A3-A1).

    Pour chacune de ces droites (3 tests), on détermine le point d'intersection avec successivement tous les plans (6 tests) du rectangle (il vaut mieux pré calculer ces plans avant de vérifier les intersections avec tous les vertex).
    Si une droite coupe un plan, on obtient la coordonnée sur le plan (qui ne se trouve pas nécéssairement sur la face du rectangle, puisque le plan s'étend à l'infini)
    On vérifie donc que cette coordonnée se trouve dans ou sur le rectangle (pour ce faire, on peut vérifier que ce point se trouve à gauche ou à droite des plans des faces opposés pris deux à deux, par exemple gauche/droite, avant/arrière, haut/bas.)
    Si suite à ce test la coordonnée est dans (sur en fait, mais c'est pareil) le rectangle du joueur, on vérifie que cette coordonnée se trouve entre les positions des sommets du vertex (les sommets qui ont défini la droite testée du vertex, par exemple A1 et A2), en calculant les deux distance entre le point d'intersection et les deux sommets (si une des distances est supérieure à la distance A1-A2, alors le point ne se situe pas entre les deux sommets).

    Si je ne me suis pas trompé, ça devrait faire l'affaire.
    Reste à programmer la fonction qui détermine le point d'intersection d'une droite avec un plan et la fonction qui détermine si un point se trouve dans un rectangle (entre 6 faces deux à deux).

  9. #8
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Et pour compléter, inutile de vérifier les intersections si le joueur ne se déplace pas.
    Par contre, si le joueur tourne, il faut également faire le test (et il pourrait buter sur les vertex en tournant).

    Si on avait défini un ellipsoïde 3D pour la forme du joueur, on n'aurait pas besoin de tester en cas de rotation et peut-être les tests pourraient être simplifiés.
    Il faut, selon le même principe que pour la forme rectangulaire du joueur, déterminer le ou les points d'intersection des 3 droites du vertex avec la sphère déformée (ellipsoïde) et vérifier que ce point se trouve entre les sommets du vertex.

    C'est plus simple mais ça peut avoir des conséquences, par exemple si on doit tester la chute du joueur (la base du joueur est ici, un point), à voir donc quelle forme on veut pour la "zone d'occupation" du joueur.

  10. #9
    invite70e74265

    Re : Processing - Problèmes de hitbox

    Ouh la la, c'est compliqué... J'ai honte mais j'y comprends pas grand chose.

    Si vous me dites que .controllable ne fonctionne pas, quelles sont les touches employées pour le déplacement ?
    Les touches sont WASD, mais je met toujours mon clavier en querty pour utiliser le programme afin d'utiliser les touches ZQSD et améliorer le confort. La commande controllable ne change rien, mais ce n'est pas un problème étant donné que le déplacement fonctionne correctement de toute façon.

    Sinon, il suffirait de changer le code java pour, soit "redresser" le vecteur velocity (en lui appliquant une rotation égale à - .pan, soit en mettant la valeur de velocity.y à 0 (cette deuxième option fera que si on regarde vers le bas ou vers le haut le joueur se déplacera moins vite).
    Je ne comprends pas trop, je n'ai pas envie d'influencer la vitesse de déplacement mais je veux plutôt empêcher la caméra de s'envoler ou s'enfoncer dans le sol. J'ai essayé votre code, mais ça ne fonctionne pas, le programme ne se lance même pas et affiche juste des erreurs concernant velocity.

    Une manière plus propre de procéder serait de distinguer la caméra du joueur.
    Et dans ce cas, controllable=false doit au préalable fonctionner.
    J'ai tenté d'utiliser cam.controllable=false, comme son nom l'indique je ne peux plus rien contrôler, la caméra ne se déplace plus. Ensuite, notre projet est de faire un jeu à la première personne, on ne veut pas qu'il soit à la troisième personne.

    On a la position centrée du rectangle (Pc), qui correspond à la position en coordonnées Monde (c'est de cette manière que
    vous avez défini les coordonnées (et ça se discute, ça pourrait être la position (0.0.0)...))
    Et qu'est-ce qu'une coordonnée Monde? Et je ne vois pas de quelles coordonnées que j'aurai apparemment définies vous parlez. A quoi correspondent-elles?

    P1 vaut Pc + (-Va*E + Vg*L -Vh*H) * 0.5
    P2 vaut Pc + ( Va*E + Vg*L -Vh*H) * 0.5
    P3 vaut Pc + ( Va*E - Vg*L -Vh*H) * 0.5
    P4 vaut Pc + (-Va*E - Vg*L -Vh*H) * 0.5 etc.
    Je ne comprends pas, qu'est-ce que Pc (un rectangle? Alors qu'est-ce que ça vaut?), à quoi correspondent concrètement les vecteurs normalisés (Va, Vh, Vg), pourquoi parfois +, pourquoi parfois -, et pourquoi *0.5?
    Je sais pas si c'est moi qui est nul, mais j'y comprends rien Et ça ne m'aide absolument pas à voir ce que je dois faire niveau programmation.

    A noter que Vg peut être déduit du vecteur directionnel de la caméra, mais Va et Vh ne sont pas le vecteur avant et le vecteur haut de la caméra.
    Vh vaut (1,0,0), puisque le rectangle du joueur a sa base positionnée à plat, et Va peut être déduit du vecteur directionnel de la caméra (noté ici Vc), en admettant que y et z sont sur les axes à plat (sinon corriger).
    Va = Normalise (0, vc.y, vc.z), en admettant que x est sur l'axe correspondant à la hauteur, y et z sur les axes à plat (si ce n'est pas le cas, il suffit de corriger, l'indice à 0 dans la formule doit correspondre à la hauteur)
    Ok je suis complètement perdu maintenant, je ne suis plus du tout ce dont vous parlez J'ai essayé de comprendre, mais rien de ce que vous avez dit après ça ne m'a paru clair, rien du tout, désolé.

  11. #10
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Citation Envoyé par Edahel Voir le message
    Les touches sont WASD, mais je met toujours mon clavier en querty pour utiliser le programme afin d'utiliser les touches ZQSD et améliorer le confort. La commande controllable ne change rien, mais ce n'est pas un problème étant donné que le déplacement fonctionne correctement de toute façon.
    C'est déjà plus clair.
    Donc effectivement, les touches employées pour déplacer la caméra, sont bien celles définies dans le code java du programme Queasycam.java (que vous pouvez consulter sur le site GitHub comme déjà précisé :https://github.com/jrc03c/queasycam (cliquez sur "clone or download" pour récupérer le zip, et allez voir dans le dossier src/template/))
    Pour info, je reposte la partie du code JAVA correspondant :
    Code:
            if (keys.containsKey('a') && keys.get('a')) velocity.add(PVector.mult(right, speed));
            if (keys.containsKey('d') && keys.get('d')) velocity.sub(PVector.mult(right, speed));
            if (keys.containsKey('w') && keys.get('w')) velocity.add(PVector.mult(forward, speed));
            if (keys.containsKey('s') && keys.get('s')) velocity.sub(PVector.mult(forward, speed));
            if (keys.containsKey('q') && keys.get('q')) velocity.add(PVector.mult(up, speed));
            if (keys.containsKey('e') && keys.get('e')) velocity.sub(PVector.mult(up, speed));
    Je ne comprends pas trop, je n'ai pas envie d'influencer la vitesse de déplacement mais je veux plutôt empêcher la caméra de s'envoler ou s'enfoncer dans le sol. J'ai essayé votre code, mais ça ne fonctionne pas, le programme ne se lance même pas et affiche juste des erreurs concernant velocity.
    Le problème, c'est que la valeur de la position de la caméra est calculée dans le code java, puis l'applet camera est appelé avec ces valeurs juste derrière.
    Je vous remet la partie du code correspondant :
    Code:
            position.add(velocity);
            center = PVector.add(position, forward);
            applet.camera(position.x, position.y, position.z, center.x, center.y, center.z, up.x, up.y, up.z);
    Cette partie du code est appelée, si controllable=true.
    Mais si controllable=false, l'applet camera, qui fixe la position et l'orientation de la camera, ne sera pas appelé.
    C'est cette partie du code qui défini les propriétés de la camera :
    Code:
    applet.camera(position.x, position.y, position.z, center.x, center.y, center.z, up.x, up.y, up.z);
    J'ai tenté d'utiliser cam.controllable=false, comme son nom l'indique je ne peux plus rien contrôler, la caméra ne se déplace plus.
    Donc controllable=false fonctionne bien.
    Ca veut dire qu'à sa création, la camera est initialisée avec ses valeurs par defaut, mais comme controllable=false, ses valeurs ne peuvent plus changer automatiquement lorsqu'on bouge la souris ou qu'on appui sur les touches du clavier.

    A noter qu'il y a deux fonction définies pour créer (et initialiser) la camera.
    Une dans laquelle on ne spécifie pas near et far et une autre où on spécifie near et far.

    Voici les définitions d'appel de chaque fonction , que vous avez choisi d'appeler dans votre code (qui ont le même nom QueasyCam... mais le "compilateur" détermine lui-même a quelle fonction il a affaire, selon les valeurs passées lors de l'appel de fonction.
    Pour info, voici les deux déclarations de la fonction QueasyCam :
    Code:
        public QueasyCam(PApplet applet)
        public QueasyCam(PApplet applet, float near, float far)
    Dans le cas de la fonction sans near et far, les valeurs par defaut sont :
    Code:
            speed = 3f;
            sensitivity = 2f;
            position = new PVector(0f, 0f, 0f);
            up = new PVector(0f, 1f, 0f);
            right = new PVector(1f, 0f, 0f);
            forward = new PVector(0f, 0f, 1f);
            velocity = new PVector(0f, 0f, 0f);
            pan = 0f;
            tilt = 0f;
            friction = 0.75f;
    Ensuite, notre projet est de faire un jeu à la première personne, on ne veut pas qu'il soit à la troisième personne.
    Oui, j'ai bien compris, mais si vous laissez controllable à true, comme les positions de la camera sont mise à jour automatiquement, et que la fonction d'application de la camera est appellée juste derrière,vous devez de toutes façons préciser manuellement les propriétés (position et orientation) de la camera, PUIS appeler la fonction qui APPLIQUE la camera.

    Ce que vous devez comprendre, c'est que la camera est APPLIQUEE.
    Cela signifie qu'à partir de certaines valeurs, position, orientation (pour faire simple), la fonction d'application de la camera produit une matrice, qui sera stoquée sur la pile employée par la carte graphique.
    Tout ce qui sera envoyé par la suite sur la pile de la carte graphique (vos coordonnées de vertex), seront "multiplipliés" par cette matrice.
    C'est juste ça "la camera" : une matrice 4x4 (et cette portion de code n'est pas dans le code java fourni).

    Et qu'est-ce qu'une coordonnée Monde? Et je ne vois pas de quelles coordonnées que j'aurai apparemment définies vous parlez. A quoi correspondent-elles?
    C'est compliqué à expliquer en quelques mots, mais disons que les coordonnées des vertexs sont relatives à la matrice.
    Les coordonnées Monde sont relatives à la position de la camera (la camera étant positionnée pour de vrai en 0.0.0 en coordonnées Monde une fois la matrice camera appliquée...)
    Mais vous pouvez laisser tomber cette subtilité dans votre cas de figure.

    Je ne comprends pas, qu'est-ce que Pc (un rectangle? Alors qu'est-ce que ça vaut?), à quoi correspondent concrètement les vecteurs normalisés (Va, Vh, Vg), pourquoi parfois +, pourquoi parfois -, et pourquoi *0.5?
    Pc c'est la position centre de la camera.
    Elle est définie ici dans le code java :
    Code:
    position = new PVector(0f, 0f, 0f);
    En fait, c'est de ma faute, j'ai "schématisé" le calcul :
    "+", ça veut dire une addition.
    Comme Va,Vg,Vh sont des vecteurs, "+" correspond à une addition de vecteurs.

    Par exemple, voici un code en langage Pascal qui additionne (+) deux vecteurs :
    Code:
    //**********************************************************//
    //** Retourne le vecteur addition de vecteurs V = V1 + V2                   **//
    //**********************************************************//
    function AddV(v1,v2 : TVector): TVector;
    begin
      AddV.vecF[0]:=v1.vecF[0] + v2.vecF[0];
      AddV.vecF[1]:=v1.vecF[1] + v2.vecF[1];
      AddV.vecF[2]:=v1.vecF[2] + v2.vecF[2];
    end;
    Je pense qu'il doit exister en langage processing une fonction analogue, qui additionne des vecteurs.

    De la même manière, "*" correspond à la multiplication d'un vecteur par une valeur scalaire, ce qui revient à changer son module (sa longueur).
    Voici un code en langage Pascal qui fait ce travail :
    Code:
    //*********************************************************//
    //** Retourne le vecteur Multiplie par un scalaire V = V1 x k                **//
    //*********************************************************//
    function MultV(v1: TVector; k: GlFloat): TVector;
    begin
      MultV.vecF[0]:=v1.vecF[0] * k;
      MultV.vecF[1]:=v1.vecF[1] * k;
      MultV.vecF[2]:=v1.vecF[2] * k;
    end;
    Donc, le signe "-" revient à multiplier le vecteur par la valeur scalaire -1, puis à l'additionner (+).

    Concrètement, les vecteurs Vh,Vg,Vh correspondent à des vecteurs UNITAIRES (dont le module, la longueur, vaut 1).
    Pour arriver à une valeur en rapport avec la largeur, la hauteur ou la profondeur, on les multiplie par L,H ou E.
    La multiplication par 0.5, c'est parce qu'on part du centre du retangle (H étant la hauteur TOTALE, 0.5*H est la demi-hauteur, puisqu'on part du centre et pas de la base).

    Citation Envoyé par LeMulet
    A noter que Vg peut être déduit du vecteur directionnel de la caméra, mais Va et Vh ne sont pas le vecteur avant et le vecteur haut de la caméra.
    Vh vaut (1,0,0), puisque le rectangle du joueur a sa base positionnée à plat, et Va peut être déduit du vecteur directionnel de la caméra (noté ici Vc), en admettant que y et z sont sur les axes à plat (sinon corriger).
    Va = Normalise (0, vc.y, vc.z), en admettant que x est sur l'axe correspondant à la hauteur, y et z sur les axes à plat (si ce n'est pas le cas, il suffit de corriger, l'indice à 0 dans la formule doit correspondre à la hauteur)
    Ok je suis complètement perdu maintenant, je ne suis plus du tout ce dont vous parlez J'ai essayé de comprendre, mais rien de ce que vous avez dit après ça ne m'a paru clair, rien du tout, désolé.
    Si vous regardez le code java :
    Code:
            up = new PVector(0f, 1f, 0f);
            right = new PVector(1f, 0f, 0f);
            forward = new PVector(0f, 0f, 1f);
    Vous constatez qu'il s'agit là de ces fameux vecteur (à peu de choses près, ici ils ont pris le vecteur latéral droite alors que j'ai pris le vecteur latéral gauche ) Vh, -Vg, Va.
    Ces valeurs, sont j'imagine initialisées à la création de la caméra, puis mises à jour automatiquement à chaque fois que l'orientation de la camera change.

    Le problème, c'est que vous ne pouvez pas vous fier à ces vecteurs tels quels pour construire le rectangle qui entoure le joueur.
    Si vous preniez ces valeurs, vous auriez un rectangle orienté (par exemple penché vers l'avant, si vous regardez vers l'avant avec la camera).
    Nous, vu qu'on veut se deplacer à l'horizontal, on veut un rectangle posé tout droit sur sa base.
    Mais on peut quand même employer les valeurs de la camera (les trois vecteurs up, right,forward), pour "redresser" le rectangle de la camera et en faire un rectangle correspondant au joueur.

  12. #11
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    J'ai essayé votre code, mais ça ne fonctionne pas, le programme ne se lance même pas et affiche juste des erreurs concernant velocity.
    Oui, c'est normal, ce n'était pas un code à copier dans le votre (en plus vous programmez en processing, pas en java...), mais un code à modifier dans le code JAVA fourni sur le site GitHub (mais je n'y connais pas grand chose en java, et je ne suis pas très sur que modifier le source va changer quelque-chose, (il faudrait que quelqu'un qui connaisse bien le java donne son avis sur la question, recréer le .jar etc.))

  13. #12
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Une chose qui m'avait échappé.
    Si on regarde le source de Queasycam :
    Code:
        private PVector up;
        private PVector right;
        private PVector forward;
    On constate que les vecteurs up, right, forward sont déclarés private...
    On ne peut donc pas les modifier (à moins comme déjà dit, si on bidouille le source QueasyCam.java (par exemple ici en déclarant les vecteurs en public), qu'on le compile pour créer les .class et qu'on mette à jour le .jar)

    Par contre, on peut les lire avec les methodes get proposée en fin de source.
    Code:
        public PVector getForward(){
            return forward;
        }
        
        public PVector getUp(){
            return up;
        }
        
        public PVector getRight(){
            return right;
    Par contre, pan, tilt et position sont déclarés public :
    Code:
        public PVector position;
        public float pan;
        public float tilt;
    C'est peut-être la solution à votre problème.
    Une possibilité serait de stocker certaines valeurs suite à un premier draw (ce qui serait bien ce serait de nous montrer votre portion de code qui fait appel à la camera, pour situer), de changer temporairement ces valeurs, de ré-appeler le draw une deuxième fois, et de remettre certaines valeurs à leur valeur stockée suite au premier draw.
    (Ca va empiler deux matrices dans la pile de vue, mais ce n'est pas grave)

    Comme on le voit d'après le source de QueasyCam, le mouvement de la souris en deux appels de draw risque d'être pris en compte à nouveau.
    Pour éviter la prise en compte d'un mouvement de souris sur pan et tilt, on peut mettre sensitivity à 0 avant appel du deuxième draw, comme on peut le voir sur cette portion de code :
    Code:
    pan += PApplet.map(mouse.x - prevMouse.x, 0, applet.width, 0, PConstants.TWO_PI) * sensitivity;
    tilt += PApplet.map(mouse.y - prevMouse.y, 0, applet.height, 0, PConstants.PI) * sensitivity;
    De la même manière, pour éviter que la camera ne se déplace deux fois, on doit mettre speed à 0 avant appel du deuxième draw et de même on doit mettre friction à 0 pour annuler velocity et éviter que la position ne change.
    Code:
            if (keys.containsKey('a') && keys.get('a')) velocity.add(PVector.mult(right, speed));
            if (keys.containsKey('d') && keys.get('d')) velocity.sub(PVector.mult(right, speed));
            if (keys.containsKey('w') && keys.get('w')) velocity.add(PVector.mult(forward, speed));
            if (keys.containsKey('s') && keys.get('s')) velocity.sub(PVector.mult(forward, speed));
            if (keys.containsKey('q') && keys.get('q')) velocity.add(PVector.mult(up, speed));
            if (keys.containsKey('e') && keys.get('e')) velocity.sub(PVector.mult(up, speed));
    
            velocity.mult(friction);
            position.add(velocity);
    Maintenant, pour que la composante y de position (qui est un vecteur) ne change pas en fonction de la direction de vue, on doit, APRES le premier draw, et AVANT l'appel du second draw, définir la valeur de y de position (c'est la hauteur à laquelle se trouvent les yeux du joueur).

    Suite à ce second appel de draw, on remet alors les valeurs qu'on avait changé, et stoqué temporairement, à leur valeur initiale.
    Donc speed, friction, sensitivity, velocity.
    On ne touche bien sûr pas à position.

    Il y aurait d'autres propriétés à gérer de cette manière, comme robot et target, mais si vous ne les employez pas, vous pouvez laisser ça de côté.

  14. #13
    invite70e74265

    Re : Processing - Problèmes de hitbox

    Bonjour, désolé pour la réponse tardive!

    J'ai essayé de donner une hitbox à la caméra et ensuite aux murs, mais durant nos recherches avec mes professeurs nous avons trouvé une solution plus simple; Queasycam possède la fonction cam.position, et nous nous en sommes servis de cette manière:

    Code:
        if (cam.position.x<150) {
    cam.position.x=150;
          }
    Par exemple ici, on vérifie si la caméra atteint 150 en x, et si cette condition est vérifiée, sa position en x est égale à 150 (donc elle ne peut pas dépasser cette valeur). Ainsi, ça nous permet de bloquer la caméra sans pour autant créer de véritable hitbox! Evidemment, on répète l'opération avec cam.position.y et cam.position.z pour tout gérer.

    Pour bloquer la caméra en hauteur, même principe:

    Code:
          if (cam.position.y>200) {
    cam.position.y=200;                      // Ici la caméra est bloquée en hauteur mais vers le haut seulement, elle ne peut pas dépasser 200 en y mais peut descendre plus bas
          }
          if (cam.position.y<200) {
    cam.position.y=200;                      //C'est donc là qu'on la bloque également en hauteur vers le bas, et combiné avec le if d'avant, elle est coincée entre les deux contraintes et ne peut pas bouger sur y
          }
    Maintenant la principale difficulté est de créer des conditions spéciales pour certaines formes de notre pièce (qui n'est pas complètement carrée), mais on devrait aisément trouver, le plus dur a été fait.

    Merci en tout cas de votre aide, et désolé de ne pas avoir été un élève très brillant xD
    Dernière modification par JPL ; 07/05/2019 à 19h23. Motif: Ajout de la balise Code (#) pour garder l'indentation

  15. #14
    invite6486d7bd

    Re : Processing - Problèmes de hitbox

    Citation Envoyé par Edahel
    Par exemple ici, on vérifie si la caméra atteint 150 en x, et si cette condition est vérifiée, sa position en x est égale à 150 (donc elle ne peut pas dépasser cette valeur).
    Avant le draw, c'est trop tôt.
    Après le draw, c'est trop tard...
    Donc si, cam.position.x peut dépasser 150 et plus précisément cam.position.x ne peut pas dépasser (150 + cam.velocity).

    Citation Envoyé par Edahel
    Pour bloquer la caméra en hauteur, même principe:
    Justement, pour vérifier, si vous regardez vers le bas (le plus bas possible), et que vous avancez vers l'avant :
    Est-ce que vous voyez le sol se rapprocher (d'un cran) lorsque vous appuyez sur la touche avance, et lorsque vous relachez cette touche, vous reculez (d'un cran) ?

    Pareil lorsque vous êtes devant un mur...(il faudra tenir compte de cam.velocity pour éviter que la caméra ne dépasse le mur)

    Citation Envoyé par Edahel
    Maintenant la principale difficulté est de créer des conditions spéciales pour certaines formes de notre pièce (qui n'est pas complètement carrée), mais on devrait aisément trouver, le plus dur a été fait.
    Le plus simple a été fait, approximativement (mais si ça suffit, pourquoi pas).

Discussions similaires

  1. Processing collisions
    Par invite58e922c1 dans le forum Programmation et langages, Algorithmique
    Réponses: 32
    Dernier message: 09/05/2019, 00h59
  2. Programmation sur processing
    Par inviteb96932ce dans le forum Programmation et langages, Algorithmique
    Réponses: 0
    Dernier message: 21/02/2018, 17h07
  3. Processing writer
    Par invite2b1b487a dans le forum Programmation et langages, Algorithmique
    Réponses: 5
    Dernier message: 11/12/2015, 23h07
  4. Word Processing,
    Par invite2800a7c8 dans le forum Programmation et langages, Algorithmique
    Réponses: 6
    Dernier message: 09/08/2015, 20h45
  5. Probleme processing
    Par invite73cc98a5 dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 16/03/2015, 18h49