[R] Détecter Collision Guictrlcreate...

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
TripleLardon
Niveau 2
Niveau 2
Messages : 19
Enregistré le : jeu. 04 févr. 2016 22:29
Status : Hors ligne

[R] Détecter Collision Guictrlcreate...

#1

Message par TripleLardon »

Bonjour à tous et à toutes :D

Voila, dans mon programme je souhaite détecter lorsque la hitbox d'un Guictrlcreate.. entre collision (se superpose) avec celle d'une autre hitbox d'un autre Guictrlcreate..

Si ce dont je vous parle n'est pas claire, je vous ai préparé un petit programme explicatif.

Code : Tout sélectionner

 #include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <FontConstants.au3>
#include <ListviewConstants.au3>
#include <ColorConstants.au3>
#include <Misc.au3>

Guicreate("",550,300)

Guictrlcreatelabel("Les touches ZQSD pour déplacer le carré bleu" & @crlf & "Les fléches directionelles pour déplacer le carré rouge",5,5)

;creation du perso 1 qui est le carré rouge
$Perso1 = Guictrlcreatelabel("",350,100,50,50)
GUICtrlSetBkColor($Perso1,$COLOR_RED)

;creation du perso 12qui est le carré bleu
$Perso2 = Guictrlcreatelabel("",150,100,50,50)
GUICtrlSetBkColor($Perso2,$COLOR_BLUE)


Guisetstate()

While 1

	$msg = GUIGetMsg(1)

;Trouve les coordonnés du perso 1
	$Coo1 = ControlGetPos("","",$Perso1)
	$X_P1 = $Coo1[0]
	$Y_P1 = $Coo1[1]

;Trouve les coordonnés du perso 2
	$Coo2 = ControlGetPos("","",$Perso2)
	$X_P2 = $Coo2[0]
	$Y_P2 = $Coo2[1]


;Systeme pour deplacer le perso 1
	  If _IsPressed("26") Then
	  Guictrlsetpos($Perso1,$X_P1,$Y_P1 - 1)

	   ElseIf _IsPressed("28") Then
	   Guictrlsetpos($Perso1,$X_P1,$Y_P1 + 1)

	   ElseIf _IsPressed("27") Then
	   Guictrlsetpos($Perso1,$X_P1 + 1,$Y_P1)


	   ElseIf _IsPressed("25") Then
	   Guictrlsetpos($Perso1,$X_P1 - 1,$Y_P1)
	   EndIf

;Systeme pour deplacer le perso 2
	   If _IsPressed("5A") Then
	  Guictrlsetpos($Perso2,$X_P2,$Y_P2- 1)

	   ElseIf _IsPressed("53") Then
	   Guictrlsetpos($Perso2,$X_P2,$Y_P2 + 1)

	   ElseIf _IsPressed("44") Then
	   Guictrlsetpos($Perso2,$X_P2 + 1,$Y_P2)


	   ElseIf _IsPressed("51") Then
	   Guictrlsetpos($Perso2,$X_P2 - 1,$Y_P2)
	   EndIf

	   
;Permet de fermer le programme
	   Select
		   Case $Msg[0] = $Gui_event_close
		Exit
	   EndSelect


	WEnd
	

Si vous avez lancé le programme si dessus, on peut bouger les carré, et j'aimerais détecter si les carrés rentre en collision entre eux. J'ai déjà fais un test en regardant si:

Code : Tout sélectionner

 if $X_Carre_Bleu = $X_Carre_Rouge and  $Y_Carre_Bleu = $Y_Carre_Rouge then
 faire quelque chose

Le problème de cette méthode est, que la collision est détecter seulement si les pixels en haut a gauche des carrés se touchent.

En espèrent avoir étais claire et aussi, que ce dont je recherche soit possible a créer.
Merci de votre lecture et bonne journée !
Modifié en dernier par TripleLardon le mer. 12 avr. 2017 10:41, modifié 1 fois.
"Lourd est le parpaing de la réalité sur la tartelette aux fraises de nos illusions" - Boulet.
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Re: [..] Détecter Collision Guictrlcreate...

#2

Message par mdanielm »

Souvenir lointain de fac:

Un carré est une -boule- pour la métrique du plan:
d(M,N) = max(|xM-xN|, |yM-yN|)

