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

Problème de collision

shinigota
shinigota
Niveau 10
07 mars 2014 à 01:22:10

Salut !
Je suis en train de créer un petit jeu dans lequel on est un petit robot bloqué dans une map, y'a donc une sortie mais pour y accéder il faut une clé qui se trouve sous une boite.
Le but est donc de déplacer les boites sans se bloquer tout en récupérant la clé.
https://www.dropbox.com/s/b88wfgx4abbgo7a/Capture%20d%27%C3%A9cran%202014-03-07%2000.29.32.png
(là vu la construction de la map, c'est pas compliqué :hap: )

Bref, toutes mes collisions marchent presque entièrement, sauf une :
Evidemment, les boites entre ellse ne doivent pas se rentrer dedans, en gros si je bouge une boite et qu'elle en rencontre une autre, ma boite passera pas à travers mais "glissera" le long de la boite.
Par exemple si j'ai une ligne de boite horizontale, en haut j'ai une autre boite que je veux faire passer de l'autre côté. Je la glisse vers le bas, ma boite va rencontrer les autres, elle pourra pas descendre du coup, mais pourra toujours bouger sur les côtés !

Ca marche, mais à un truc près :
https://www.dropbox.com/s/gupq7is3k7d9o1p/Capture%20d%27%C3%A9cran%202014-03-07%2000.35.58.png
Par exemple, la boite que je glisse, qui est tout en bas (celle au dessus du carré rouge, alignée, qui d'ailleurs montre ou se trouverais la boite sans collisions) prend bien en compte la ligne de boites tout en bas, mais pas celles à sa gauche !
Du coup si j'essaie de la faire passer en dessous, évidemment la boite voudra pas et pourra que glisser sur les côtés, mais elle prend pas en compte celles à sa droite ou sa gauche, et je peux passer à travers, et d'ailleurs on le vois bien là, elle st à moitié dans celle de gauche !
Je peux aussi le faire horizontalement, j'ai le même problème ...
https://www.dropbox.com/s/gupq7is3k7d9o1p/Capture%20d%27%C3%A9cran%202014-03-07%2000.35.58.png

Bref j'ai fais un topic sur le fofo programmation, mais finalement je me suis dis que les collisions sont utilisées surtout dans les jeux, alors je re demande ici, car en plus de ça fait maintenant 3 jours que je reste bloqué au même endroit en ayant plus ou moins avancé ....

J'ai essayé plusieurs choses : avec la méthode intersect pour les rectangles (qui vient de awt, obligé de l'utiliser en fait c'est un DM de spé ISN :hap: ), sauf que mes boites doivent glisser l'une sur l'autre, et les arrêtes doivent que être collées, mais rentrent pas en contact et d'après ce que j'ai constaté avec ce que j'ai essayé, la méthode intersect fonctionne seulement si les rectangles se "rentrent dedans". Du coup j'ai un décalage, vu que je dois faire rentrer ma boite dans l'autre pour que ça fonctionne, et moi je veux juste qu'elles soient côte à côte...
Du coup j'ai essayé de détecter les collisions manuellement avec les coordonnées pour prendre en compte le décalage, qui est d'un pixel, puis après j'ai essayé trois tonnes de truc, dont je ne m'en souviens même plus, et là je procède de la manière :
Quand je bouge ma boite je récupère à chaque fois ses coordonnées. Quand elle rentre en collision avec une autre boite, je récupère les coordonnées de celle ci, puis après avec des calculs, je définis qu'un boolean right et vrai si ma boite vient du côté droit de la boîte qui bloque, top si elle vient du haut.
Et selon d'où elle vien,t quand ma boite va rentrer en collision avec une autre je bloquerais les coordonnées X, ou Y selon si elle vient de droite, gauche, haut ou bas.
Par exemple si y'a une collision et que la boite que je glisse vient de droite, ça voudrait dire que je pourrais pas passer à travers de l'autre boite (qui est alors a gauche), donc j'aurais le droit de glisser que en Y (vu qu'en X y'a la boite qui bloque) tant que je suis en collision avec celle ci, et enfin, j'aurais :
tmpBox.setPosition(box.getX() + box.getBounds().width, e.getY() - deltaY);
Où tmpBox c'est la boite que je déplace, box celle qui est en collision avec la mienne, et e c'est la souris.

Bref, voilà mon code avec des commentaires évidemment:
http://pastebin.com/vWJHyYMT

C'est long, mais n'ayez pas peur, y'a plein de choses répétitives :hap:
Puis y'a une partie qui a rien à voir avec le problème mais je voulais la mettre pour avoir la méthode en entière.

Bref, merci énormément d'avoir lu mon code, d'avoir eu le courage de lire mon pavé, et désolé de vous avoir fait perdu du temps, mais bon j'aimerais bien rendre un truc qui fonctionne et je suis complètement perdu.
Et merci pour les futures réponses !
Sur ce, bonne soirée (ou matinée ? :hap: ) !

Pseudo supprimé
Pseudo supprimé 07 mars 2014 à 03:00:43

Bonjour,
Je ne suis pas rentré a fond dans ton code mais quelque chose me choque.

Tu fais :
if(tmpX < tmpX2){
left = false;
right = true;
} else {
left = true;
right = false;
}

A la suite :
if(top && right){
if(abs(tmpX - tmpX2) > abs(tmpY - tmpY2)){
right = true; // LA PROBLEME left devrait aussi être mis a false
top = false; // IDEM bottom devrait aussi être mis à true
} else {
right = false; // BEN AJOUTE L'INVERSE pour left
top = true; // IDEM pour bottom
}
..
..

En fait tu risque de te trouver avec par exemple rigth et left tous les deux a true ??

Et de plus dans ton code plus haut :
if (right) {
tmpBox.setPosition(box.getX() + box.getBounds().width, e.getY() - deltaY);
}
if (left){
tmpBox.setPosition(box.getX() - tmpBox.getBounds().width, e.getY() - deltaY);
}
A mon avis soit c'est left ou soit c'est right, mais traite pas les deux.

Un conseil, prends une feuille de papier, un crayon, réfléchit a ton algo de nouveau.

Bonne continuation.

Pseudo supprimé
Pseudo supprimé 07 mars 2014 à 03:10:24

Pour t'aider dans ta démarche.
Utilise plutot des concepts de directions.

Par ex:
DirX => -1 left, 0 rien, 1 right
DirY => -1 top, 0 rien, 1 bottom

Bonne Continuation.

shinigota
shinigota
Niveau 10
07 mars 2014 à 12:13:40

D'abord, merci beaucoup de ton aide, j'avais pas pensé aux -1 0 et 1 :oui:
Déjà ça sera beaucoup plus simple à traiter :oui:

Sinon
right = true; // LA PROBLEME left devrait aussi être mis a false
top = false; // IDEM bottom devrait aussi être mis à true

Justement, bottom ne dois pas être true, en fait au début de la méthode on constate que le cube vient d'en haut à gauche, donc on doit le placer soit en haut de l'autre, soit à sa gauche, donc je garde qu'une direction et bottom devrait être false.
Sinon je pense bien que mon algo est pas terrible, mais le system.out.println m'affichant les valeurs des booléens me dit bien ce qui est attendu :oui:

Sinon j'avais déjà réfléchis sur papier, j'ai du m'y prendre comme un manche vu que j'ai horreur des collisions, puis c'est ce qui m'a aider à pondre ça :hap:

Bon je m'y remet !

Pseudo supprimé
Pseudo supprimé 07 mars 2014 à 12:35:18

Bonjour,
Tu t'y prends mal dans ton raisonnement.
A mon sens il ne faut pas traiter cela par un event drag.

1 / Event button mouse down
Si position mouse est sur un cube mobile
Alors le sélectionner
Et mémoriser position souris

2 / Event button mouse up
Déselectionner le cube

3 / Event mouse move
Si cube sélectionné
Calculer direction movement souris entre ancienne position et nouvelle position.
Mémoriser position souris
Traiter déplacement du cube

Voila en espérant que cela t'aide/

shinigota
shinigota
Niveau 10
07 mars 2014 à 12:44:44

Merci encore de ton aide :oui:
J'avais pas trop compris la différence enter mousemoved et mousegdragged, mais bon, d'après google si j'ai bien saisis le truc, mousedragged c'est quand on clic en même temps.
En effet j'aurais du utiliser mousemoved alors, d'ailleurs je vais le changer, là si on clic et qu'on glisse la souris sans cliquer avant sur une boite j'ai des erreurs dans la console comme quoi tmpBox (la boite qu'on glisse) n'existe pas, du coup j'suis obligé de foutre un peu partout des if (tmpBox != null)...

Sinon je réfléchis encore pour le fait que l'algo ne prenne en compte qu'une boite, et que dans le cas du screen je passe à travers de l'autre, en fait j'ai une autre idée mais ça à l'air vraiment compliqué :
Faudrait que je teste les collisions avec chaque boite, les directions, ce qui est déjà fait, mais que si j'ai plusieurs boites en collision faudrait que j'arrive à "additionner" les dirX et dirY, comme ça j'aurait dirX 1 comme quoi sur la première boite je suis obligatoirement gauche, et dirY = 1 comme quoi je suis obligatoirement en dessous de l'autre boite ...

Mais j'suis sur que y'a une méthode bien plus simple et que je passe à côté ... :(

shinigota
shinigota
Niveau 10
07 mars 2014 à 12:50:31

Désolé du double post, mais en fait si j'ai bien compris ta partie 3/, en gros il faudrait donc que j'ai un cube sélectionné, que je bouge la souris et qu'il soit déplacé seulement à la fin du mouvement ?
Si c'est le cas j'aurais pensé que déplacer le cube en même temps que la souris serait bien plus pratique, surtout dans les niveaux difficiles ou y'aurait alors plein de caisses :oui:
Mais je t'ai peut être mal compris, dans ce cas là je m'en excuse :oui:

Pseudo supprimé
Pseudo supprimé 07 mars 2014 à 12:59:36

Non en même temps...
Essaye deja de mettre en application cet algo.

shinigota
shinigota
Niveau 10
07 mars 2014 à 14:27:41

L'algo pour les déplacements dans mousemoved ou l'idée que j'ai proposée ?
Si c'est l'idée j'y ai réfléchi, mais je bloque un peu, finalement je me suis dis qu'il fallait vérifier les collisions en X quand on en a une en Y, et en Y quand on en a une en X, mais pour ça il fallait enregistrer les boites avec lesquelles on rentre en collision pour savoir si on est encore en collision avec ...
J'suis vraiment perdu... :(

Pseudo supprimé
Pseudo supprimé 07 mars 2014 à 14:47:40

RE,

3 / Event mouse move
a)Si cube sélectionné
b)Calculer direction movement souris entre ancienne position et nouvelle position.
c)Mémoriser position souris
d)Traiter déplacement du cube

b) Tu possede ancienne position souris et nouvelle tu peut donc en déduire le déplacement gauche droite, haut base.
ex
deltaX = e.Mousex - old.Mousex;
deltaY = e.Mousey - old.Mousey;
A ce stade tu as donc la direction ou bouger le cube ainsi que son nombre de pixel correspondand.

c) memo position souris
old_mouse = e;

d) traiter déplacement du cube
C'est la que tu doit regarder si en déplacant le cube sélectionné.

Si déplace cube de deltaX
Si collision avec autre cube (gauche ou droite en fonction du signe de deltaX)
CollisionX = Vrai
Autrement
CollisionY = False

// faire même traitement pour deplace de deltaY

Si CollisionX est vrai
ALors positionCube.x += deltaX

Si CollisionY est vrai
ALors positionCube.y += deltaY

Bonne continuation.

Pseudo supprimé
Pseudo supprimé 07 mars 2014 à 14:50:26

Pdon me suis pas relus

Si déplace cube de deltaX
Si collision avec autre cube (gauche ou droite en fonction du signe de deltaX)
CollisionX = Vrai
Autrement
CollisionX = False

// faire même traitement pour deplace de deltaY

Si CollisionX est faux
ALors positionCube.x += deltaX

Si CollisionY est faux
ALors positionCube.y += deltaY

Bonne continuation.

shinigota
shinigota
Niveau 10
07 mars 2014 à 15:03:42

Merci beaucoup, c'est super sympas de ta part !
J'vais réfléchir à tout ça, remettre en forme l'algo avec les éléments que tu m'a donné :oui:

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