#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GDIPlus.au3>
#include <misc.au3>

Opt("GUIOnEventMode", 1)

_GDIPlus_Startup()

Global $hBitmap, $hGraphic, $hBuffer

Global Const $iWidth = 400
Global Const $iHeight = 600
Global Const $iFriction = 0.98
Global Const $iGravitation = 0.1
Global Const $iBallSpeed = 15

Global $iPoints = "00"
Global $aAimVect[2]
Global $iAimDeg = 3.1415 * 0.1
Global $iDir = -1
Global $iPlayerMode = -1
Global $iPlayerTurn

Global $iRadius
Global $bAimMode = True
Global $aBall[5] ;X-Pos, Y-Pos, X-Vektor, Y-Vektor, Radius
Global $iBlocks = 0
Global $aBlock[5][20] ;X-Pos, Y-Pos, Radius, Pen, Level
Global $aHitColors[3] = [0xFF00FF00, 0xFFFFFF00, 0xFFFF0000]
Global $hPen_Size = _GDIPlus_PenCreate($aHitColors[0], 2)

Global $hBrush_String = _GDIPlus_BrushCreateSolid(0xFF00FA00)
Global $hFormat = _GDIPlus_StringFormatCreate()
Global $hFamily = _GDIPlus_FontFamilyCreate("impact")
Global $hFont_Points = _GDIPlus_FontCreate($hFamily, 8, 2)
Global $hFont_Menu = _GDIPlus_FontCreate($hFamily, 25, 2)
Global $tLayout_Points = _GDIPlus_RectFCreate($iWidth - 70, $iHeight - 20, 70, 20)
Global $tLayout_Menu_Single = _GDIPlus_RectFCreate($iWidth / 2 - 100, $iHeight / 4 - 20, 200, 40)
Global $tLayout_Menu_Multi = _GDIPlus_RectFCreate($iWidth / 2 - 100, ($iHeight / 4) * 3 - 20, 200, 40)
Global $aInfo_Points = _GDIPlus_GraphicsMeasureString($hGraphic, "Points: 00", $hFont_Points, $tLayout_Points, $hFormat)
Global $aInfo_Menu_Single = _GDIPlus_GraphicsMeasureString($hGraphic, "Singleplayer", $hFont_Menu, $tLayout_Menu_Single, $hFormat)
Global $aInfo_Menu_Multi = _GDIPlus_GraphicsMeasureString($hGraphic, "Multiplayer", $hFont_Menu, $tLayout_Menu_Multi, $hFormat)

Global $hBrush_White = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
Global $hPen_White = _GDIPlus_PenCreate(0xFFFFFFFF)

$hGui = GUICreate("Orbit-Shooter", $iWidth, $iHeight)
$Single = GUICtrlCreateLabel("", 0, 0, $iWidth, $iHeight / 2)
GUICtrlSetOnEvent($Single, "_Single")
$Multi = GUICtrlCreateLabel("", 0, $iHeight / 2, $iWidth, $iHeight / 2)
GUICtrlSetOnEvent($Multi, "_Multi")

GUISetState()
GUISetOnEvent(-3, "_Exit")

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphic)
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)

While $iPlayerMode < 0
	_GDIPlus_GraphicsClear($hBuffer, 0xFF000000)
	_GDIPlus_GraphicsDrawStringEx($hBuffer, "Singleplayer", $hFont_Menu, $tLayout_Menu_Single, $aInfo_Menu_Single[0], $hBrush_String)
	_GDIPlus_GraphicsDrawStringEx($hBuffer, "Multiplayer", $hFont_Menu, $tLayout_Menu_Multi, $aInfo_Menu_Multi[0], $hBrush_String)
	$aMouseInfo = GUIGetCursorInfo()
	If IsArray($aMouseInfo) Then
		Switch $aMouseInfo[4]
			Case $Single
				_GDIPlus_GraphicsDrawRect($hBuffer, 2, 2, $iWidth - 4, $iHeight / 2 - 4, $hPen_Size)
			Case $Multi
				_GDIPlus_GraphicsDrawRect($hBuffer, 2, $iHeight / 2 + 2, $iWidth - 4, $iHeight / 2 - 4, $hPen_Size)
		EndSwitch
	EndIf
	_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iWidth, $iHeight)
	Sleep(20)
WEnd

GUICtrlDelete($Single)
GUICtrlDelete($Multi)

Do
Until Not _IsPressed(01)