Deux boules se rencontrent si la distance des centres est inférieure à la somme des rayons.

Exemple:
Carré 1 de centre C1(100,120) et de rayon 20 = width/2 = height/2
Carré 2 de centre C2(130,110) et de rayon 30 = ....
Ils se rencontrent si :
d(C1,C2) = max(30,10) <= 30+20
Comme 30 <= 50, ils se rencontrent.

... idée à tester sur des carrés seulement !
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Re: [..] Détecter Collision Guictrlcreate...

#3

Message par mdanielm »

Idée 2:
Une autre idée consiste à convertir les contrôles en objet -Region- de GDIPlus et d'utiliser _GDIPlus_RegionCombineRect() qui effectue l'intersection des régions.
Courage!
Avatar du membre
TripleLardon
Niveau 2
Niveau 2
Messages : 19
Enregistré le : jeu. 04 févr. 2016 22:29
Status : Hors ligne

Re: [..] Détecter Collision Guictrlcreate...  

#4

Message par TripleLardon »

Bonjour!

Je me permet une petit MaJ du post. Presque un an après j'y ai soudainement repensé et j'ai donc fait une fonction permettant de détecter une collision entre 2 carrés
Cette fonction de marche qu'avec des carrés, mais ils suffit de changer la manière dont sont calculés les coordonnées des angles (ou coin) pour que cela marche avec des rectangles.

La fonction comprend les arguments suivant:
$x1 = Coordonné x de carré 1
$y1 = Coordonné y de carré 1
$x2 = Coordonné x de carré 2
$y2 = Coordonné y de carré 2
$z1 = Largeur du carré 1
$z2 = Largeur du carré 2

Fonction:
func collision($x1,$y1,$x2,$y2,$z1,$z2)

   Local $A1[2] = [$x1,$y1]
   Local $B1[2] = [$x1 + $z1,$y1]
   Local $C1[2] = [$x1 + $z1,$y1 + $z1]
   Local $D1[2] = [$x1,$y1 + $z1]

   Local $A2[2] = [$x2,$y2]
   Local $B2[2] = [$x2 + $z2,$y2]
   Local $C2[2] = [$x2 + $z2,$y2 + $z2]
   Local $D2[2] = [$x2,$y2 + $z2]

   If ($C1[0] > $A2[0] and $C1[0] < $B2[0] and $C1[0] < $C2[0] and $C1[0] > $D2[0] and $C1[1] > $A2[1] and $C1[1] > $B2[1] and $C1[1] < $C2[1] and $C1[1] < $D2[1]) or($B1[0] > $A2[0] and $B1[0] < $B2[0] and $B1[0] < $C2[0] and $B1[0] > $D2[0] and $B1[1] > $A2[1] and $B1[1] > $B2[1] and $B1[1] < $C2[1] and $B1[1] < $D2[1]) or ($D1[0] > $A2[0] and $D1[0] < $B2[0] and $D1[0] < $C2[0] and $D1[0] > $D2[0] and $D1[1] > $A2[1] and $D1[1] > $B2[1] and $D1[1] < $C2[1] and $D1[1] < $D2[1]) or ($A1[0] > $A2[0] and $A1[0] < $B2[0] and $A1[0] < $C2[0] and $A1[0] > $D2[0] and $A1[1] > $A2[1] and $A1[1] > $B2[1] and $A1[1] < $C2[1] and $A1[1] < $D2[1]) Then
      Return 1
   EndIf
EndFunc
Il a peux être moyen de réduire la fonction, mais au moins ça marche :D
"Lourd est le parpaing de la réalité sur la tartelette aux fraises de nos illusions" - Boulet.
Avatar du membre
Numeric
Niveau 5
Niveau 5
Messages : 127
Enregistré le : mer. 23 mars 2016 08:17
Status : En ligne

Re: [R] Détecter Collision Guictrlcreate...

#5

Message par Numeric »

Sujet résolu mais pour faire plus simple... :D
#include <WinAPI.au3>


