Während Whileschleife keine Buttons mehr drückbar

  • Hallo zusammen,

    ich bin gerade dabei ein kleines Spielchen zu machen.

    Hierbei müsst ihr als Chef eines Unternehemns Geld verdienen und so wirtschafen.

    Nun komme ich aber leider nicht mehr weiter aktuell ?(

    Im Script (Zeile 80) zählt er dann zwar alle 2 Sekunden die 500 € auf das Konto, nur kann man dann keine Buttons mehr drücken.

    z.B. der "Geld verdienen" Button geht dann nicht mehr

    ebeneso der Beenden Button auch nicht mehr.

    Hat von euch vielleicht einer ein Lösung für mich wie er pro ( z.b. 5 Sekunden mir immer 500€ auf dieses "Konto" macht aber die Buttons noch bedienbar sind.

    Vielen Dank im Vorfeld !! :)

    Gruß

    Headsniper1997


    3 Mal editiert, zuletzt von Headsniper1997 (28. April 2018 um 18:02)

  • Du hast eine While Schleife in der While Schleife. Dadurch können die Events nicht mehr verarbeitet werden da du diese Schleife niemals verlässt. Du bist hängst quasi in der zweiten While Schleife drin ohne diese jemals zu verlassen.

    Sleep() eignet sich allgemein nicht um mit Zeiten (in dem Fall 2 Sekunden) zu arbeiten. Die bessere Alternative wäre hier mit TimerInit() und TimerDiff() zu arbeiten.

    Außerdem sehe ich noch ein paar Sachen die ich persönlich bemängeln würde. Das ist aber der Code Stil und hat weniger mit der Funktionalität des Programmes zu tun.

  • Wie könnte ich das dann anstellen (bin relativ neu) ?

    sagen wir ich Drücke den Button "Mitarbeiter kaufen"

    Dann soll er im Label ausgeben

    Aktueller MItarbeiterstand: 10

    und soll dann in einer schleife pro Sekunde 500 € auf das Konto rechnen

    und im Firmenkontostand wieder ausgeben.

    später dann bei 20 z.b. 1000 € pro Sekunde auf das Konto

  • und soll dann in einer schleife pro Sekunde 500 € auf das Konto rechnen

    Du kannst auch eine Funktion mit AdlibRegister registrieren die alle x Millisekunden ausgeführt wird.

    Dann hast du auch keine blockierende Schleife.

    Grundsätzlich solltest du dein Programm nicht-blockend programmieren, das bedeutet, dass die GUI-Elemente separat abgefangen werden sollten.

    Das kannst du am einfachsten erreichen indem du den OnEvent-Modus verwendest.

    Wenn du trotzdem bei der GUIGetMsg() Variante bleiben willst wäre die einfachste Lösung, mit dem Buttonklick eine Variable auf True zu setzen und dann in der

    GUIGetMsg()-Schleife das Geld zuzuweisen, so fängst du immer noch die Buttonklicks ab aber fügst deinem Konto Geld hinzu.

  • Du kannst auch eine Funktion mit AdlibRegister registrieren die alle x Millisekunden ausgeführt wird.

    Dann hast du auch keine blockierende Schleife.

    Nein, auf keinen Fall!

    So wie sein Code momentan aussieht wird das nur noch schlimmer. Hast du mal genauer rein geschaut?

    ---

    Naja, du könntest beispielsweise in deiner Hauptschleife mit TimerInit() und TimerDiff() arbeiten, um die Zeitdifferenz zu messen. Darauf basierend kannst du alle x Sekunden den Kontostand erhöhen:

    AutoIt
    Global $timer = TimerInit()
    
    ; Deine Hauptschleife:
    While True
        If TimerDiff($timer) >= 2000 Then
            ConsoleWrite("2 Sekunden sind vergangen..." & @CRLF)
            $timer = TimerInit()
        EndIf
    WEnd

    Dein Code ist die reinste Katastrophe. Du erstellt 2 GUIs und löscht GUI Elemente. Ich würde dir erst mal empfehlen von Koda die Finger zu lassen und selber so eine GUI mal aufzubauen. Folgende Funktionen könnten dir von Hilfe sein:

    GUICtrlSetData()

    GUICtrlSetStata()

    Dann musst du nicht ständig die GUI Elemente löschen und neu erstellen.

  • Okay also ich verstehe, dass eine While schleife in einer While schleife nicht funktionieren kann.

    Dennoch kann ich noch nicht recht nachvollziehen, wie das nun mein Problem löst, bzw. wie ich deinen Code Yjuq in meinem anwenden kann


    Hat jemand vielleicht ein plastischeres Bsp. ?

  • Ich könnte dir auch natürlich die fertige Lösung geben. Allerdings bezweifel ich, dass dies in irgend einer Weise weiterhilft. Hilfe zur Selbsthilfe - Fangen wir erst mal damit an dass du lernst Beispiele und Prinzipien von fremden Code in den eigenen einzuarbeiten. :)

    Einmal editiert, zuletzt von Yjuq (29. April 2018 um 05:18)

  • Zitat

    Ich könnte dir auch natürlich die fertige Lösung geben. Allerdings bezweifel ich, dass dies in irgend einer Weise weiterhilft.

    Da finde ich hast du vollkommen recht.

    zumindest funktioniert das was du mir da geschickt hast nun in kombi mit dem meinen

    Habe noch hizugefügt (wie es später dann auch funktionieren soll)

    Zumindest damit kann ich jetzt mal weiterarbeiten.

    Hast du mir denn noch Tipps, da du anfänglich meinst mein Script sei sehr schlecht aufgebaut was man dort für die übersicht machen kann ?

    hab schon son bisschen rausgefunden ;==> hinter die einzelnen dinge zu schreiben um sie zu definieren

    und in verschiedenen ebenen zu arbeiten.

    Gibts da noch mehr ?

    Dennoch vielen Dank !!!

  • Ich hab dein Script aus dem ersten Post mal so überarbeitet, dass es deutlich ansehnlicher und übersichtlicher ist.

    Zu den Änderungen:

    1. Variablen passend benennen, damit man weiß, was sie bedeuten. Bei $label1 weiß keiner was sich dahinter verbirgt. Dabei auch gerne am Anfang der Variable den Typ nennen. So zum Beispiel i für eine Zahl, b für ein Bool,...

    2. Die Hauptschleife so übersichtlich halten wie möglich. Daher alles in Funktionen auslagern, sodass deine Hauptschleife schlank bleibt und du auf einen blick siehst, was beim Klick auf den Button passiert.

    3. Alles was redundant ist (sich wiederholt) ebenfalls in Funktionen auslagern. Da hab ich hier zum Beispiel das _setCompanyMoney definiert. Dadurch wird beim ändern des Geldes jedesmal auch das Label aktualisiert. Änderst du irgendwann mal das Label musst du es nicht überall im Code ändern, sondern nur an dieser einen Stelle.

    4. Das Fenster am Anfang vollständig erstellt und die Controls nur ein/ausblenden. Da du ein Spiel programmierst solltest du den Overhead des ständigen neuerstellens vermeiden, da das, wenn dein Spiel größer wird, ausbremsen kann!

    5. Ich hab das hier jetzt nicht umgesetzt, aber schau dir auf jedenfall Arrays an. Gerade beim erstellen von Fenstern sind diese eine sehr größe Hilfe. Auch sonst wirst du vermutlich irgendwann nichtmehr drumrumkommen

    Der Code:

    MfG Kanashius

  • Wow okay vielen neue dinge die ich erst noch verstehen muss.

    Hab den ganzen morgen und mittag jetzt drangesessen und versucht das selbst hinzubekommen, mit erfolg.

    Dank der hilfe von Yjuqs kleinem Script funktionert es jetzt so wie das von dir Kanashius (zwar leider nicht so übersichtlich wie deins) aber immerhin ein großer Erfolg für mich.

    Trotzdem vielen dank für deine Mühe, werde mir ein wenig von deinem Stiel versuchen anzueignene

    Gruß

    Headsniper1997

  • Ich kann dir auch die TimerDiff() Methode empfehlen. Wenn es ein wenig "besser" sein soll, muss man in der Hauptschleife

    einen Iterator, FPS Variable und Speed Variable einbauen und kalkulieren. Ist aber nur bei aufwendigen Spielen nötig. :D

  • Ich kann dir auch die TimerDiff() Methode empfehlen. Wenn es ein wenig "besser" sein soll, muss man in der Hauptschleife

    einen Iterator, FPS Variable und Speed Variable einbauen und kalkulieren. Ist aber nur bei aufwendigen Spielen nötig. :D

    Wozu? Kannst du mir ggf. genauer erklären was du meinst? Ich sehe da keinen Sinn in deiner Aufzählung...

    Ich hatte dir doch auch schon mal dazu was verfasst:

    PandaRunner Reworked - Ein Autoit Game

    Einmal editiert, zuletzt von Yjuq (30. April 2018 um 14:23)

  • Wozu? Kannst du mir ggf. genauer erklären was du meinst? Ich sehe da keinen Sinn in deiner Aufzählung...

    Ich hatte dir doch auch schon mal dazu was verfasst:

    PandaRunner Reworked - Ein Autoit Game

    Hi, ja danke das war echt hilfreich damals. ^^

    Ich meinte das so, dass man anstelle der direkten Verwendung

    des Timers auch die Durchläufe des Skripts nehmen kann. Wobei

    man im Endeffekt auch einen Timer benötigt, so wie du es mir gesagt hast.

    Aber dadurch das man den Timer nicht direkt nimmt, hat man mehrere Möglichkeiten,

    wie z.B das man jetzt einfach mal sagt, ich ändere die Geschwindigkeit von 1 auf 0,5 oder auf 0 (pausiert).

    Und dafür kann man dann eine einheitliche Variable benutzen. :D


    Edit:

    Achja jetzt weiß ich wieder, wo ich das Problem hatte mit den Timern. Also ich wollte z.B jede 1000ms einen

    Gegner spawnen lassen. Wenn 1000ms erreicht wurden, wurde der Timer eben wieder zurückgesetzt.

    Wenn das Spiel jedoch mal 2 Sekunden laggt, entsteht ja eine Differenz von einer Sekunde. Dadurch wird

    ein Gegner weniger gespawnt. Wenn ich beim Rundenstart aber einen Iterator starte und diesen mit dem Speed Timer

    multipliziere, habe ich immer einen exakten Wert und kann so die Gegner Bild für Bild optimal spawnen lassen. :)

    Einmal editiert, zuletzt von xSunLighTx3 (30. April 2018 um 15:14)

  • So richtig kann ich mir unter deiner Beschreibung nicht vorstellen was du meinst. Vielleicht hab ich auch was anderes im Sinn als du versuchst du erläutern. Wärst du so freundlich und würdest ein minimalistisches Beispiel dazu verfassen?