Hi Forum!
Ich veröffentliche hier mal eine Beta-Version meines Spiels Orbit-Shooter.
Es ist ein einfacher Klon von Orbital.
Es geht darum, möglichs lange zu "überleben", man schießt mit Kugeln, die an der Stelle, wo sie stehen bleiben, so groß werden bis sie den Rand berühren, und wenn der Schuss über die eigene "Todeslinie" kommt, hat man verloren.
Implementiert ist "Luftwiederstand" und vektorielles Abprallen von den anderen Kugeln.
Es ist noch ein bisschen buggy, evtl bleiben die Kugeln in einander stecken, oder bleiben einfach mitten im Flug stehen, probierts aus!
Danken möchte ich name22, ich habe mir zur Hilfe seine GDI+ Circle Collision angesehen..(aber nicht so ganz nachvollzeihen können und es dann selber überlegt :P)
Bug: Da ich nicht die FPS errechnen lasse, kann es sein, dass das Spiel auf langsamen Rechnern auch langsamer läuft, und die Geschwindigkeit nicht an die FPS angepasst ist, das ist aber verschmerzbar .
Hier der Code:
Spoiler anzeigen
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GDIPlus.au3>
#include <misc.au3>
Opt("GUIOnEventMode", 1)
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]Global $hBitmap, $hGraphic, $hBuffer
[/autoit] [autoit][/autoit] [autoit]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
Fresapore