While True
	_GDIPlus_GraphicsClear($hBuffer, 0xFF000000)
	If $bAimMode Then
		$aAimVect[0] = Cos($iAimDeg) * $iBallSpeed
		$aAimVect[1] = Sin($iAimDeg) * $iBallSpeed
		If $iAimDeg <= 3.1415 * 0.1 Then
			$iDir *= -1
		EndIf
		If $iAimDeg >= 3.1415 * 0.9 Then
			$iDir *= -1
		EndIf
		If Abs($iAimDeg) = 360 Then $iAimDeg = 0
		If $iPlayerMode = 1 Then
			If $iPlayerTurn = 0 Then _GDIPlus_GraphicsDrawLine($hBuffer, $iWidth / 2 + $aAimVect[0] * 40 / $iBallSpeed, $iHeight - $aAimVect[1] * 40 / $iBallSpeed, $iWidth / 2 + $aAimVect[0] * 3, $iHeight - $aAimVect[1] * 3, $hPen_White)
			If $iPlayerTurn = 1 Then _GDIPlus_GraphicsDrawLine($hBuffer, $iWidth / 2 + $aAimVect[0] * 40 / $iBallSpeed, $aAimVect[1] * 40 / $iBallSpeed, $iWidth / 2 + $aAimVect[0] * 3, $aAimVect[1] * 3, $hPen_White)
		Else
			_GDIPlus_GraphicsDrawLine($hBuffer, $iWidth / 2 + $aAimVect[0] * 40 / $iBallSpeed, $iHeight - $aAimVect[1] * 40 / $iBallSpeed, $iWidth / 2 + $aAimVect[0] * 3, $iHeight - $aAimVect[1] * 3, $hPen_White)
		EndIf
		$iAimDeg += $iDir * 0.01
		If _IsPressed(01) Then
			$aBall[4] = 10
			$aBall[0] = $iWidth / 2 - $aBall[4] + (50 / $aAimVect[1]) * $aAimVect[0]
			If $iPlayerTurn = 0 Then
				$aBall[1] = $iHeight - $aBall[4] - 50
			Else
				$aBall[1] = $aBall[4] + 50
			EndIf
			$aBall[2] = $aAimVect[0]
			If $iPlayerTurn = 0 Then
				$aBall[3] = -$aAimVect[1]
			Else
				$aBall[3] = $aAimVect[1]
			EndIf
			$bAimMode = False
		EndIf
	EndIf
	If Not $bAimMode Then
		_CalcCollision()
		_CalcGravitation()
		$aBall[2] *= $iFriction
		$aBall[3] *= $iFriction
		$aBall[0] += $aBall[2]
		$aBall[1] += $aBall[3]
	EndIf
	_GDIPlus_GraphicsDrawLine($hBuffer, 0, $iHeight - 50, $iWidth, $iHeight - 50, $hPen_White)
	If $iPlayerMode = 1 Then _GDIPlus_GraphicsDrawLine($hBuffer, 0, 50, $iWidth, 50, $hPen_White)
	_GDIPlus_GraphicsDrawEllipse($hBuffer, $iWidth / 2 - 40, $iHeight - 40, 80, 80, $hPen_White)
	If $iPlayerMode = 1 Then _GDIPlus_GraphicsDrawEllipse($hBuffer, $iWidth / 2 - 40, -40, 80, 80, $hPen_White)
	If Not $bAimMode Then _GDIPlus_GraphicsFillEllipse($hBuffer, $aBall[0] - $aBall[4], $aBall[1] - $aBall[4], $aBall[4] * 2, $aBall[4] * 2, $hBrush_White)
	For $i = 0 To $iBlocks - 1
		_GDIPlus_GraphicsDrawEllipse($hBuffer, $aBlock[0][$i] - $aBlock[2][$i], $aBlock[1][$i] - $aBlock[2][$i], $aBlock[2][$i] * 2, $aBlock[2][$i] * 2, $aBlock[3][$i])
	Next
	If $iPlayerMode = 0 Then _GDIPlus_GraphicsDrawStringEx($hBuffer, "Points: " & $iPoints, $hFont_Points, $tLayout_Points, $aInfo_Points[0], $hBrush_String)
	_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iWidth, $iHeight)
	If (Not $bAimMode) And (Sqrt($aBall[2] ^ 2 + $aBall[3] ^ 2) < 0.5 Or ((($iPlayerTurn = 0) And ($aBall[1] > $iHeight - 50 - $aBall[4]))) Or (($iPlayerTurn = 1) And ($aBall[1] < 50 + $aBall[4]))) Then
		If ($iPlayerMode = 0) And ($aBall[1] > $iHeight - 50 - $aBall[4]) Then
			MsgBox(0, "Game Over", "Game over" & @CRLF & "You reached " & $iPoints & " Points.")
			Exit
		ElseIf ((($iPlayerTurn = 0) And ($aBall[1] > $iHeight - 50 - $aBall[4]))) Or (($iPlayerTurn = 1) And ($aBall[1] < 50 + $aBall[4])) Then
			MsgBox(0, "Game Over", "Player " & Mod($iPlayerTurn + 1, 2) + 1 & " has won the Game")
			Exit
		EndIf
		$iRadius = 1
		If $iPlayerMode = 1 Then $iPlayerTurn = Mod($iPlayerTurn + 1, 2)
		Do
			_GDIPlus_GraphicsClear($hBuffer, 0xFF000000)
			$iRadius += 1
			For $i = 0 To $iBlocks - 1
				If Sqrt(($aBlock[0][$i] - $aBall[0]) ^ 2 + ($aBlock[1][$i] - $aBall[1]) ^ 2) <= $iRadius + $aBlock[2][$i] Then ExitLoop 2
			Next
			_GDIPlus_GraphicsDrawLine($hBuffer, 0, $iHeight - 50, $iWidth, $iHeight - 50, $hPen_White)
			If $iPlayerMode = 1 Then _GDIPlus_GraphicsDrawLine($hBuffer, 0, 50, $iWidth, 50, $hPen_White)
			_GDIPlus_GraphicsDrawEllipse($hBuffer, $iWidth / 2 - 40, $iHeight - 40, 80, 80, $hPen_White)
			If $iPlayerMode = 1 Then _GDIPlus_GraphicsDrawEllipse($hBuffer, $iWidth / 2 - 40, -40, 80, 80, $hPen_White)
			_GDIPlus_GraphicsDrawEllipse($hBuffer, $aBall[0] - $iRadius, $aBall[1] - $iRadius, $iRadius * 2, $iRadius * 2, $hPen_Size)
			For $i = 0 To $iBlocks - 1
				_GDIPlus_GraphicsDrawEllipse($hBuffer, $aBlock[0][$i] - $aBlock[2][$i], $aBlock[1][$i] - $aBlock[2][$i], $aBlock[2][$i] * 2, $aBlock[2][$i] * 2, $aBlock[3][$i])
			Next
			If $iPlayerMode = 0 Then _GDIPlus_GraphicsDrawStringEx($hBuffer, "Points: " & $iPoints, $hFont_Points, $tLayout_Points, $aInfo_Points[0], $hBrush_String)
			_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iWidth, $iHeight)
		Until ($aBall[0] - $iRadius <= 0) Or ($aBall[0] + $iRadius >= $iWidth) Or ((($iPlayerMode = 0) And ($aBall[1] - $iRadius <= 0)) Or (($iPlayerMode = 1) And ($aBall[1] - $iRadius <= 50))) Or ($aBall[1] + $iRadius >= $iHeight - 50)
		$aBlock[0][$iBlocks] = $aBall[0]
		$aBlock[1][$iBlocks] = $aBall[1]
		$aBlock[2][$iBlocks] = $iRadius
		$aBlock[4][$iBlocks] = 3
		_GDIPlus_PenDispose($aBlock[3][$iBlocks])
		$aBlock[3][$iBlocks] = _GDIPlus_PenCreate($aHitColors[3 - $aBlock[4][$iBlocks]], 3)
		$iBlocks += 1
		$bAimMode = True
	EndIf
	Sleep(10)
