Hi,
ich habe mal als Grundlage für ein Spiel mal eine kleine Physik Demo gebaut. Nur leider spinnt die Kollisionserkennung manchmal rum (Ball fliegt durch Körper durch).
viel Spaß damit
Spoiler anzeigen
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
HotKeySet("{Esc}", "_Exit")
_GDIPlus_Startup()
$hGUI = GUICreate("Ball Physik Demo by Sprenger120", 500, 500, 50, 50)
$hGUIDC = _WinAPI_GetDC($hGUI)
$hBitmapBackpuffer = _WinAPI_CreateCompatibleBitmap($hGUIDC, 500, 500)
$hDCBackpuffer = _WinAPI_CreateCompatibleDC($hGUIDC)
_WinAPI_SelectObject($hDCBackpuffer, $hBitmapBackpuffer)
$hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDCBackpuffer)
GUISetState(@SW_SHOW)
Global Const $iBall = 5;Größe des Balles
Global Const $iPunkteAnz = 7 ;Anzahl der Punkte
Global Const $iRectAnz = 5;Anzahl der Quadrate
Global Const $ARRAY_X = 0
Global Const $ARRAY_Y = 1
Global Const $ARRAY_StepX = 2
Global Const $ARRAY_StepY = 3
Global Const $ARRAY_NextStepColl = 4
Global Const $ARRAY_Width = 2
Global Const $ARRAY_Height = 3
Dim $aPunkte[$iPunkteAnz][5] ;X|Y|StepX|StepY|NextStepCollision
Dim $aRect[$iRectAnz][4] ;X|Y|W|H
;Punkte Array befüllen
[/autoit] [autoit][/autoit] [autoit]For $x = 0 To $iPunkteAnz - 1
$aPunkte[$x][$ARRAY_X] = Random(0,500,1)
$aPunkte[$x][$ARRAY_Y] = Random(0,500,1)
$aPunkte[$x][$ARRAY_StepX] = 8;Random(5, 10, 1)
$aPunkte[$x][$ARRAY_StepY] = 8;Random(5, 10, 1)
If Mod($aPunkte[$x][$ARRAY_StepX], 2) Then $aPunkte[$x][$ARRAY_StepX] += 1
;~ If Mod($aPunkte[$x][$ARRAY_StepY], 2) Then $aPunkte[$x][$ARRAY_StepY] += 1
$aPunkte[$x][$ARRAY_NextStepColl] = 0
Next
;Rect Array befüllen
For $x = 0 To $iRectAnz - 1
$aRect[$x][0] = Random(100, 400, 1)
$aRect[$x][1] = Random(100, 400, 1)
$aRect[$x][2] = Random(20, 90, 1)
$aRect[$x][3] = Random(20, 90, 1)
While 1
[/autoit] [autoit][/autoit] [autoit];Prüfen ob sich Rechtecke nicht berühren
For $i = 0 To $iRectAnz - 1
If $i = $x Then ContinueLoop
If _RectCollision($aRect[$x][$ARRAY_X], $aRect[$x][$ARRAY_Y], $aRect[$x][$ARRAY_Width], $aRect[$x][$ARRAY_Width], $aRect[$i][0], $aRect[$i][1], $aRect[$i][2], $aRect[$i][3]) Then
$aRect[$x][0] = Random(100, 400, 1)
$aRect[$x][1] = Random(100, 400, 1)
$aRect[$x][2] = Random(20, 90, 1)
$aRect[$x][3] = Random(20, 90, 1)
ContinueLoop 2
EndIf
Next
ExitLoop
WEnd
Next
#cs
$aPunkte[0][$ARRAY_X] = 0
$aPunkte[0][$ARRAY_Y] = 125
$aPunkte[0][$ARRAY_StepX] = 10;Random(5, 15, 1)
$aPunkte[0][$ARRAY_StepY] = 0;Random(5, 15, 1)
$aPunkte[0][$ARRAY_NextStepColl] = 0
$aPunkte[1][$ARRAY_X] = 125
$aPunkte[1][$ARRAY_Y] = 0
$aPunkte[1][$ARRAY_StepX] = 0;Random(5, 15, 1)
$aPunkte[1][$ARRAY_StepY] = 10;Random(5, 15, 1)
$aPunkte[1][$ARRAY_NextStepColl] = 0
$aPunkte[2][$ARRAY_X] = 300
$aPunkte[2][$ARRAY_Y] = 101
$aPunkte[2][$ARRAY_StepX] = 10;Random(5, 15, 1)
$aPunkte[2][$ARRAY_StepY] = 0;Random(5, 15, 1)
$aPunkte[2][$ARRAY_NextStepColl] = 0
$aPunkte[3][$ARRAY_X] = 101
$aPunkte[3][$ARRAY_Y] = 300
$aPunkte[3][$ARRAY_StepX] = 0;Random(5, 15, 1)
$aPunkte[3][$ARRAY_StepY] = 10;Random(5, 15, 1)
$aPunkte[3][$ARRAY_NextStepColl] = 0
$aRect[0][$ARRAY_X] = 100
$aRect[0][$ARRAY_Y] = 100
$aRect[0][$ARRAY_Width] = 50
$aRect[0][$ARRAY_Height] = 50
$aRect[1][$ARRAY_X] = 150
$aRect[1][$ARRAY_Y] = 100
$aRect[1][$ARRAY_Width] = 50
$aRect[1][$ARRAY_Height] = 50
$aRect[2][$ARRAY_X] = 200
$aRect[2][$ARRAY_Y] = 100
$aRect[2][$ARRAY_Width] = 50
$aRect[2][$ARRAY_Height] = 50
$aRect[3][$ARRAY_X] = 125
$aRect[3][$ARRAY_Y] = 150
$aRect[3][$ARRAY_Width] = 50
$aRect[3][$ARRAY_Height] = 50
$aRect[4][$ARRAY_X] = 175
$aRect[4][$ARRAY_Y] = 150
$aRect[4][$ARRAY_Width] = 50
$aRect[4][$ARRAY_Height] = 50
#ce
$hBrushPunkte = _GDIPlus_BrushCreateSolid(0xFF22b14c)
While Sleep(20)
_GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF)
;Punkte Zeichnen
For $x = 0 To $iPunkteAnz - 1
_GDIPlus_GraphicsFillRect($hGraphics, $aPunkte[$x][$ARRAY_X] + $iBall / 2, $aPunkte[$x][$ARRAY_Y] + $iBall / 2, $iBall, $iBall, $hBrushPunkte)
Next
;Rect's zeichnen
For $x = 0 To $iRectAnz - 1
_GDIPlus_GraphicsDrawRect($hGraphics, $aRect[$x][0], $aRect[$x][1], $aRect[$x][2], $aRect[$x][3])
Next
For $x = 0 To $iPunkteAnz - 1
;Seitenwände
If $aPunkte[$x][$ARRAY_X] > 500 Then $aPunkte[$x][$ARRAY_StepX] *= -1 ;Rechts
If $aPunkte[$x][$ARRAY_Y] > 500 Then $aPunkte[$x][$ARRAY_StepY] *= -1 ;Unten
If $aPunkte[$x][$ARRAY_X] < 0 Then $aPunkte[$x][$ARRAY_StepX] *= -1 ;Links
If $aPunkte[$x][$ARRAY_Y] < 0 Then $aPunkte[$x][$ARRAY_StepY] *= -1 ;Oben
Switch $aPunkte[$x][$ARRAY_NextStepColl]
Case True
Switch $aPunkte[$x][$ARRAY_NextStepColl]
Case 1 ;oben, unten
$aPunkte[$x][$ARRAY_StepY] *= -1
Case 2 ;rechts, links
$aPunkte[$x][$ARRAY_StepX] *= -1
Case 3 ;beide Achsen umkehren
$aPunkte[$x][$ARRAY_StepX] *= -1
$aPunkte[$x][$ARRAY_StepY] *= -1
EndSwitch
$aPunkte[$x][$ARRAY_NextStepColl] = 0
$aPunkte[$x][$ARRAY_StepX] = Int($aPunkte[$x][$ARRAY_StepX])
$aPunkte[$x][$ARRAY_StepY] = Int($aPunkte[$x][$ARRAY_StepY])
Case False
If $aPunkte[$x][$ARRAY_StepX] = 0 Then $aPunkte[$x][$ARRAY_StepX] = 0.0000001
If $aPunkte[$x][$ARRAY_StepY] = 0 Then $aPunkte[$x][$ARRAY_StepY] = 0.0000001
;ein schritt weitersetzen
$aPunkte[$x][$ARRAY_X] += $aPunkte[$x][$ARRAY_StepX]
$aPunkte[$x][$ARRAY_Y] += $aPunkte[$x][$ARRAY_StepY]
$iTempX = $aPunkte[$x][$ARRAY_X] + $aPunkte[$x][$ARRAY_StepX]
$iTempY = $aPunkte[$x][$ARRAY_Y] + $aPunkte[$x][$ARRAY_StepY]
$m = 0
;Steigung errechnen
If $iTempX - $aPunkte[$x][$ARRAY_X] <> 0 Then
$m = ($iTempY - $aPunkte[$x][$ARRAY_Y]) / ($iTempX - $aPunkte[$x][$ARRAY_X])
$b = $aPunkte[$x][$ARRAY_Y] - $m * $aPunkte[$x][$ARRAY_X]
Else
$m = 0
EndIf
;~ ConsoleWrite("m=" & $m & @CRLF)
[/autoit] [autoit][/autoit] [autoit];Testen ob der Punkt ein Quadrat berühren wird im nächsten step
For $i = 0 To $iRectAnz - 1
If Not _RectCollision($iTempX, $iTempY, 1, 1, $aRect[$i][$ARRAY_X], $aRect[$i][$ARRAY_Y], $aRect[$i][$ARRAY_Width], $aRect[$i][$ARRAY_Height]) Then ContinueLoop
;Ermitteln woher der Ball kommt
#cs
.__2__
| |
1 3
|__4__|
#ce
$ForStep = 1
If $aPunkte[$x][$ARRAY_StepX] < 0 Then $ForStep = -1
;Bestimmen woher die Kugel kommt
For $f = $aPunkte[$x][$ARRAY_X] To $aPunkte[$x][$ARRAY_X] + $aPunkte[$x][$ARRAY_StepX] Step $ForStep
$y = $m * $f + $b
;Ecke
If $f = $aRect[$i][$ARRAY_X] And $y = $aRect[$i][$ARRAY_Y] Then ;oben links
ConsoleWrite("Ecke: oben links" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 3
ExitLoop 2
EndIf
If $f = $aRect[$i][$ARRAY_X] + $aRect[$i][$ARRAY_Width] And $y = $aRect[$i][$ARRAY_Y] Then ;oben rechts
ConsoleWrite("Ecke: oben rechts" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 3
ExitLoop 2
EndIf
If $f = $aRect[$i][$ARRAY_X] + $aRect[$i][$ARRAY_Width] And $y = $aRect[$i][$ARRAY_Y] + $aRect[$i][$ARRAY_Height] Then ;unten rechts
ConsoleWrite("Ecke: unten rechts" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 3
ExitLoop 2
EndIf
If $f = $aRect[$i][$ARRAY_X] And $y = $aRect[$i][$ARRAY_Y] + $aRect[$i][$ARRAY_Height] Then ;unten links
ConsoleWrite("Ecke: untenlinks" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 3
ExitLoop 2
EndIf
;Seiten
If $y = $aRect[$i][$ARRAY_Y] And $f >= $aRect[$i][$ARRAY_X] And $f <= $aRect[$i][$ARRAY_X] + $aRect[$i][$ARRAY_Width] Then ; oben
ConsoleWrite("oben" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 1
ExitLoop 2
EndIf
If $y = $aRect[$i][$ARRAY_Y] + $aRect[$i][$ARRAY_Height] And $f >= $aRect[$i][$ARRAY_X] And $f <= $aRect[$i][$ARRAY_X] + $aRect[$i][$ARRAY_Width] Then ;unten
ConsoleWrite("unten" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 1
ExitLoop 2
EndIf
If $f = $aRect[$i][$ARRAY_X] And $y >= $aRect[$i][$ARRAY_Y] And $y <= $aRect[$i][$ARRAY_Y] + $aRect[$i][$ARRAY_Height] Then ; links
ConsoleWrite("links" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 2
ExitLoop 2
EndIf
If $f = $aRect[$i][$ARRAY_X] + $aRect[$i][$ARRAY_Width] And $y >= $aRect[$i][$ARRAY_Y] And $y <= $aRect[$i][$ARRAY_Y] + $aRect[$i][$ARRAY_Height] Then ; rechts
ConsoleWrite("rechts" & @CRLF)
$aPunkte[$x][$ARRAY_NextStepColl] = 2
ExitLoop 2
EndIf
Next
Next
EndSwitch
Next
_WinAPI_BitBlt($hGUIDC, 0, 0, 500, 500, $hDCBackpuffer, 0, 0, $SRCCOPY)
WEnd
While GUIGetMsg() <> -3
WEnd
Func _RectCollision($iX1, $iY1, $iWidth1, $iHeight1, $iX2, $iY2, $iWidth2, $iHeight2)
;Author: Faweyr
Return $iX1 + $iWidth1 > $iX2 And $iX1 < $iX2 + $iWidth2 And $iY1 + $iHeight1 > $iY2 And $iY1 < $iY2 + $iHeight2
EndFunc ;==>_RectCollision
Func _Exit()
_GDIPlus_GraphicsDispose($hGraphics)
_WinAPI_DeleteObject($hBitmapBackpuffer)
_WinAPI_DeleteDC($hDCBackpuffer)
_WinAPI_ReleaseDC($hGUI, $hGUIDC)
_GDIPlus_BrushDispose($hBrushPunkte)
_GDIPlus_Shutdown()
Exit
EndFunc ;==>_Exit