name22

Circle Collision

Jun 29th, 2011
112
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <WindowsConstants.au3>
  2. #include <GUIConstants.au3>
  3. #include <GDIPlus.au3>
  4. #include <WinAPI.au3>
  5. #include "VectorMath.au3"
  6. #include <Array.au3>
  7. #include <Misc.au3>
  8.  
  9. ; - Author: name22 (www.autoit.de)
  10.  
  11. Opt("GUIOnEventMode", 1)
  12.  
  13. ;###-v-SETTINGS-v-###
  14.  
  15. $iGUIWidth = 600
  16. $iGUIHeight = 400
  17. $iARGB_BG = 0xFFFFFFFF
  18. $nFPS = 50
  19.  
  20. $iCircles = 5
  21. $nSlowMotion = 10
  22.  
  23. $nFriction = 1
  24. $nGravity = 0
  25.  
  26. ;###-^-SETTINGS-^-###
  27.  
  28. $nSleepTime = 1000 / $nFPS
  29.  
  30. $nTimeMod = 1
  31. $nFPS_Display = 0
  32.  
  33. $vNTdll = DllOpen("ntdll.dll")
  34. $vUser32Dll = DllOpen("User32.dll")
  35.  
  36. $tPrecSleep = DllStructCreate("int64 time;")
  37. $pPrecSleep = DllStructGetPtr($tPrecSleep)
  38.  
  39. $hMain = GUICreate("Example by name22", $iGUIWidth, $iGUIHeight)
  40. GUISetState()
  41.  
  42. $hDC_Main = _WinAPI_GetDC($hMain)
  43. $hDC_Buffer = _WinAPI_CreateCompatibleDC($hDC_Main)
  44. $hBitmap_Buffer = _WinAPI_CreateCompatibleBitmap($hDC_Main, $iGUIWidth, $iGUIHeight)
  45. _WinAPI_SelectObject($hDC_Buffer, $hBitmap_Buffer)
  46.  
  47. _GDIPlus_Startup()
  48.  
  49. $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer)
  50. _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
  51.  
  52. $hBrush_Black = _GDIPlus_BrushCreateSolid(0xFF000000)
  53.  
  54. $hStringFormat = _GDIPlus_StringFormatCreate()
  55. $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial")
  56. $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 6)
  57. $hFont_Number = _GDIPlus_FontCreate($hFamily_FPS, 10)
  58.  
  59. $aMeasure = _GDIPlus_GraphicsMeasureString($hGraphics, "FPS: 000", $hFont_FPS, _GDIPlus_RectFCreate(), $hStringFormat)
  60. $tLayout_FPS = $aMeasure[0]
  61. $aMeasure = ""
  62. DllStructSetData($tLayout_FPS, "X", $iGUIWidth - DllStructGetData($tLayout_FPS, "Width") - 3)
  63. DllStructSetData($tLayout_FPS, "Y", $iGUIHeight - DllStructGetData($tLayout_FPS, "Height"))
  64. DllStructSetData($tLayout_FPS, "Width", DllStructGetData($tLayout_FPS, "Width") + 3)
  65.  
  66. $tLayout_Number = _GDIPlus_RectFCreate()
  67.  
  68. Global $aCircles[$iCircles + 1][6] = [[$iCircles]]
  69.  
  70. For $i = 1 To $aCircles[0][0]
  71.     $aCircles[$i][4] = Random(10, 20, 1) ;Circle Radius/Mass
  72.     $aCircles[$i][0] = Random($aCircles[$i][4], $iGUIWidth - $aCircles[$i][4], 1) ;X-Position of Circle Center
  73.     $aCircles[$i][1] = Random($aCircles[$i][4], $iGUIHeight - $aCircles[$i][4], 1) ;Y-Position of Circle Center
  74.     $aCircles[$i][2] = Random(-1, 1) ;X-Velocity
  75.     $aCircles[$i][3] = Random(-1, 1) ;Y-Velocity
  76.     $nRandomSpeed = Random(100, 200, 1) * -1 ^ Random(1, 2, 1)
  77.     $aCircles[$i][2] = $aCircles[$i][2] * $nRandomSpeed
  78.     $aCircles[$i][3] = $aCircles[$i][3] * $nRandomSpeed
  79.     $aCircles[$i][5] = _GDIPlus_BrushCreateSolid("0xFF" & Hex(Random(0x000000, 0xFFFFFF, 1), 6)) ;Brush
  80. Next
  81.  
  82. GUISetOnEvent($GUI_EVENT_CLOSE, "_Close", $hMain)
  83. OnAutoItExitRegister("_Shutdown")
  84. HotKeySet("i", "_DisplayInfo")
  85.  
  86. $nT_Sleep = TimerInit() + $nSleepTime
  87. $nT_UpdateFPS = TimerInit()
  88. While True
  89.     DllStructSetData($tPrecSleep, "time", -10000 * ($nSleepTime - TimerDiff($nT_Sleep)))
  90.     DllCall($vNTdll, "dword", "ZwDelayExecution", "int", 0, "ptr", $pPrecSleep)
  91.     $nFrameTime = TimerDiff($nT_Sleep)
  92.     $nT_Sleep = TimerInit()
  93.  
  94.     $nFPS_Cur = 1000 / $nFrameTime
  95.     If TimerDiff($nT_UpdateFPS) >= 500 Then
  96.         $nFPS_Display = $nFPS_Cur
  97.         $nT_UpdateFPS = TimerInit()
  98.     EndIf
  99.  
  100.     Switch _IsPressed("20", $vUser32Dll)
  101.         Case True
  102.             $nTimeMod = $nSlowMotion
  103.         Case False
  104.             If $nTimeMod <> 1 Then $nTimeMod = 1
  105.     EndSwitch
  106.  
  107.  
  108.     $nFPS_Cur *= $nTimeMod
  109.  
  110.     _GDIPlus_GraphicsClear($hGraphics, $iARGB_BG)
  111.  
  112.     For $i1 = 1 To $aCircles[0][0]
  113.         $aCircles[$i1][3] += $nGravity / $nFPS_Cur
  114.         $aCircles[$i1][2] *= $nFriction
  115.         $aCircles[$i1][3] *= $nFriction
  116.  
  117.         $aCircles[$i1][0] += $aCircles[$i1][2] / $nFPS_Cur
  118.         $aCircles[$i1][1] += $aCircles[$i1][3] / $nFPS_Cur
  119.  
  120.         _GDIPlus_GraphicsFillEllipse($hGraphics, $aCircles[$i1][0] - $aCircles[$i1][4], $aCircles[$i1][1] - $aCircles[$i1][4], $aCircles[$i1][4] * 2, $aCircles[$i1][4] * 2, $aCircles[$i1][5])
  121.         DllStructSetData($tLayout_Number, "X", $aCircles[$i1][0] - 5)
  122.         DllStructSetData($tLayout_Number, "Y", $aCircles[$i1][1] - 8)
  123.         _GDIPlus_GraphicsDrawStringEx($hGraphics, $i1, $hFont_Number, $tLayout_Number, $hStringFormat, $hBrush_Black)
  124.  
  125.         For $i2 = $i1 + 1 To $aCircles[0][0]
  126.             Switch ($aCircles[$i1][0] - $aCircles[$i2][0]) ^ 2 + ($aCircles[$i1][1] - $aCircles[$i2][1]) ^ 2 <= ($aCircles[$i1][4] + $aCircles[$i2][4]) ^ 2
  127.                 Case True
  128.                     $aCircles[$i1][0] -= $aCircles[$i1][2] / $nFPS_Cur
  129.                     $aCircles[$i1][1] -= $aCircles[$i1][3] / $nFPS_Cur
  130.                     $aCircles[$i2][0] -= $aCircles[$i2][2] / $nFPS_Cur
  131.                     $aCircles[$i2][1] -= $aCircles[$i2][3] / $nFPS_Cur
  132.  
  133.                     $nQ = _Circle_FixCircle_GetCollisionPointRatio($aCircles[$i1][0], $aCircles[$i1][1], $aCircles[$i2][0], $aCircles[$i2][1], $aCircles[$i1][4], $aCircles[$i2][4], ($aCircles[$i1][2] - $aCircles[$i2][2]), ($aCircles[$i1][3] - $aCircles[$i2][3]))
  134.                     $aCircles[$i1][0] += $aCircles[$i1][2] * $nQ
  135.                     $aCircles[$i1][1] += $aCircles[$i1][3] * $nQ
  136.                     $aCircles[$i2][0] += $aCircles[$i2][2] * $nQ
  137.                     $aCircles[$i2][1] += $aCircles[$i2][3] * $nQ
  138.  
  139.                     $nX_UN = $aCircles[$i1][0] - $aCircles[$i2][0]
  140.                     $nY_UN = $aCircles[$i1][1] - $aCircles[$i2][1]
  141.                     $nL_UN = Sqrt($nX_UN ^ 2 + $nY_UN ^ 2)
  142.                     $nX_UN = $nX_UN / $nL_UN
  143.                     $nY_UN = $nY_UN / $nL_UN
  144.  
  145.                     $nX_UT = -$nY_UN
  146.                     $nY_UT = $nX_UN
  147.  
  148.                     $nVel1_N = $nX_UN * $aCircles[$i1][2] + $nY_UN * $aCircles[$i1][3]
  149.                     $nVel2_N = $nX_UN * $aCircles[$i2][2] + $nY_UN * $aCircles[$i2][3]
  150.                     $nVel1_T = $nX_UT * $aCircles[$i1][2] + $nY_UT * $aCircles[$i1][3]
  151.                     $nVel2_T = $nX_UT * $aCircles[$i2][2] + $nY_UT * $aCircles[$i2][3]
  152.  
  153.                     $nVel1_N_New = ($nVel1_N * ($aCircles[$i1][4] - $aCircles[$i2][4]) + 2 * $aCircles[$i2][4] * $nVel2_N) / ($aCircles[$i1][4] + $aCircles[$i2][4])
  154.                     $nVel2_N_New = ($nVel2_N * ($aCircles[$i2][4] - $aCircles[$i1][4]) + 2 * $aCircles[$i1][4] * $nVel1_N) / ($aCircles[$i1][4] + $aCircles[$i2][4])
  155.  
  156.                     $aCircles[$i1][2] = $nVel1_N_New * $nX_UN + $nVel1_T * $nX_UT
  157.                     $aCircles[$i1][3] = $nVel1_N_New * $nY_UN + $nVel1_T * $nY_UT
  158.                     $aCircles[$i2][2] = $nVel2_N_New * $nX_UN + $nVel2_T * $nX_UT
  159.                     $aCircles[$i2][3] = $nVel2_N_New * $nY_UN + $nVel2_T * $nY_UT
  160.             EndSwitch
  161.         Next
  162.         Switch True
  163.             Case $aCircles[$i1][0] <= $aCircles[$i1][4] And $aCircles[$i1][2] < 0
  164.                 $aCircles[$i1][2] *= -1
  165.                 $aCircles[$i1][0] = $aCircles[$i1][4]
  166.             Case $aCircles[$i1][0] >= $iGUIWidth - $aCircles[$i1][4] And $aCircles[$i1][2] > 0
  167.                 $aCircles[$i1][2] *= -1
  168.                 $aCircles[$i1][0] = $iGUIWidth - $aCircles[$i1][4]
  169.         EndSwitch
  170.         Switch True
  171.             Case $aCircles[$i1][1] <= $aCircles[$i1][4] And $aCircles[$i1][3] < 0
  172.                 $aCircles[$i1][3] *= -1
  173.                 $aCircles[$i1][1] = $aCircles[$i1][4]
  174.             Case $aCircles[$i1][1] >= $iGUIHeight - $aCircles[$i1][4] And $aCircles[$i1][3] > 0
  175.                 $aCircles[$i1][3] *= -1
  176.                 $aCircles[$i1][1] = $iGUIHeight - $aCircles[$i1][4]
  177.         EndSwitch
  178.     Next
  179.  
  180.     _GDIPlus_GraphicsDrawStringEx($hGraphics, "FPS: " & Round($nFPS_Display, 1), $hFont_FPS, $tLayout_FPS, $hStringFormat, $hBrush_Black)
  181.     _WinAPI_BitBlt($hDC_Main, 0, 0, $iGUIWidth, $iGUIHeight, $hDC_Buffer, 0, 0, $SRCCOPY)
  182. WEnd
  183.  
  184. Func _Circle_FixCircle_GetCollisionPointRatio($nX_CirclePos, $nY_CirclePos, $nX_FixCirclePos, $nY_FixCirclePos, $nRadiusCircle, $nRadiusFixCircle, $nX_CircleVel, $nY_CircleVel)
  185.     $nVectorLength = Sqrt($nX_CircleVel ^ 2 + $nY_CircleVel ^ 2)
  186.     $nX_CircleDir = $nX_CircleVel / $nVectorLength
  187.     $nY_CircleDir = $nY_CircleVel / $nVectorLength
  188.  
  189.     $nD = Abs(($nX_FixCirclePos - $nX_CirclePos) * $nX_CircleDir + ($nY_FixCirclePos - $nY_CirclePos) * $nY_CircleDir)
  190.     $nDistance = $nD - Sqrt(($nRadiusCircle + $nRadiusFixCircle) ^ 2 - (($nX_FixCirclePos - $nX_CirclePos) ^ 2 + ($nY_FixCirclePos - $nY_CirclePos) ^ 2 - $nD ^ 2))
  191.  
  192.     Return $nDistance / $nVectorLength
  193. EndFunc
  194.  
  195. Func _DisplayInfo()
  196.     $nTmp = TimerDiff($nT_Sleep)
  197.     _ArrayDisplay($aCircles)
  198.     $nT_Sleep = TimerInit() - $nTmp
  199. EndFunc
  200.  
  201. Func _Close()
  202.     Exit
  203. EndFunc
  204.  
  205. Func _Shutdown()
  206.     _WinAPI_ReleaseDC($hMain, $hDC_Main)
  207.     _WinAPI_DeleteDC($hDC_Buffer)
  208.     _WinAPI_DeleteObject($hBitmap_Buffer)
  209.  
  210.     _GDIPlus_GraphicsDispose($hGraphics)
  211.     _GDIPlus_BrushDispose($hBrush_Black)
  212.     For $i = 1 To $aCircles[0][0]
  213.         _GDIPlus_BrushDispose($aCircles[$i][5])
  214.     Next
  215.     _GDIPlus_StringFormatDispose($hStringFormat)
  216.     _GDIPlus_FontFamilyDispose($hFamily_FPS)
  217.     _GDIPlus_FontDispose($hFont_FPS)
  218.     _GDIPlus_Shutdown()
  219.  
  220.     DllClose($vNTdll)
  221.     DllClose($vUser32Dll)
  222. EndFunc
  223.  
  224.  
  225. ; #FUNCTION#;===============================================================================
  226. ;
  227. ; Name...........: _HighPrecisionSleep()
  228. ; Description ...: Sleeps down to 0.1 microseconds
  229. ; Syntax.........: _HighPrecisionSleep( $iMicroSeconds, $hDll=False)
  230. ; Parameters ....:  $iMicroSeconds      - Amount of microseconds to sleep
  231. ;                  $hDll  - Can be supplied so the UDF doesn't have to re-open the dll all the time.
  232. ; Return values .: None
  233. ; Author ........: Andreas Karlsson (monoceres)
  234. ; Modified.......:
  235. ; Remarks .......: Even though this has high precision you need to take into consideration that it will take some time for autoit to call the function.
  236. ; Related .......:
  237. ; Link ..........;
  238. ; Example .......; No
  239. ;
  240. ;;==========================================================================================
  241. Func _HighPrecisionSleep($iMicroSeconds,$hDll=False)
  242.     Local $hStruct, $bLoaded
  243.     If Not $hDll Then
  244.         $hDll=DllOpen("ntdll.dll")
  245.         $bLoaded=True
  246.     EndIf
  247.     $hStruct=DllStructCreate("int64 time;")
  248.     DllStructSetData($hStruct,"time",-1*($iMicroSeconds*10))
  249.     DllCall($hDll,"dword","ZwDelayExecution","int",0,"ptr",DllStructGetPtr($hStruct))
  250.     If $bLoaded Then DllClose($hDll)
  251. EndFunc
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×