Sign in to follow this  
Followers 0
gottygolly

Collision detection using controls.

5 posts in this topic

I made this script just out of boredom and started to try and make it so when the boxes hit each other they would bounce like they do on the walls.

Any ideas on how to get this done? (I tried nesting another For loop inside the while loop and set it to detect it but it was too demanding on my PC)

#include<guiconstants.au3>
#include <ButtonConstants.au3>
#include <GuiMenu.au3>
#include <String.au3>
$title = "GUI"
$gui = GUICreate($title,640,480,-1,-1)
Opt("GUIOnEventMode",1)
GUISetOnEvent(-3,"_Exit")
$sec = @SEC
$msec = @MSEC
Local $box[10]
Local $speed_x[UBound($box)],$speed_y[UBound($box)]
For $i = 0 To UBound($box)-1
   $box[$i] = GUICtrlCreateLabel("",random(0,620,1),random(0,460,1),20,20)
   $random = Random(0,1,1)
   GUICtrlSetBkColor($box[$i],0x000000)
   If $random = 1 Then
      $speed_x[$i] = 1
      $speed_y[$i] = 1
   ElseIf $random = 0 Then
      $speed_x[$i] = -1
      $speed_y[$i] = -1
   EndIf
Next
GUISetState()

While 1
   $s = @SEC
   $m = @MSEC
   For $i = 0 To UBound($box)-1
   $box_cp = ControlGetPos($gui,"",$box[$i])
   If $box_cp[0] <= 0 Then
      $speed_x[$i] *= -1
   ElseIf $box_cp[1] <= 0 Then
      $speed_y[$i] *= -1
   ElseIf $box_cp[0] + $box_cp[2] >= 640 Then
      $speed_x[$i] *= -1
   ElseIf $box_cp[1] + $box_cp[3] >= 480 Then
      $speed_y[$i] *= -1
   EndIf
   GUICtrlSetPos($box[$i],$box_cp[0]-$speed_x[$i],$box_cp[1]-$speed_y[$i])
Next
   Sleep(10)
WEnd

Func _Exit()
   Exit
EndFunc

 

Share this post


Link to post
Share on other sites



I've got a bit of a head cold so I've been struggling to actually comprehend even some of my own code these last couple of days, otherwise I would try to get you started.

I see you're using ControlGetPos, instead of doing that you could store the positions of the controls in an array and just use that array to update where the control will be moved to. Once you do that you can just loop through the array, checking the positions of all of the other boxes. If the position of the current control you're checking is going to collide with another, then you can adjust the direction.

Hopefully this might help

 

The main array that holds all of the positions of the heart is

Global $heart_buffer[$MAX_HEART_COUNT][12]

The main loop of the function is what changes the x and y coordinates of the hearts but this function is what sets the starting positions and sizes of each heart

Func SetHeartStats(Const ByRef $iIndex)

 

1 person likes this

Share this post


Link to post
Share on other sites

Thank you for the reply and sharing all that information.

I've been very busy at work so I haven't had time to look through all of your code and try to understand it.

One quick dumb question however -

The line: 

Global $heart_buffer[$MAX_HEART_COUNT][12]

How is that used exactly? I understand the [$MAX_HEART_COUNT] but not the [12] part.

Share this post


Link to post
Share on other sites

It's a 2d array, the $MAX_HEART_COUNT is the maximum number of hearts that are displayed (this is the # of rows in the array)

the [12] is the columns, looking at my SetHeartStats functions we'll see what each of these do
 

Quote