; #FUNCTION# ====================================================================================================================
; Name ..........: Ws_CtrlMetrics
; Description ...: Determine si deux controls de même classe entre en colision
; Syntax ........: Ws_CtrlMetrics($idCtrl1, $idCtrl2, $CtrlC_Name)
; Parameters ....: $idCtrl1             - an integer value.
;                  $idCtrl2             - an integer value.
;                  $CtrlC_Name          - an unknown value.
; Return values .: -1 Ctrl1 ou Ctrl2 n'appartient pas à la classe indiquée
;                  Succes : "String explicite"
; Author ........: Numeric
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func Ws_CtrlMetrics($idCtrl1, $idCtrl2, $CtrlC_Name)
   If Not _isGUICtrHwnd($idCtrl1, $CtrlC_Name) Then
      Return SetError(1, 0, -1)
   EndIf

   If Not _isGUICtrHwnd($idCtrl2, $CtrlC_Name) Then
      Return SetError(2, 0, -2)
   EndIf
   Local $aCtrl1_POS = ControlGetPos("", "", $idCtrl1)
   Local $aCtrl2_POS = ControlGetPos("", "", $idCtrl2)

   If (($aCtrl1_POS[2] - $aCtrl1_POS[0]) <= ($aCtrl2_POS[2] - $aCtrl2_POS[0])) And (($aCtrl2_POS[3] - $aCtrl2_POS[1]) <= ($aCtrl1_POS[3] - $aCtrl1_POS[1])) Or _
         (($aCtrl1_POS[2] - $aCtrl1_POS[0]) >= ($aCtrl2_POS[2] - $aCtrl2_POS[0])) And (($aCtrl2_POS[3] - $aCtrl2_POS[1]) >= ($aCtrl1_POS[3] - $aCtrl1_POS[1])) Then

      $sRetText = "Les deux contrôles se touchent!"
   Else
      $sRetText = "Les deux contrôles ne se touchent pas!"
   EndIf
   Return _WinAPI_ShowMsg($sRetText)

EndFunc   ;==>Ws_CtrlMetrics


; #FUNCTION# ====================================================================================================================
; Name ..........: _isGUICtrHwnd
; Description ...: Determine si un control appartient une classe determinée
; Syntax ........: _isGUICtrHwnd($hWnd[, $CtrlC_Name = "Static"])
; Parameters ....: $hWnd                - a handle value.
;                  $CtrlC_Name          - [optional] an unknown value. Default is "Static".
; Return values .: Succes True or False
; Author ........: Numeric
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _isGUICtrHwnd($hWnd, $CtrlC_Name = "Static")
   Return BitAND(_WinAPI_IsClassName($hWnd, $CtrlC_Name), True) = True
EndFunc   ;==>_isGUICtrHwnd


Exemple()


Func Exemple()
   #include <GUIConstantsEx.au3>
   #include <StaticConstants.au3>
   #include <WindowsConstants.au3>
   #Region ### START Koda GUI section ### Form=
   Global $Form1 = GUICreate("Numeric ", 304, 118, 192, 124)
   Global $Label1 = GUICtrlCreateLabel("Control Label 1", 32, 24, 75, 17)
   Global $Label2 = GUICtrlCreateLabel("Control Label 2", 88, 24, 75, 17)
   Global $Label3 = GUICtrlCreateLabel("Control Label 3", 32, 56, 75, 17)
   GUISetState(@SW_SHOW)
   #EndRegion ### END Koda GUI section ###
     Ws_CtrlMetrics($Label1,$Label2,"") ;Si Label1 et Label2
    Ws_CtrlMetrics($Label2,$Label1,"");Si Label2 et Label1
    Ws_CtrlMetrics($Label1,$Label3,"") ;Label1 et Label3
    Ws_CtrlMetrics($Label2,$Label3,"") ;Label2 et Label3
   While 1
      $nMsg = GUIGetMsg()
      Switch $nMsg
         Case $GUI_EVENT_CLOSE
            Exit

         Case $Form1
         Case $Form1
         Case $Form1
         Case $Form1
         Case $Label1
         Case $Label2
         Case $Label3
      EndSwitch
   WEnd
EndFunc   ;==>Exemple

 
De 0 et 1 vers les étoiles , tout part du Binaire, Numeric
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2272
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [R] Détecter Collision Guictrlcreate...

#6

Message par jchd »

... et en utilisant Abs() on a une condition à tester deux fois plus simple.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Répondre