[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 » mer. 02 mars 2016 22:43

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 09:41, modifié 1 fois.
"Lourd est le parpaing de la réalité sur la tartelette aux fraises de nos illusions" - Boulet.

Avatar du membre
mdanielm
Membre émérite
Membre émérite
Messages : 235
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

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

#2

Message par mdanielm » jeu. 03 mars 2016 08:49

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 !

Avatar du membre
mdanielm
Membre émérite
Membre émérite
Messages : 235
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

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

#3

Message par mdanielm » jeu. 03 mars 2016 10:29

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 » mar. 11 avr. 2017 20:28

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 : 106
Enregistré le : mer. 23 mars 2016 08:17
Status : Hors ligne

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

#5

Message par Numeric » ven. 12 mai 2017 02:38

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

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2090
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

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

#6

Message par jchd » ven. 12 mai 2017 13:58

... 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