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
autoit.de/wcf/attachment/12873/
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