Wenn Fenster inaktiv wird, dann - Error: Subscript used with non-Array variable.

  • Schönen guten Tag,

    Ich habe Pong programmiert (Einfach mal so, aus langerweile, irgendetwas muss man ja mal machen). Nun habe ich allerdings einen mir nicht erklärbaren Fehler, der entsteht wenn das Fenster inaktiv wird bzw. minimiert wird (Wobei der Fehler beim minimieren bereits durch eine Extra-Funktion korrigiert ist).

    Theoretisch könnte ich durch eine etwas kompliziertere GUI-Abfrage Abfrage, die Inaktivität des Fensters erkennen und das Pong Skript pausieren (So habe ich das bereits auch schon beim minimieren eingebaut). Das ist allerdings nur eine nicht perfekte Not-Lösung.

    Mir geht es eher darum zu erfahren warum dieser Fehler überhaupt eintritt und ob er nicht anderwärtig ausgebessert werden kann.

    Hier ist der Source-Code:


    [autoit]

    #include <GUIConstantsEx.au3>
    #include <GuiEdit.au3>
    Opt("GUIOnEventMode", 1)
    $mainwindow = GUICreate("Pong - v0.12 Alpha - - - by KloMeister", 602, 250)
    GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "minimiert")
    GUISetOnEvent($GUI_EVENT_RESTORE, "maximiert")
    $ball = GUICtrlCreateLabel("•", 2, 2)
    $okbutton = GUICtrlCreateButton("Start Game", 250, 50, 100)
    GUICtrlSetOnEvent($okbutton, "OKButton")
    $Checkbox1 = GUICtrlCreateCheckbox("CPU Enable", 255, 80, 185, 25)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlCreateLabel("________________________________________________________________________________________________________________", -8, -2, 716, 14)
    GUICtrlCreateLabel("¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯", -8, 200, 716, 14)
    $controls1 = GUICtrlCreateLabel("Control: w = up, s = down", 25, 104, 124, 17)
    $controls2 = GUICtrlCreateLabel("Control: Arowkeys", 490, 104, 100, 17)
    $PtP1 = GUICtrlCreateLabel("Punkte P1:", 498, 230, 57, 17)
    $PtP2= GUICtrlCreateLabel("Punkte P2:", 8, 230, 57, 17)
    $PointsP1 = GUICtrlCreateLabel("0", 562, 230)
    $PointsP2 = GUICtrlCreateLabel("0", 72, 230)
    Local $Variable
    Local $hoch
    Local $hoch2
    local $ballrechts
    local $ballrunter
    local $ballrichtunghoch
    local $ballrichtungrechts
    local $StartEnable
    local $bothoch
    local $Reaktion
    local $idlemoverichtung
    Local $aPos
    Local $bPos
    Local $ingame
    $bothoch = 1
    $Reaktion = 0
    $ingame = 0
    Call("randomstart")
    $Paddel1 = GUICtrlCreateLabel("", 10, 70, 4, 36)
    GUICtrlSetBkColor(-1, 0x000000)
    $Paddel2 = GUICtrlCreateLabel("", 590, 70, 4, 36)
    GUICtrlSetBkColor(-1, 0x000000)
    $StartEnable = 0
    GUISetState(@SW_SHOW)
    HotKeySet("{UP}", "TOP")
    HotKeySet("{DOWN}", "DOWN")
    HotKeySet("{w}", "TOP2")
    HotKeySet("{s}", "DOWN2")
    While 1
    Sleep(25)
    if $StartEnable = 1 then ;Abfrage ob Gamestart - Button gedrueckt
    ;Paddel Abfrage und Bewegung Player1
    if GUICtrlRead($Checkbox1) = 4 then ;Checke if CPU
    $aPos = ControlGetPos("", "", $Paddel1)
    if $aPos[1] >160 then
    GUICtrlSetPos($Paddel1, 10, 160)
    endif
    if $aPos[1] <12 then
    GUICtrlSetPos($Paddel1, 10, 12)
    endif
    if $hoch = 1 Then
    $aPos = ControlGetPos("", "", $Paddel1)
    GUICtrlSetPos($Paddel1, 10, $aPos[1] -4)
    ElseIf $hoch = 2 then
    Local $aPos = ControlGetPos("", "", $Paddel1)
    GUICtrlSetPos($Paddel1, 10, $aPos[1] +4)
    EndIf
    Else
    ;wenn CPU
    if $ballrichtungrechts = 1 then
    Call("idlearound")
    Else
    $aPos = ControlGetPos("", "", $Paddel1)
    $bPos = ControlGetPos("", "", $ball)
    if $Reaktion = 2 then
    if $aPos[1] + random(9,20) < $bPos[1] Then
    $bothoch = 1
    Else
    $bothoch = 0
    endif
    $Reaktion = 0
    endif
    $Reaktion = $Reaktion +1
    if $bpos[0] <175 then
    if $bothoch = 1 Then
    $aPos = ControlGetPos("", "", $Paddel1)
    GUICtrlSetPos($Paddel1, 10, $aPos[1] +6)
    Else
    $aPos = ControlGetPos("", "", $Paddel1)
    GUICtrlSetPos($Paddel1, 10, $aPos[1] -6)
    endif
    Else
    Call("idlearound")
    endif
    endif
    endif
    ;Paddel Abfrage und Bewegung Player2
    $aPos = ControlGetPos("", "", $Paddel2)
    if $aPos[1] >160 then
    GUICtrlSetPos($Paddel2, 590, 160)
    endif
    if $aPos[1] <12 then
    GUICtrlSetPos($Paddel2, 590, 12)
    endif
    if $hoch2 = 1 Then
    $aPos = ControlGetPos("", "", $Paddel2)
    GUICtrlSetPos($Paddel2, 590, $aPos[1] -4)
    ElseIf $hoch2 = 2 then
    Local $aPos = ControlGetPos("", "", $Paddel2)
    GUICtrlSetPos($Paddel2, 590, $aPos[1] +4)
    EndIf
    ;Ballrichtung
    if $ballrichtunghoch= 0 then
    $aPos = ControlGetPos("", "", $ball)
    GUICtrlSetPos($ball, $aPos[0] , $aPos[1] + $ballrunter)
    Else
    $aPos = ControlGetPos("", "", $ball)
    GUICtrlSetPos($ball, $aPos[0] , $aPos[1] - $ballrunter)
    EndIf
    if $ballrichtungrechts= 0 then
    $aPos = ControlGetPos("", "", $ball)
    GUICtrlSetPos($ball, $aPos[0] - $ballrechts, $aPos[1])
    Else
    $aPos = ControlGetPos("", "", $ball)
    GUICtrlSetPos($ball, $aPos[0] + $ballrechts , $aPos[1])
    EndIf
    ;Ballabfrage fuer Waende
    $aPos = ControlGetPos("", "", $ball)
    if $aPos[1] >190 then
    $ballrichtunghoch=1
    endif
    $aPos = ControlGetPos("", "", $ball)
    if $aPos[1] <10 then
    $ballrichtunghoch=0
    endif
    ;Abfrage Ball - Paddelkontakt P1
    $aPos = ControlGetPos("", "", $Paddel2)
    $bPos = ControlGetPos("", "", $ball)
    if $bPos[0] >585 then
    if $bPos[1] - $aPos[1] >-7 then
    if $bPos[1] - $aPos[1] <34 then
    $ballrichtungrechts=0
    $ballrechts = $ballrechts * 1 + round(random(0.1,0.5),2)
    $ballrunter = $ballrunter * 1 + round(random(0.1,0.3),2)

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

    Else ;Beim nicht Ball bekommen
    _GUICtrlEdit_SetText($PointsP2, _GUICtrlEdit_GetText($PointsP2) +1)
    msgbox (0,"","Win P2")
    Call("randomstart")
    endif
    Else
    _GUICtrlEdit_SetText($PointsP2, _GUICtrlEdit_GetText($PointsP2) +1)
    msgbox (0,"","Win P2")
    Call("randomstart")
    endif
    endif
    ;Abfrage Ball - Paddelkontakt P2
    $aPos = ControlGetPos("", "", $Paddel1)
    $bPos = ControlGetPos("", "", $ball)
    if $bPos[0] <15 then
    if $bPos[1] - $aPos[1] >-7 then
    if $bPos[1] - $aPos[1] <34 then
    $ballrichtungrechts=1
    $ballrechts = $ballrechts * 1 + round(random(0.1,0.5),2)
    $ballrunter = $ballrunter * 1 + round(random(0.1,0.3),2)
    Else ;Beim nicht Ball bekommen
    _GUICtrlEdit_SetText($PointsP1, _GUICtrlEdit_GetText($PointsP1) +1)
    msgbox (0,"","Win P1")
    Call("randomstart")
    endif
    Else
    _GUICtrlEdit_SetText($PointsP1, _GUICtrlEdit_GetText($PointsP1) +1)
    msgbox (0,"","Win P1")
    Call("randomstart")
    endif
    endif
    endif
    WEnd
    ;Tastenabfrage
    Func TOP()
    $hoch2 = 1
    EndFunc ;
    Func DOWN()
    $hoch2 = 2
    EndFunc ;
    Func TOP2()
    $hoch = 1
    EndFunc ;
    Func DOWN2()
    $hoch = 2
    EndFunc ;
    Func OKButton()
    $StartEnable = 1
    $ingame = 1
    ControlHide ( "", "", $okbutton)
    ControlHide ( "", "", $Checkbox1)
    ControlHide ( "", "", $controls1)
    ControlHide ( "", "", $controls2)
    if GUICtrlRead($Checkbox1) = 1 then $CPU= GUICtrlCreateLabel("CPU Enabled", 8, 210)
    EndFunc
    Func CLOSEClicked()
    Exit
    EndFunc
    Func minimiert()
    $StartEnable = 0
    EndFunc
    Func maximiert()
    if $ingame = 1 then $StartEnable = 1
    EndFunc
    func idlearound()
    $aPos = ControlGetPos("", "", $Paddel1)
    if $aPos[1] <12 then
    $idlemoverichtung = 0
    endif
    if $aPos[1] >160 then
    $idlemoverichtung = 1
    endif
    if $idlemoverichtung = 1 then
    Local $aPos = ControlGetPos("", "", $Paddel1)
    GUICtrlSetPos($Paddel1, 10, $aPos[1] -6)
    Else
    Local $aPos = ControlGetPos("", "", $Paddel1)
    GUICtrlSetPos($Paddel1, 10, $aPos[1] +6)
    endif
    EndFunc
    Func randomstart()
    $random = random(1,4,1)
    select
    case $random = 1
    GUICtrlSetPos($ball, 300, 90)
    $ballrechts = 3
    $ballrunter = 2
    $ballrichtunghoch = 0
    $ballrichtungrechts = 1
    case $random = 2
    GUICtrlSetPos($ball, 300, 90)
    $ballrechts = 3
    $ballrunter = 2
    $ballrichtunghoch = 1
    $ballrichtungrechts = 1
    case $random = 3
    GUICtrlSetPos($ball, 300, 90)
    $ballrechts = 3
    $ballrunter = 2
    $ballrichtunghoch = 1
    $ballrichtungrechts = 0
    case $random = 4
    GUICtrlSetPos($ball, 300, 90)
    $ballrechts = 3
    $ballrunter = 2
    $ballrichtunghoch = 0
    $ballrichtungrechts = 0
    EndSelect
    endfunc

    [/autoit]

    Einmal editiert, zuletzt von KloMeister (8. Juli 2013 um 22:49)

  • Ganz einfach: Der Fehler liegt in Zeile 73 und 74.
    Sobald das Fenster minimiert wird, kann sich die angegebene ID nicht mehr zuordnen bzw. Würde sich auf das neue aktive Fenster beziehen :x
    Demnach wird entweder KEIN Array ausgegeben (Was den Fehler erzeugt) oder es werden falsche Werte zurück gegeben (Welches in einen anderen Fall erst eintritt)

    Am besten schreibst du das wenn schon so um:
    $aPos = ControlGetPos($mainwindow, "", $Paddel1)

    Sieh doch einfach mal in die Hilfe :x
    Da steht das auch drin auf welches Fenster sich das ganze bezieht wenn kein Fensterame angegeben ist...
    >> Nämlich auf das derzeitig aktive Fenster ^^


    €dit:
    Statt Controls kannst du ja beispielsweise GDI+ nutzen...
    Oder zeichne mithilfe eines Graphic Controls...

    Einmal editiert, zuletzt von Yjuq (8. Juli 2013 um 22:48)