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

Dynamic/Static Circle Collision

By: name22 on Jun 29th, 2011  |  syntax: AutoIt  |  size: 8.67 KB  |  hits: 87  |  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.  
  6. ; - Author: name22 (www.autoit.de)
  7.  
  8. Opt("GUIOnEventMode", 1)
  9.  
  10. ;###-v-SETTINGS-v-###
  11.  
  12. $iGUIWidth = 400
  13. $iGUIHeight = 400
  14. $iARGB_BG = 0xFFFFFFFF
  15. $nFPS = 60
  16.  
  17. $nGravity = 10
  18. $nAirFriction = 0.99
  19. $nGroundFriction = 0.99
  20. $nBounciness = 0.6
  21.  
  22. $nAccellForce = 5
  23.  
  24. $nX_CirclePos = $iGUIWidth / 2
  25. $nY_CirclePos = 10
  26. $nX_CircleVel = 0
  27. $nY_CircleVel = 0
  28.  
  29. $nX_FixPoint = $iGUIWidth / 2
  30. $nY_FixPoint = $iGUIHeight
  31.  
  32. $nRadiusCircle = 10
  33. $nRadiusFixCircle = 250
  34.  
  35. ;###-^-SETTINGS-^-###
  36.  
  37. $bContact = True
  38. $bMouseDown = False
  39. $nX_NewVel = 0
  40. $nY_NewVel = 0
  41.  
  42. $nSleepTime = 1000 / $nFPS
  43.  
  44. $nFPS_Display = 0
  45. $nFPS_Average = $nFPS
  46.  
  47. $vNTdll = DllOpen("ntdll.dll")
  48.  
  49. $tPrecSleep = DllStructCreate("int64 time;")
  50. $pPrecSleep = DllStructGetPtr($tPrecSleep)
  51.  
  52. $hMain = GUICreate("Example by name22", $iGUIWidth, $iGUIHeight)
  53. GUISetState()
  54.  
  55. $hDC_Main = _WinAPI_GetDC($hMain)
  56. $hDC_Buffer = _WinAPI_CreateCompatibleDC($hDC_Main)
  57. $hBitmap_Buffer = _WinAPI_CreateCompatibleBitmap($hDC_Main, $iGUIWidth, $iGUIHeight)
  58. _WinAPI_SelectObject($hDC_Buffer, $hBitmap_Buffer)
  59.  
  60. _GDIPlus_Startup()
  61.  
  62. $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer)
  63. _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
  64.  
  65. $hBrush_Black = _GDIPlus_BrushCreateSolid(0xFF000000)
  66. $hBrush_Circle = _GDIPlus_BrushCreateSolid(0xFFFF0000)
  67.  
  68. $hPen_Circle = _GDIPlus_PenCreate(0xFF0000FF, 2)
  69. $hPen_NewVel = _GDIPlus_PenCreate(0xF000FF00, 5)
  70. _GDIPlus_PenSetEndCap($hPen_NewVel, $GDIP_LINECAPARROWANCHOR)
  71.  
  72. $hStringFormat = _GDIPlus_StringFormatCreate()
  73. $hFamily_FPS = _GDIPlus_FontFamilyCreate("Visitor TT1 BRK")
  74. $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 7)
  75.  
  76. $aMeasure = _GDIPlus_GraphicsMeasureString($hGraphics, "FPS: 000", $hFont_FPS, _GDIPlus_RectFCreate(), $hStringFormat)
  77. $tLayout_FPS = $aMeasure[0]
  78. $aMeasure = ""
  79. DllStructSetData($tLayout_FPS, "X", $iGUIWidth - DllStructGetData($tLayout_FPS, "Width") - 3)
  80. DllStructSetData($tLayout_FPS, "Y", $iGUIHeight - DllStructGetData($tLayout_FPS, "Height"))
  81. DllStructSetData($tLayout_FPS, "Width", DllStructGetData($tLayout_FPS, "Width") + 3)
  82.  
  83. GUISetOnEvent($GUI_EVENT_CLOSE, "_Close", $hMain)
  84. OnAutoItExitRegister("_Shutdown")
  85.  
  86. $nT_Sleep = TimerInit() + $nSleepTime
  87. $nT_UpdateFPS = TimerInit()
  88. $nT_AdjustSleepTime = TimerInit()
  89. While True
  90.         DllStructSetData($tPrecSleep, "time", -10000 * ($nSleepTime - TimerDiff($nT_Sleep)))
  91.         DllCall($vNTdll, "dword", "ZwDelayExecution", "int", 0, "ptr", $pPrecSleep)
  92.         $nFrameTime = TimerDiff($nT_Sleep)
  93.         $nT_Sleep = TimerInit()
  94.  
  95.         $nFPS_Cur = 1000 / $nFrameTime
  96.         If TimerDiff($nT_UpdateFPS) >= 500 Then
  97.                 $nFPS_Display = $nFPS_Cur
  98.                 $nT_UpdateFPS = TimerInit()
  99.         EndIf
  100.         If TimerDiff($nT_AdjustSleepTime) >= 5000 Then
  101.                 $nFPS_Average = ($nFPS_Average + $nFPS_Cur) / 2
  102.                 If $nFPS_Average - $nFPS < -2 Then $nSleepTime += 0.02
  103.                 If $nFPS_Average - $nFPS < 2 Then $nSleepTime -= 0.02
  104.                 $nT_AdjustSleepTime = TimerInit()
  105.         EndIf
  106.  
  107.         $aCursorInfo = GUIGetCursorInfo($hMain)
  108.  
  109.         _GDIPlus_GraphicsClear($hGraphics, $iARGB_BG)
  110.  
  111.         Switch $aCursorInfo[2]
  112.                 Case True
  113.                         Switch $bMouseDown
  114.                                 Case True
  115.                                         $nX_NewVel = $aCursorInfo[0] - $nX_CirclePos
  116.                                         $nY_NewVel = $aCursorInfo[1] - $nY_CirclePos
  117.                                         _GDIPlus_GraphicsDrawLine($hGraphics, $nX_CirclePos, $nY_CirclePos, $nX_CirclePos + $nX_NewVel, $nY_CirclePos + $nY_NewVel, $hPen_NewVel)
  118.                                 Case False
  119.                                         GUISetCursor(16, 1, $hMain)
  120.                                         $bMouseDown = True
  121.                                         $nX_CirclePos = $aCursorInfo[0]
  122.                                         $nY_CirclePos = $aCursorInfo[1]
  123.                         EndSwitch
  124.                 Case False
  125.                         Switch $bMouseDown
  126.                                 Case True
  127.                                         GUISetCursor(2, 1, $hMain)
  128.                                         $bMouseDown = False
  129.                                         $nX_CircleVel = $nX_NewVel * $nAccellForce
  130.                                         $nY_CircleVel = $nY_NewVel * $nAccellForce
  131.                         EndSwitch
  132.  
  133.                         $nY_CircleVel += $nGravity
  134.                         $nX_CircleVel *= $nAirFriction
  135.                         $nY_CircleVel *= $nAirFriction
  136.  
  137.                         $nX_V = $nX_CircleVel / $nFPS_Cur
  138.                         $nY_V = $nY_CircleVel / $nFPS_Cur
  139.                         $nL_V = Sqrt($nX_V ^ 2 + $nY_V ^ 2)
  140.  
  141.  
  142.                         $nX_N = $nX_V / $nL_V
  143.                         $nY_N = $nY_V / $nL_V
  144.  
  145.                         $nX_C = $nX_FixPoint - $nX_CirclePos
  146.                         $nY_C = $nY_FixPoint - $nY_CirclePos
  147.                         $nL_C = Sqrt($nX_C ^ 2 + $nY_C ^ 2)
  148.  
  149.                         Switch $nL_V > 0
  150.                                 Case True
  151.                                         Switch $nL_C - ($nRadiusCircle + $nRadiusFixCircle) <= $nL_V
  152.                                                 Case True
  153.                                                         $nD = $nX_N * $nX_C + $nY_N * $nY_C
  154.                                                         Switch $nD >= 0
  155.                                                                 Case True
  156.                                                                         $nF = $nL_C ^ 2 - $nD ^ 2
  157.                                                                         Switch $nF <= ($nRadiusCircle + $nRadiusFixCircle) ^ 2
  158.                                                                                 Case True
  159.                                                                                         $nDistance = $nD - Sqrt(($nRadiusCircle + $nRadiusFixCircle) ^ 2 - $nF)
  160.                                                                                         Switch $nDistance <= $nL_V
  161.                                                                                                 Case True
  162.                                                                                                         $nX_CirclePos += $nX_N * $nDistance
  163.                                                                                                         $nY_CirclePos += $nY_N * $nDistance
  164.  
  165.                                                                                                         $nX_C = $nX_FixPoint - $nX_CirclePos
  166.                                                                                                         $nY_C = $nY_FixPoint - $nY_CirclePos
  167.                                                                                                         $nL_C = Sqrt($nX_C ^ 2 + $nY_C ^ 2)
  168.  
  169.                                                                                                         $nX_UN = $nX_C / $nL_C
  170.                                                                                                         $nY_UN = $nY_C / $nL_C
  171.  
  172.                                                                                                         $nVel_N = ($nX_UN * $nX_CircleVel + $nY_UN * $nY_CircleVel) * $nBounciness
  173.                                                                                                         $nVel_T = (-$nY_UN * $nX_CircleVel + $nX_UN * $nY_CircleVel) * $nGroundFriction
  174.  
  175.                                                                                                         $nX_CircleVel = -$nVel_N * $nX_UN + $nVel_T * - $nY_UN
  176.                                                                                                         $nY_CircleVel = -$nVel_N * $nY_UN + $nVel_T * $nX_UN
  177.                                                                                         EndSwitch
  178.                                                                         EndSwitch
  179.                                                         EndSwitch
  180.                                         EndSwitch
  181.                         EndSwitch
  182.                         Switch True
  183.                                 Case $nX_CirclePos + $nX_CircleVel / $nFPS_Cur <= $nRadiusCircle
  184.                                         $nX_CircleVel *= -$nBounciness
  185.                                         $nY_CircleVel *= $nGroundFriction
  186.                                         $nX_CirclePos = $nRadiusCircle
  187.                                 Case $nX_CirclePos + $nX_CircleVel / $nFPS_Cur >= $iGUIWidth - $nRadiusCircle
  188.                                         $nX_CircleVel *= -$nBounciness
  189.                                         $nY_CircleVel *= $nGroundFriction
  190.                                         $nX_CirclePos = $iGUIWidth - $nRadiusCircle
  191.                         EndSwitch
  192.                         Switch True
  193.                                 Case $nY_CirclePos + $nY_CircleVel / $nFPS_Cur <= $nRadiusCircle
  194.                                         $nY_CircleVel *= -$nBounciness
  195.                                         $nX_CircleVel *= $nGroundFriction
  196.                                         $nY_CirclePos = $nRadiusCircle
  197.                                 Case $nY_CirclePos + $nY_CircleVel / $nFPS_Cur >= $iGUIHeight - $nRadiusCircle
  198.                                         $nY_CircleVel *= -$nBounciness
  199.                                         $nX_CircleVel *= $nGroundFriction
  200.                                         $nY_CirclePos = $iGUIHeight - $nRadiusCircle
  201.                         EndSwitch
  202.  
  203.                         $nX_CirclePos += $nX_CircleVel / $nFPS_Cur
  204.                         $nY_CirclePos += $nY_CircleVel / $nFPS_Cur
  205.         EndSwitch
  206.  
  207.         _GDIPlus_GraphicsFillEllipse($hGraphics, $nX_CirclePos - $nRadiusCircle, $nY_CirclePos - $nRadiusCircle, $nRadiusCircle * 2, $nRadiusCircle * 2, $hBrush_Circle)
  208.         _GDIPlus_GraphicsDrawEllipse($hGraphics, $nX_FixPoint - $nRadiusFixCircle, $nY_FixPoint - $nRadiusFixCircle, $nRadiusFixCircle * 2, $nRadiusFixCircle * 2, $hPen_Circle)
  209.         _GDIPlus_GraphicsDrawStringEx($hGraphics, "FPS: " & Int($nFPS_Display), $hFont_FPS, $tLayout_FPS, $hStringFormat, $hBrush_Black)
  210.         _WinAPI_BitBlt($hDC_Main, 0, 0, $iGUIWidth, $iGUIHeight, $hDC_Buffer, 0, 0, $SRCCOPY)
  211. WEnd
  212.  
  213. Func _Close()
  214.         Exit
  215. EndFunc   ;==>_Close
  216.  
  217. Func _Shutdown()
  218.         _WinAPI_ReleaseDC($hMain, $hDC_Main)
  219.         _WinAPI_DeleteDC($hDC_Buffer)
  220.         _WinAPI_DeleteObject($hBitmap_Buffer)
  221.  
  222.         _GDIPlus_GraphicsDispose($hGraphics)
  223.         _GDIPlus_BrushDispose($hBrush_Black)
  224.         _GDIPlus_BrushDispose($hBrush_Circle)
  225.         _GDIPlus_PenDispose($hPen_Circle)
  226.         _GDIPlus_PenDispose($hPen_NewVel)
  227.         _GDIPlus_StringFormatDispose($hStringFormat)
  228.         _GDIPlus_FontFamilyDispose($hFamily_FPS)
  229.         _GDIPlus_FontDispose($hFont_FPS)
  230.         _GDIPlus_Shutdown()
  231.  
  232.         DllClose($vNTdll)
  233. EndFunc   ;==>_Shutdown
  234.  
  235. ;- Copyright: name22, Donnerstag 12. Mai 2011
  236.  
  237.  
  238. ; #FUNCTION#;===============================================================================
  239. ;
  240. ; Name...........: _HighPrecisionSleep()
  241. ; Description ...: Sleeps down to 0.1 microseconds
  242. ; Syntax.........: _HighPrecisionSleep( $iMicroSeconds, $hDll=False)
  243. ; Parameters ....:  $iMicroSeconds      - Amount of microseconds to sleep
  244. ;                  $hDll  - Can be supplied so the UDF doesn't have to re-open the dll all the time.
  245. ; Return values .: None
  246. ; Author ........: Andreas Karlsson (monoceres)
  247. ; Modified.......:
  248. ; 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.
  249. ; Related .......:
  250. ; Link ..........;
  251. ; Example .......; No
  252. ;
  253. ;;==========================================================================================
  254. Func _HighPrecisionSleep($iMicroSeconds, $hDll = False)
  255.         Local $hStruct, $bLoaded
  256.         If Not $hDll Then
  257.                 $hDll = DllOpen("ntdll.dll")
  258.                 $bLoaded = True
  259.         EndIf
  260.         $hStruct = DllStructCreate("int64 time;")
  261.         DllStructSetData($hStruct, "time", -1 * ($iMicroSeconds * 10))
  262.         DllCall($hDll, "dword", "ZwDelayExecution", "int", 0, "ptr", DllStructGetPtr($hStruct))
  263.         If $bLoaded Then DllClose($hDll)
  264. EndFunc   ;==>_HighPrecisionSleep