GDI+ Pong KI und Winkel Problem

  • Hallo erstmal,

    da ich mich neuerdings mit GDIPlus beschäftige wollte ich mal den Klassiker Pong nachschreiben,
    allerdings hacke ich an einer vernüftigen Berechnug eines "Abstoßwinkels" von dem Balken für den Ball fest. Ich hab mir dazu schon was einfallen lassen allerdings sieht die Bewegung des Balls sehr unnatürlich aus und wenn der Ball die mitte des Balkens trift fliegt er genau grade wieder rüber.
    Ausserdem weis ich leider nicht wie ich ansetzen kann um eine KI zu schreiben die nicht jeden Ball durch lässt aber auch nicht jeden Ball hällt.

    Desweitern wollte ich Fragen ob es eine "bessere" möglichkeit gibt etwas mit GDI+ darzustellen als es erst in den Buffer zu schreiben und den dann auf die GUI zu zeichnen, wenn ich z.B. für $iX eine Zahl höher als 5 nehme sieht man die Obere hälfte des Balls etwas "nachhinken".

    Hoffe ihr könnt mir dabei etwas unte die arme greifen und mir ein paar Denkanstöße geben.

    Hier mein Bisheriges Script(die Bilder sind Angehängt)

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlus.au3>
    #include <Misc.au3>
    Opt("GUIOnEventMode", 1)
    HotKeySet("{Esc}", "dispose")
    HotKeySet("d", "de")

    [/autoit] [autoit][/autoit] [autoit]

    $x = 300 ; Ball start Position
    $y = 300 ; Ball start Position
    $ix = 2 ; Horizontale Geschwindigkeit
    $iy = 1 ; Vertikle Geschwindigkeit
    $py = 170 ; Player start Position
    $gy = $x ; Gegner Position
    $dev_mode = False ; Dev Mode
    $safety = 2 ; Randabstand

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $Main_GUI = GUICreate("Main_GUI", 273, 156, 372, 264, BitOR($WS_POPUP, $WS_CLIPSIBLINGS))
    ;GUISetBkColor(0x000000)
    GUISetOnEvent($GUI_EVENT_CLOSE, "Main_GUIClose")
    $Label1 = GUICtrlCreateLabel("Start", 64, 8, 146, 42)
    ;GUICtrlSetFont(-1, 32, 400, 0, "Capture it 2")
    GUICtrlSetOnEvent(-1, "Label1Click")
    $Label2 = GUICtrlCreateLabel("Highscore", 8, 104, 259, 42)
    ;GUICtrlSetFont(-1, 32, 400, 0, "Capture it 2")
    GUICtrlSetOnEvent(-1, "Label2Click")
    $Label3 = GUICtrlCreateLabel("Optionen", 24, 56, 221, 42)
    ;GUICtrlSetFont(-1, 32, 400, 0, "Capture it 2")
    GUICtrlSetOnEvent(-1, "Label3Click")
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    $hgui = GUICreate("", 600, 350, @DesktopWidth / 2 - 300, @DesktopHeight / 2 - 175, BitOR($WS_POPUP, $WS_CLIPSIBLINGS))
    GUISetBkColor(0x000000)
    GUISetOnEvent($GUI_EVENT_CLOSE, "Main_GUIClose")

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hgui)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics(600, 350, $hGraphic)
    $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    $hBackground = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\BG.jpg")
    $hBalken = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Balken.png")
    $hBall = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Ball.png")
    While Sleep(100)

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func Label1Click()
    GUISwitch($Main_GUI)
    GUISetState(@SW_HIDE)
    GUISwitch($hgui)
    GUISetState(@SW_SHOW)
    Game_Start()
    EndFunc ;==>Label1Click
    Func Label2Click()
    ;folgt noch
    EndFunc ;==>Label2Click
    Func Label3Click()
    ;folgt noch
    EndFunc ;==>Label3Click
    Func Main_GUIClose()
    Exit
    EndFunc ;==>Main_GUIClose
    Func Game_Start()
    While 1
    If $dev_mode = True Then Dev()
    If _IsPressed(28) Then $py += 5
    If _IsPressed(26) Then $py -= 5
    Kolision()
    WM_Paint()
    If $x <= 20 - $safety Then Check_Kolision($py, $y)
    If $x <= 0 - $safety Then lose()
    WEnd
    EndFunc ;==>Game_Start
    Func lose()
    MsgBox(0, "", "Ende")
    Exit
    EndFunc ;==>lose
    Func Kolision()
    If $py > 332 - $safety Then $py = 332
    If $py < 15 - $safety Then $py = 15
    $x += $ix
    $y += $iy
    $gy = $y
    If $gy > 332 - $safety Then $gy = 332
    If $gy < 15 - $safety Then $gy = 15
    If $x >= 560 - $safety Then $ix *= -1
    If $y >= 330 - $safety Or $y <= 0 + $safety Then $iy *= -1
    EndFunc ;==>Kolision
    Func Check_Kolision($a, $b)
    $check = False
    For $t = $b To $b + 20
    For $i = $a - 30 To $a + 30
    If $i - $b = 0 Then
    $ix *= -1
    $iy = Round(($i - $a) * 0.175, 0)
    ;MsgBox(0,"", $iy & "=" & $i & "-" & $a)
    Return
    EndIf
    Next
    Next
    EndFunc ;==>Check_Kolision
    Func WM_Paint()
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hBackground, 0, 0, 600, 350)
    If $dev_mode = True Then _GDIPlus_GraphicsDrawImageRect($hBuffer, $hBall, 10, $py, 700, 2)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hBalken, 580, $gy - 30, 10, 60)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hBalken, 10, $py - 30, 10, 60)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hBall, $x, $y, 20, 20)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 600, 350)
    EndFunc ;==>WM_Paint
    Func Dev()

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MouseCoordMode", 1)
    $pos = MouseGetPos()
    Opt("MouseCoordMode", 0)
    $poss = MouseGetPos()
    ToolTip("Player: " & $py & @CRLF & "Maus: " & $poss[1] & @CRLF & "Ball:" & $x & "|||" & $y & @CRLF & "IX: " & $ix & @CRLF & "IY: " & $iy, $pos[0], $pos[1])
    EndFunc ;==>Dev
    Func dispose()
    _GDIPlus_ImageDispose($hBackground)
    _GDIPlus_ImageDispose($hBalken)
    _GDIPlus_ImageDispose($hBall)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>dispose

    [/autoit] [autoit][/autoit] [autoit]

    Func de()
    HotKeySet("d", "nix")
    HotKeySet("e", "ed")
    EndFunc ;==>de
    Func ed()
    HotKeySet("v", "ve")
    HotKeySet("e", "nix")
    EndFunc ;==>ed
    Func ve()
    HotKeySet("v", "ved")
    EndFunc ;==>ve
    Func ved()
    $dev_mode = True
    HotKeySet("v", "nix")
    EndFunc ;==>ved
    Func nix()

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>nix

    [/autoit]
  • Ja das stimmt schon aber dann wäre es ja egal wo man den Ball trift im Original ist es aber so das je weiter ausen man den Ball trift desto steiler wird er wieder zurückgeworfen.

  • Zur KI: Gib der KI doch eine maximale Geschwindigkeit, um das Paddle zu bewegen und baue eine Reaktionszei bei Richtungsänderungen ein.

    Für die Berechnung der Winkel kannst du auf eine abgerundete Form des Paddles zurückgreifen. Dann steht die Reflexionsachse schief, sodass der Auftreffwinkel sich verändert.