WEnd

Func _CalcCollision()
	Local $aTangent[2] ;Vektor der Tangente
	Local $iVector_Scal
	$aBall[0] += $aBall[2]
	$aBall[1] += $aBall[3]
	Local $tmpVect[2] = [$aBall[2], $aBall[3]]
	If $aBall[0] <= $aBall[4] Or $aBall[0] >= $iWidth - $aBall[4] Then
		$aBall[2] *= -1
		Switch $aBall[0] < $iWidth / 2
			Case True
				$aBall[0] = $aBall[4]
			Case False
				$aBall[0] = $iWidth - $aBall[4]
		EndSwitch
	EndIf
	If $iPlayerTurn = 0 Then
		If $aBall[1] <= $aBall[4] + (50 * $iPlayerMode) Then
			$aBall[3] *= -1
			$aBall[1] = $aBall[4] + (50 * $iPlayerMode)
		EndIf
	Else
		If $aBall[1] >= $iHeight - 50 - $aBall[4] Then
			$aBall[3] *= -1
			$aBall[1] = $iHeight - 50 - $aBall[4]
		EndIf
	EndIf
	For $i = 0 To $iBlocks - 1
		If Sqrt(($aBall[0] - $aBlock[0][$i]) ^ 2 + ($aBall[1] - $aBlock[1][$i]) ^ 2) <= $aBall[4] + $aBlock[2][$i] Then
			If $aBall[0] = $aBlock[0][$i] Then
				$aBall[3] *= -1
			ElseIf $aBall[1] = $aBlock[1][$i] Then
				$aBall[2] *= -1
			Else
				$aTangent[0] = ($aBall[1] - $aBlock[1][$i])
				$aTangent[1] = ($aBlock[0][$i] - $aBall[0])
				$iVector_Scal = 2 * (($aTangent[0] * $aBall[2] + $aTangent[1] * $aBall[3]) / ($aTangent[0] ^ 2 + $aTangent[1] ^ 2))
				$aBall[2] = $iVector_Scal * $aTangent[0] - $aBall[2]
				$aBall[3] = $iVector_Scal * $aTangent[1] - $aBall[3]
			EndIf
			If $aBlock[4][$i] > 1 Then
				$aBlock[4][$i] -= 1
				$aBlock[3][$i] = _GDIPlus_PenCreate($aHitColors[3 - $aBlock[4][$i]], 3)
			Else
				For $j = $i + 1 To $iBlocks - 1
					$aBlock[0][$j - 1] = $aBlock[0][$j]
					$aBlock[1][$j - 1] = $aBlock[1][$j]
					$aBlock[2][$j - 1] = $aBlock[2][$j]
					$aBlock[3][$j - 1] = $aBlock[3][$j]
					$aBlock[4][$j - 1] = $aBlock[4][$j]
				Next
				$iBlocks -= 1
				If $iPoints < 9 Then
					$iPoints = "0" & $iPoints + 1
				Else
					$iPoints += 1
				EndIf
			EndIf
		EndIf
	Next

	$aBall[0] -= $tmpVect[0]
	$aBall[1] -= $tmpVect[1]
