Don't like ads? PRO users don't see any ads ;-)

Circle Collision v2.0

By: name22 on Jun 29th, 2011  |  syntax: AutoIt  |  size: 9.40 KB  |  hits: 134  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <WindowsConstants.au3>
  2. #include <GUIConstants.au3>
  3. #include <GDIPlus.au3>
  4. #include <WinAPI.au3>
  5. #include <Misc.au3>
  6.  
  7. ; - Author: name22 (www.autoit.de)
  8.  
  9. Opt("GUIOnEventMode", 1)
  10.  
  11. ;###-v-SETTINGS-v-###
  12.  
  13. $iGUIWidth = 600
  14. $iGUIHeight = 400
  15. $iARGB_BG = 0xFFFFFFFF
  16. $nFPS = 60
  17.  
  18. $nGravity = 0
  19. $nAirFriction = 1
  20. $nGroundFriction = 1
  21. $nBounciness = 1
  22.  
  23. $iCircles = 10
  24. $nSlowMotion = 10
  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("Physics Engine", $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_Copyright = _GDIPlus_FontCreate($hFamily_FPS, 8)
  58. $hFont_Number = _GDIPlus_FontCreate($hFamily_FPS, 10)
  59.  
  60. $aMeasure = _GDIPlus_GraphicsMeasureString($hGraphics, "FPS: 000", $hFont_FPS, _GDIPlus_RectFCreate(), $hStringFormat)
  61. $tLayout_FPS = $aMeasure[0]
  62. $aMeasure = ""
  63. DllStructSetData($tLayout_FPS, "X", $iGUIWidth - DllStructGetData($tLayout_FPS, "Width") - 3)
  64. DllStructSetData($tLayout_FPS, "Y", $iGUIHeight - DllStructGetData($tLayout_FPS, "Height"))
  65. DllStructSetData($tLayout_FPS, "Width", 0)
  66.  
  67. $tLayout_Copyright = _GDIPlus_RectFCreate(0, $iGUIHeight - 15)
  68.  
  69. Global $aCircles[$iCircles + 1][6] = [[$iCircles]]
  70.  
  71. For $i = 1 To $aCircles[0][0]
  72.         $aCircles[$i][4] = Random(10, 20, 1) ;Circle Radius/Mass
  73.         $aCircles[$i][0] = Random($aCircles[$i][4], $iGUIWidth - $aCircles[$i][4], 1) ;X-Position of Circle Center
  74.         $aCircles[$i][1] = Random($aCircles[$i][4], $iGUIHeight - $aCircles[$i][4], 1) ;Y-Position of Circle Center
  75.         $aCircles[$i][2] = Random(-1, 1) ;X-Velocity
  76.         $aCircles[$i][3] = Random(-1, 1) ;Y-Velocity
  77.         $nRandomSpeed = Random(200, 400, 1) * - 1 ^ Random(1, 2, 1)
  78.         $aCircles[$i][2] = $aCircles[$i][2] * $nRandomSpeed
  79.         $aCircles[$i][3] = $aCircles[$i][3] * $nRandomSpeed
  80.         $aCircles[$i][5] = _GDIPlus_BrushCreateSolid("0xFF" & Hex(Random(0x000000, 0xFFFFFF, 1), 6)) ;Brush
  81. Next
  82.  
  83. GUISetOnEvent($GUI_EVENT_CLOSE, "_Close", $hMain)
  84. OnAutoItExitRegister("_Shutdown")
  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.         $nFPS_Cur *= $nTimeMod
  108.  
  109.         _GDIPlus_GraphicsClear($hGraphics, $iARGB_BG)
  110.  
  111.         For $i1 = 1 To $aCircles[0][0]
  112.  
  113.                 $aCircles[$i1][3] += $nGravity
  114.                 $aCircles[$i1][2] *= $nAirFriction
  115.                 $aCircles[$i1][3] *= $nAirFriction
  116.  
  117.                 Switch True
  118.                         Case $aCircles[$i1][0] + $aCircles[$i1][2] / $nFPS_Cur <= $aCircles[$i1][4]
  119.                                 $aCircles[$i1][2] *= -$nBounciness
  120.                                 $aCircles[$i1][3] *= $nGroundFriction
  121.                                 $aCircles[$i1][0] = $aCircles[$i1][4]
  122.                         Case $aCircles[$i1][0] + $aCircles[$i1][2] / $nFPS_Cur >= $iGUIWidth - $aCircles[$i1][4]
  123.                                 $aCircles[$i1][2] *= -$nBounciness
  124.                                 $aCircles[$i1][3] *= $nGroundFriction
  125.                                 $aCircles[$i1][0] = $iGUIWidth - $aCircles[$i1][4]
  126.                 EndSwitch
  127.                 Switch True
  128.                         Case $aCircles[$i1][1] + $aCircles[$i1][3] / $nFPS_Cur <= $aCircles[$i1][4]
  129.                                 $aCircles[$i1][3] *= -$nBounciness
  130.                                 $aCircles[$i1][2] *= $nGroundFriction
  131.                                 $aCircles[$i1][1] = $aCircles[$i1][4]
  132.                         Case $aCircles[$i1][1] + $aCircles[$i1][3] / $nFPS_Cur >= $iGUIHeight - $aCircles[$i1][4]
  133.                                 $aCircles[$i1][3] *= -$nBounciness
  134.                                 $aCircles[$i1][2] *= $nGroundFriction
  135.                                 $aCircles[$i1][1] = $iGUIHeight - $aCircles[$i1][4]
  136.                 EndSwitch
  137.  
  138.                 For $i2 = $i1 + 1 To $aCircles[0][0]
  139.                         $nX_V = ($aCircles[$i1][2] - $aCircles[$i2][2]) / $nFPS_Cur
  140.                         $nY_V = ($aCircles[$i1][3] - $aCircles[$i2][3]) / $nFPS_Cur
  141.                         $nL_V = Sqrt($nX_V ^ 2 + $nY_V ^ 2)
  142.  
  143.                         $nX_N = $nX_V / $nL_V
  144.                         $nY_N = $nY_V / $nL_V
  145.  
  146.                         $nX_C = $aCircles[$i2][0] - $aCircles[$i1][0]
  147.                         $nY_C = $aCircles[$i2][1] - $aCircles[$i1][1]
  148.                         $nL_C = Sqrt($nX_C ^ 2 + $nY_C ^ 2)
  149.  
  150.                         Switch $nL_V > 0
  151.                                 Case True
  152.                                         Switch $nL_C - ($aCircles[$i1][4] + $aCircles[$i2][4]) <= $nL_V
  153.                                                 Case True
  154.                                                         $nD = $nX_N * $nX_C + $nY_N * $nY_C
  155.                                                         Switch $nD >= 0
  156.                                                                 Case True
  157.                                                                         $nF = $nL_C ^ 2 - $nD ^ 2
  158.                                                                         Switch $nF <= ($aCircles[$i1][4] + $aCircles[$i2][4]) ^ 2
  159.                                                                                 Case True
  160.                                                                                         $nDistance = $nD - Sqrt(($aCircles[$i1][4] + $aCircles[$i2][4]) ^ 2 - $nF)
  161.                                                                                         Switch $nDistance <= $nL_V
  162.                                                                                                 Case True
  163.                                                                                                         $nQ = $nDistance / $nL_V
  164.  
  165.                                                                                                         $aCircles[$i1][0] += $aCircles[$i1][2] / $nFPS_Cur * $nQ
  166.                                                                                                         $aCircles[$i1][1] += $aCircles[$i1][3] / $nFPS_Cur * $nQ
  167.                                                                                                         $aCircles[$i2][0] += $aCircles[$i2][2] / $nFPS_Cur * $nQ
  168.                                                                                                         $aCircles[$i2][1] += $aCircles[$i2][3] / $nFPS_Cur * $nQ
  169.  
  170.                                                                                                         $nX_C = $aCircles[$i2][0] - $aCircles[$i1][0]
  171.                                                                                                         $nY_C = $aCircles[$i2][1] - $aCircles[$i1][1]
  172.                                                                                                         $nL_C = Sqrt($nX_C ^ 2 + $nY_C ^ 2)
  173.  
  174.                                                                                                         $nX_UN = $nX_C / $nL_C
  175.                                                                                                         $nY_UN = $nY_C / $nL_C
  176.  
  177.                                                                                                         $nVel1_N = ($nX_UN * $aCircles[$i1][2] + $nY_UN * $aCircles[$i1][3]) * $nBounciness
  178.                                                                                                         $nVel2_N = ($nX_UN * $aCircles[$i2][2] + $nY_UN * $aCircles[$i2][3]) * $nBounciness
  179.                                                                                                         $nVel1_T = (-$nY_UN * $aCircles[$i1][2] + $nX_UN * $aCircles[$i1][3]) * $nGroundFriction
  180.                                                                                                         $nVel2_T = (-$nY_UN * $aCircles[$i2][2] + $nX_UN * $aCircles[$i2][3]) * $nGroundFriction
  181.  
  182.                                                                                                         $nVel1_N_New = ($nVel1_N * ($aCircles[$i1][4] - $aCircles[$i2][4]) + 2 * $aCircles[$i2][4] * $nVel2_N) / ($aCircles[$i1][4] + $aCircles[$i2][4])
  183.                                                                                                         $nVel2_N_New = ($nVel2_N * ($aCircles[$i2][4] - $aCircles[$i1][4]) + 2 * $aCircles[$i1][4] * $nVel1_N) / ($aCircles[$i1][4] + $aCircles[$i2][4])
  184.  
  185.                                                                                                         $aCircles[$i1][2] = $nVel1_N_New * $nX_UN + $nVel1_T * - $nY_UN
  186.                                                                                                         $aCircles[$i1][3] = $nVel1_N_New * $nY_UN + $nVel1_T * $nX_UN
  187.                                                                                                         $aCircles[$i2][2] = $nVel2_N_New * $nX_UN + $nVel2_T * - $nY_UN
  188.                                                                                                         $aCircles[$i2][3] = $nVel2_N_New * $nY_UN + $nVel2_T * $nX_UN
  189.                                                                                         EndSwitch
  190.                                                                         EndSwitch
  191.                                                         EndSwitch
  192.                                         EndSwitch
  193.                         EndSwitch
  194.                 Next
  195.  
  196.                 $aCircles[$i1][0] += $aCircles[$i1][2] / $nFPS_Cur
  197.                 $aCircles[$i1][1] += $aCircles[$i1][3] / $nFPS_Cur
  198.  
  199.                 _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])
  200.         Next
  201.  
  202.         _GDIPlus_GraphicsDrawStringEx($hGraphics, "FPS: " & Round($nFPS_Display, 1), $hFont_FPS, $tLayout_FPS, $hStringFormat, $hBrush_Black)
  203.         _GDIPlus_GraphicsDrawStringEx($hGraphics, "© name22", $hFont_Copyright, $tLayout_Copyright, $hStringFormat, $hBrush_Black)
  204.         _WinAPI_BitBlt($hDC_Main, 0, 0, $iGUIWidth, $iGUIHeight, $hDC_Buffer, 0, 0, $SRCCOPY)
  205. WEnd
  206.  
  207. Func _Close()
  208.         Exit
  209. EndFunc   ;==>_Close
  210.  
  211. Func _Shutdown()
  212.         _WinAPI_ReleaseDC($hMain, $hDC_Main)
  213.         _WinAPI_DeleteDC($hDC_Buffer)
  214.         _WinAPI_DeleteObject($hBitmap_Buffer)
  215.  
  216.         _GDIPlus_GraphicsDispose($hGraphics)
  217.         _GDIPlus_BrushDispose($hBrush_Black)
  218.         For $i = 1 To $aCircles[0][0]
  219.                 _GDIPlus_BrushDispose($aCircles[$i][5])
  220.         Next
  221.         _GDIPlus_StringFormatDispose($hStringFormat)
  222.         _GDIPlus_FontFamilyDispose($hFamily_FPS)
  223.         _GDIPlus_FontDispose($hFont_FPS)
  224.         _GDIPlus_Shutdown()
  225.  
  226.         DllClose($vNTdll)
  227.         DllClose($vUser32Dll)
  228. EndFunc   ;==>_Shutdown
  229.  
  230. ;- Copyright: name22, Donnerstag 12. Mai 2011
  231.  
  232.  
  233. ; #FUNCTION#;===============================================================================
  234. ;
  235. ; Name...........: _HighPrecisionSleep()
  236. ; Description ...: Sleeps down to 0.1 microseconds
  237. ; Syntax.........: _HighPrecisionSleep( $iMicroSeconds, $hDll=False)
  238. ; Parameters ....:  $iMicroSeconds      - Amount of microseconds to sleep
  239. ;                  $hDll  - Can be supplied so the UDF doesn't have to re-open the dll all the time.
  240. ; Return values .: None
  241. ; Author ........: Andreas Karlsson (monoceres)
  242. ; Modified.......:
  243. ; 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.
  244. ; Related .......:
  245. ; Link ..........;
  246. ; Example .......; No
  247. ;
  248. ;;==========================================================================================
  249. Func _HighPrecisionSleep($iMicroSeconds, $hDll = False)
  250.         Local $hStruct, $bLoaded
  251.         If Not $hDll Then
  252.                 $hDll = DllOpen("ntdll.dll")
  253.                 $bLoaded = True
  254.         EndIf
  255.         $hStruct = DllStructCreate("int64 time;")
  256.         DllStructSetData($hStruct, "time", -1 * ($iMicroSeconds * 10))
  257.         DllCall($hDll, "dword", "ZwDelayExecution", "int", 0, "ptr", DllStructGetPtr($hStruct))
  258.         If $bLoaded Then DllClose($hDll)
  259. EndFunc   ;==>_HighPrecisionSleep