JS Timer + Loop.

  • Hi! Zu meinem Problem:


    Ich möchte in JS ein Game programmieren, dazu brauche ich bei einer bestimmten Funktion nen Zähler + Timer. Nur wie?

    Ich habe eine Variable und 3 Arrays.

    Code
    <script>
    level = 0;
    counter = 0;
    bloonCounter = [];
    timeLapse = [];
    whichBloons = [];
    </script>

    in der Function levels(); wird level um 1 erhöht. Damit ändern sich auch die Werte der Arrays und von counter.

    Code
    <script>
    case 1:
    counter = 1;
    whichBloons = [1];
    bloonCounter = [14];
    timeLapse = [0];
    break;
    </script>

    Counter sagt mir immer wie viele Felder die Arrays haben.

    Mit einer for Schleife habe ich immer die richtigen Zahlen.

    Code
    <script>
    for (var i = 0; i < counter; i++) {
    
    }
    </script>

    Ich möchte whichBloons[i] bloonCounter[i]-mal erzeugen ab der Sekunde timeLapse[i]. ( den Bloon 1 möchte ich 14-mal erzeugen und das ab der Sekunde 0 ).

    Im Array Bloons sind die einzelnen Bloonobjekte gespeichert. Der Typ 0 hat als interval 3000 gespeichert.


    Wenn der Typ 0 also erzeugt wird, soll er das in Intervallen tun, alle 3 Sekunden. Solange bis der Typ 0 14-mal erstellt wurde. Dann ist die Schleife einmal durch und i wird um 1 erhöht. Dann geht der Spaß mit dem zweiten Wert der Arrays los. Solange bis alles durchgearbeitet ist, dann ist das Level durch.


    Ich habe bereits vieles veruscht, mit setInterval, setTimeout, habe Functions erstellt die den Loop übernehmen wollten... Sitze jetzt seit knapp 3 Tagen daran. Ich war einmal kurz davor, da wurden dann aber alle 3 Sekunden gleich 14 Bloons erstellt, bis der Wert von Counter erreicht war. Habe letzten endes auch verstanden wieso, aber ne Lösung hab ich bis heute nicht. Kann mir einer helfen?


    Mit Logik hab ich da echt meine Probleme. Aber teilweise fehlt mir auch das Wissen über gewisse Funktionen...

  • Prüfe mal, ob ich das richtig verstanden habe und dies das tut, war Du dir vorstellst:

  • idx1 ist bei dir jetzt ein statischer Wert, der sich jedoch nach jedem Durchlauf ändern soll.


    Daher wollte ich das mit ner Schleife machen. Dann wäre i immer die Nummer im Array die ich brauche und die zu den anderen Arrays passt.

  • Doch, der ändert sich in Zeile 20. Ich habe dein Vorhaben so verstanden:


    idx1 = 0:

    0 Sek. warten

    5-mal bloom 1 erzeugen, aber nicht direkt hintereinander, sondern mit einem Intervall von 3 Sek (intv)


    idx1 = 1:

    1 Sek. warten

    3-mal bloom 2 erzeugen, aber nicht direkt hintereinander, sondern mit einem Intervall von 3 Sek (intv)


    (mit den (willkürlichen) Beispielwerten aus meinem Code)

  • Jetzt hört der nicht auf Bloons zu erstellen. Liegt wahrscheinlich daran, dass whichBloons[idx1] undefined ist. Aber woran kann das liegen? whichBloons ist definend und der erste Eintrag ist 0.

  • Das Problem hatte ich auch und es lag bei mir daran, dass die Index-Variablen anderweitig verwendet und verändert wurden. Versuche, es so zu kapseln:

  • Sempervivum an sich funktioniert das Script. Danke! Nur habe ich es mir mit dem TimeLaps anders vorgestellt.


    die zweite Reihe an Bloons soll nicht erst dann erstellt werden, wenn die andere fertig ist, sondern timeLaps[1] sekunden nach dem man die Funktion ausführt.


  • Dann ist es eigentlich viel einfacher. Prüfe dies, ob es das ist, was Du dir vorstellst:

  • Sempervivum Nach meinen Versuch das jetzt in die Praxis umzusetzen sind natülich einige Fehler entstanden. Statt einfache console.logs will ich natürlich was anderes.


    Undzwar soll jedes mal auf dem Canvas ein Bild gezeichnet werden, also ein Bloon. Die sollen dann über den Bildschirm laufen, wie im Originalspiel Bloons TD 4. Nur wenn ich ctx.clearRect(); einsetze um die Animation zu vollenden, bleibt der Schirm weiß.


    Also:

    Ich hoffe ich konnte vermitteln was ich meine und suche gerade nach einer Lösung, bzw. nach einen Grund wieso das überhaupt passiert.


    Denn nach meine Auffasung sollte es dadurch aussehen als wenn sich die Bloons über den Bildschirm bewegen, da erst alles gelöscht wird und dann der nächste bloon einen Pixel weiter gezeichnet wird.

  • Jetzt wird die Sache interessant ;)

    Dein Name drawBloons() ist ein wenig irreführend, weil immer nur ein Bloon gezeichnet wird. Also Canvas wird gelöscht - ein Bloon wird gezeichnet - neuer Aufruf - Canvas wird gelöscht, dabei verschwindet der erste Bloon wieder - ein anderer Bloon wird gezeichnet.

    Wenn Du mehrere Objekte animieren willst, musst Du so vorgehen, dass Du nur einen Animationframe führst und darin alle Bloons neu zeichnest.

    Das kann recht kompliziert werden und um es übersichtlich zu halten, wäre es angebracht, die Bloons mit ihren Parametern in einem Array zu halten. Dann kann man sie problemlos in jedem Frame neu zeichnen.

    Es gibt einen Weg, das Ganze stark zu vereinfachen, wenn man nämlich eine Bibliothek wie jCanvas verwendet. Dann kannst Du bestimmte Parameter wie in deinem Fall die Position ganz einfach animieren und musst dir über das Löschen und Neuzeichnen keine Gedanken machen:

    https://projects.calebevans.me/jcanvas/docs/animateLayers/

  • Ja, die Sache war Interessant, bis ich sie gelöst hab :D Hab das clearRect einfach an die richtige Stelle gepackt.


    Auf andere Weise ist aber interessant die Bloons nun in eine andere Richtung zu weisen, wenn sie einen bestimmten Punkt erreicht haben.


    Dazu habe ich mal zwei Arrays:

    Code
    coordiantes [];
    direction = [];

    Sobald coordinates[x] und coordinates[y] erreicht ist, soll direction[x] und direction[y] gemacht werden.

    So gut? Oder gäbs da was besseres?


    Die sache mit JCanvas ist ganz bestimmt schlauer, aber ich glaub die Diskussion hatten wir schon einmal ;D Ich hab mir für dieses Projekt vorgesetzt nur vanilla JS zu verwenden, vor Allem um meine Programmierfähigkeiten was Logik angeht zu verbessern. Viele sachen sind in JCanvas schon fertig, aber genau da will ich meinen Kopf schulen.

  • Ja, ich konnte mich auch erinnern, dass ich schon mal dieses Thema hatte, aber ich dachte, es sei jemand anderes gewesen, sonst hätte ich nicht damit angefangen.

    Diese Problematik mit der Umkehr der Richtung hatte ich auch schon ein paar Mal. Einmal war es so ein Spiel, wo sich Figuren innerhalb von Mauern bewegen sollten, allerdings nicht animiert, sondern mit den Pfeiltasten.

    Um zu beurteilen, ob der Ansatz mit den Koordinaten und der Richtung Erfolg verspricht, müsste man etwas mehr wissen, ob sich dahinter auch irgendwelche Begrenzungen, so wie Mauern verbergen etc., oder etwas anderes.

  • Hier ist mal ein Bild: https://ibb.co/r2wgSxY


    Die roten Dinger sind die Bloons, die sich auf der Strasse entlang bewegen sollen. Vom anfang bis zum Ende.

    Hier sehen wir in 'coordinates' ab welchem Punkt sich die direction ändern soll. in 'directions' steht 0 für einen negativ Wert, 1 für neutral und 2 für positiv.

    Haben wir nun also x = 1; und y = 2; soll die der Bloon sich auf der X-Achse nicht bewegen, aber auf der Y-Achse nach unten. (Weil +1 dazu gerechnet wird).


    xPlusZaehler und yPlusZaehler stehen im drawImage(); für die Position x und y.

    Klappt soweit auch ganz gut, nur weiß ich nicht wie ich das coordinates Array rüberholen kann. Kann ich sowas machen wie:

    Code
    return coordinates, directions;

    und dann:

    Code
    var h = Street()[0];

    geht das?

  • Vollständig habe ich das Ganze jetzt nicht gedanklich nachvollzogen.


    Aber erst Mal eine Empfehlung: Statt 0, 1 und 2 würde ich -1, 0 und +1 für die Richtungen empfehlen, einmal weil ich es anschaulicher finde und weil Du dann gleich einen Wert hast, um eine neue Position zu berechnen, entweder durch

    x += directions.x; y+= directions.y;

    oder

    x += speed * directions.x;

    ohne dass Du ifs oder einen Switch brauchst.


    Grundsätzlich kann eine Funktion nur einen Wert zurückgeben, dieser kann jedoch eine Struktur aus Arrays und Objekten sein, etwa so:

    return {xdir: die_x_richtung, ydir: die_y_richtung};

    wenn es nur die Richtung ist. Oder wenn Du sowohl Koordinaten als auch Richtung zurück geben willst, etwa so:

    Code
    var directions = {};
    direction.xdir = // hier die x-Richtung fest legen
    direction.ydir = // hier die y-Richtung fest legen
    var coordinates = {};
                     // die Koordinaten fest legen
    return {directions: directions, coordinates: coordinates};
  • Okay, das ist natürlich schlauer. Also alles. Versuche ich so umzusetzen.


    Sempervivum Ja, es klappt erstmal soweit, aber natürlich nicht ganz ohne Fehler, bzw. gibt es ein neues Problem. Wie teile ich jetzt dem Programm mit, ab wann die Bloons abbiegen sollen? Habe da ein wenig rumprobiert, doch es hat nicht geklappt:


    Code
    if(xPlusZaehler == returnMap[h+1].x && yPlusZaehler == returnMap[h+1].y) { h++; }
  • Komischerweise geht es erst, dann nicht mehr. Ab einem bestimmten Punkt ist h+1 plötzlich undefined. Wie löst man das Problem?


    EDIT: Ja ok, habs!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!