EndFunc   ;==>_CalcCollision

Func _CalcGravitation()
	Local $iGrav
	Local $aVect[2]
	For $i = 0 To $iBlocks - 1
		$aVect[0] = ($aBlock[0][$i] - $aBall[0]) / Sqrt(($aBlock[0][$i] - $aBall[0]) ^ 2 + ($aBlock[1][$i] - $aBall[1]) ^ 2)
		$aVect[1] = ($aBlock[1][$i] - $aBall[1]) / Sqrt(($aBlock[0][$i] - $aBall[0]) ^ 2 + ($aBlock[1][$i] - $aBall[1]) ^ 2)
		$iGrav = $iGravitation * ($aBlock[2][$i] ^ 2) / (($aBlock[0][$i] - $aBall[0]) ^ 2 + ($aBlock[1][$i] - $aBall[1]) ^ 2)
		$aBall[2] += $iGrav * $aVect[0]
		$aBall[3] += $iGrav * $aVect[1]
	Next
EndFunc   ;==>_CalcGravitation

Func _Exit()
	_GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_BitmapDispose($hBitmap)
	_GDIPlus_FontDispose($hFont_Points)
	_GDIPlus_FontDispose($hFont_Menu)
	_GDIPlus_FontFamilyDispose($hFamily)
	_GDIPlus_StringFormatDispose($hFormat)
	_GDIPlus_BrushDispose($hBrush_String)
	_GDIPlus_BrushDispose($hBrush_White)
	_GDIPlus_PenDispose($hPen_Size)
	_GDIPlus_PenDispose($hPen_White)
	For $i = 0 To $iBlocks - 1
		_GDIPlus_PenDispose($aBlock[3][$i])
	Next
	_GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_Shutdown()
	Exit
EndFunc   ;==>_Exit

Func _Single()
	$iPlayerTurn = 0
	$iPlayerMode = 0
EndFunc   ;==>_Single

Func _Multi()
	$iPlayerTurn = 0
	$iPlayerMode = 1
EndFunc   ;==>_Multi