[0] is the X position
[1] is the Y position
[2] is the width
[3] is the height
[4] (not relevant to what you're doing but) is a timeout I used that controlled how long the heart was shown. Once it hit the timeout it would started to shrink the heart
[5] Timer (value returned from TimerInit())
[6] Vertical speed (how fast it moves up and down)
[7] A bool value I set that determined if the heart would move left and right
[8] Horizontal speed (how fast it moves left and right)
[9] Maximum distance it can move left or right before changing direction (if it's currently moving left and goes above this value, it shifts it to move right)
[10] # of pixels it's already moved in the left or right direction
[11] a counter that was just used to make the heart not instantly stop moving left then move right (just made it look smoother when moving horizontally)

Inside the main while loop you can see where I adjust the x and y position of the hearts, and if it's supposed to shrink, where I'm checking the timeout for the timer, and adjusting the width and height, so the heart looks like it's shrinking.

You could customize yours however you like, making some controls bigger or smaller, making some controls move faster or slower, etc.

Share this post


Link to post
Share on other sites

You can do something like this here:

#include <guiconstants.au3>
#include <ButtonConstants.au3>
#include <GuiMenu.au3>
#include <String.au3>
#include <WinAPIGdi.au3>

$title = "GUI"
$gui = GUICreate($title, 640, 480, -1, -1)
Opt("GUIOnEventMode", 1)
GUISetOnEvent(-3, "_Exit")
$sec = @SEC
$msec = @MSEC
Local $box[10]
Local $speed_x[UBound($box)], $speed_y[UBound($box)]
For $i = 0 To UBound($box) - 1
    $box[$i] = GUICtrlCreateLabel("", Random(0, 620, 1), Random(0, 460, 1), 20, 20)
    $random = Random(0, 1, 1)
    GUICtrlSetBkColor($box[$i], 0x000000)
    If $random = 1 Then
        $speed_x[$i] = 1
        $speed_y[$i] = 1
    ElseIf $random = 0 Then
        $speed_x[$i] = -1
        $speed_y[$i] = -1
    EndIf
Next
GUISetState()

While 1
    $s = @SEC
    $m = @MSEC
    For $i = 0 To UBound($box) - 1
        $box_cp = ControlGetPos($gui, "", $box[$i])
        If BitOR($box_cp[0] <= 0, $box_cp[0] + $box_cp[2] >= 640) Then $speed_x[$i] *= -1
        If BitOR($box_cp[1] <= 0, $box_cp[1] + $box_cp[3] >= 480) Then $speed_y[$i] *= -1
        Collision_Check($box_cp, $i)
        GUICtrlSetPos($box[$i], $box_cp[0] - $speed_x[$i], $box_cp[1] - $speed_y[$i])
    Next
    Sleep(10)
WEnd

Func Collision_Check($aR1, $iPos)
    Local $i, $aR2
    For $i = 0 To UBound($box) - 1
        If $i = $iPos Then ContinueLoop

        $aR2 = ControlGetPos($gui, "", $box[$i])

        If BitAND($aR1[0] + $aR1[2] / 2 + $aR2[2] / 2 > $aR2[0], _
                $aR2[0] + $aR2[2] / 2 + $aR1[2] / 2 > $aR1[0], _
                $aR1[1] + $aR1[3] / 2 + $aR2[3] / 2 > $aR2[1], _
                $aR2[1] + $aR2[3] / 2 + $aR1[3] / 2 > $aR1[1]) Then
            Select
                Case ($aR2[0] + $aR2[2]) - $aR1[0] < 5 ; Left edge
                    $speed_x[$i] *= -1
                    $speed_x[$iPos] *= -1
                    Return 1
                Case ($aR2[1] + $aR2[3]) - $aR1[1] < 5 ; Upper edge
                    $speed_y[$i] *= -1
                    $speed_y[$iPos] *= -1
                    Return 2
                Case ($aR1[1] + $aR1[0]) - $aR1[2] < 5 ; Right edge
                    $speed_x[$i] *= -1
                    $speed_x[$iPos] *= -1
                    Return 3
                Case ($aR1[2] + $aR1[1]) - $aR1[3] < 5 ; Lower edge
                    $speed_y[$i] *= -1
                    $speed_y[$iPos] *= -1
                    Return 4
            EndSelect
        EndIf
    Next
EndFunc   ;==>Collision_Check

Func _Exit()
    Exit
EndFunc   ;==>_Exit

 

1 person likes this

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0