Javascript "Bild mit Pfeiltasten automatisch bewegen" HILFE

  • Guten Tag, wir machen in der Schule ein Projekt wo wir Space Invaders programmieren.


    Allerdings häng ich grad bei einer Aufgabe fest, bei dieser Aufgabe geht
    es darum, dass wenn man einmal die Pfeiltaste nach Rechts klickt, er
    automatisch bis zumSchluss des Fenster weiter geht.


    Wenn man ein 2tes mal nach Rechts klickt, soll er doppelt so schnell weiterlaufen.


    Wenn ich jetzt jedoch nach Links drücke, soll er Stoppen. Und erst dann
    wenn ich danach wieder nach Links drücke immer soviele Pixel weiter
    gehen bis zum Schluss.


    Wenn er nun zB nach Rechts läuft und ich drücke nach unten soll er nach rechts und nach unten laufen.


    Dies soll alles in den Code eingebaut werden:


    [HTML]<!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <title>Bild bewegen</title>


    <script type="text/javascript">


    function myFunction(event) {
    var x = event.keyCode;
    var image = document.getElementById("image");
    var top = parseInt(image.style.top);
    var left = parseInt(image.style.left);


    if (x == 37 && left > 0) {
    image.style.left = left - 10 + 'px';
    }


    else if (x == 38 && top > 0) {
    image.style.top = top - 10 + 'px';
    }


    else if (x == 39 && left + image.width + 10 < window.innerWidth) {
    image.style.left = left + 10 + 'px';
    }


    else if (x == 40 && top + image.height + 10 < window.innerHeight) {
    image.style.top = top + 10 + 'px';
    }


    }


    </script>
    <style>
    #image {
    position: absolute;
    width: 119px;
    height: 55px;
    }
    </style>
    </head>
    <body onkeydown="myFunction(event)">
    <img src="Starwars-Zerstoerer.gif" id="image" style="position:absolute;top:0px;left:0px;bottom:0px;" />
    </body>
    </html>[/HTML]




    Danke im vorraus.

  • Und du möchtest jetzt das wir dir das machen?
    also, das Wort 'HILFE' in der Überschrift ist überflüssig..
    Ich kann noch nicht richtig nachvollziehen was du jetzt eigentlich erwartest oO
    Soweit ich verstehe fragst du dich wie du abfragen kannst ob die taste schonmal gedrückt wurde..?


    (Ich will dir hier kein Code vorbeten, da dein Lehrer das eh checkt wenn das nicht von dir selber kommt und du es ihm nicht erklären kannst)
    Für dich selber bringt es dir mehr wenn du einfach mal eine EXPLIZITE Frage stellst! :)

  • Hey danke für die Antwort.
    Ich selber habe schon Probiert, dass wenn ich eine Funktion einfüge die das macht, allerdings funktioniert das nur so halb abgehackt.
    Mein Lehrer selber sagt, dass wir uns jegliche Hilfe nehmen dürfen, wo wir wollen.
    Solange es zum Schluss funktioniert.


    Was ich mich spezifisch frage, wie ist es möglich eine Funktion in ein if /else if statement einzufügen. Habs halt nur so probiert:


    x hab ich zu ner Variablen gemacht die den Keycode mit onkeydown reingibt.
    max = window.innerWidth
    und x3 sollen die Pixel sein.




    Würde mich echt freuen für eine kleine Hilfestellung und inspiration.
    Denn ich schaue mir den Code immer so an, dass ich ihn verstehe. Ich verwende ihn nie ganz wie er mir vorgegeben wird, sondern baue ihn so um dass auch ich ihn verstehe.

  • Eine Funktion rufst du mit dem Funktionennamen(Parameter1,Parameter2..) auf, dass function kannst du dir dort sparen :)
    Falls du nicht mit immediately Invoked Funktions, sondern Closures zurückgeben willst solltest du mal unter Closures googeln, aber
    ich denke das ist nicht genau das was du suchst.


    Du willst hier eher bereits vorher definierte Funktion aufrufen, was wie oben erwähnt gemacht wird. Zudem rate ich dir die Funktionen ganz oben in deinem Script
    zu definieren, damit du sie schneller findest und auch auf andere Programmiersprachen vorbereitet bist. Den es funktioniert nicht in jeder Sprache so, dass du die Funktion erst im Nachhinein definieren kannst. Dies ist eine besondere Eigenschaft von Javascript die sich Hoisting nennt :)


    Du benötigst hier eine Abfrage die immer wieder (ggf. rekursiv) prüft ob eine Taste gedrückt wurde. Wenn ja musst du prüfen ob es sich um jene handelt die eine gewisse Funktionsweise im Spiel ermöglichen sollen(Pfeil links/rechts) und dann dort die jeweilige Funktion aufrufen.


    Schema:


    RekursiveTimeoutfunktion ->


    falls Tastendruck vorliegt ->
    Prüfung ob daraus ein ereignis folgt ->
    ausführung dieses Ereignises


    <---- Selbstaufruf der Funktion(Rekursion)


    mfg

  • Diese Methode zur Bewegung eines Objektes nennt sich in der Spieleprogrammierung auch velocity (z.Dt. Geschwindigkeit). Dabei geht es um die permanente Abfrage ob eine Geschwindigkeit in eine der 2 oder 3 möglichen Dimensionen stattfindet, also eine entsprechende Bewegung erzeugt werden soll.


    In Javascript müsste man zusätzlich eine Funktion erstellen, welche diese Bewegung am DOM-Element erzeugt und sich selbstverständlich auch auf mehrere Objekte anwenden lässt ohne den Garbage Collector zu füllen. Letzteres ist in Javascript oft gar nicht so einfach wie es sein sollte.


    Vernünftige Bewegung, Kollision, Animation ist ohne ein solides Basiswissen übrigens keinen Versuch wert, meiner Meinung nach sollte man in der Schule eventuell einfachere Dinge praktizieren. Ich entnahm aus deinem Code einfach mal das du nicht außerordentlich viel Durchblick besitzt. Das meine ich keineswegs negativ, der Code ist nur äußerst laienhaft, verstärkt durch grausame Einrückung (welche ich schon beseitigt habe).


    Ich habe mich trotzdem mal an die Arbeit gemacht und ein kleines Beispiel dazu erstellt. Die erste Hürde ist die Möglichkeit zur Anwendung auf mehrere Objekte. Hierzu sind Klassen nötig, also wird simpel eine Klasse erstellt. Zur einfachen Instanziierung erstellt sich diese am Besten über eine Funktion. Möchte man nun ein Element übergeben sähe das wie folgt aus:


    JavaScript
    function player(element)
    {
        this.element = element;
    }
    
    
    
    
    var player1 = new player(document.getElementById("player1"));


    Für Bewegung und insbesondere für Collider sind einige Größen des Elementes Voraussetzung zu wissen. Richtige Collider gibt es in diesem Beispiel nicht, sie werden lediglich in der später erläuterten Update-Funktion simuliert. In Javascript ist es leider nicht sinnvoll und oft auch einfach unmöglich verschiedene Aufgaben auf unterschiedliche Klassen aufzuteilen, wie man es eigentlich gewohnt ist. Darum befindet sich auch fast alles in einer Klasse.


    Die benötigten Größen sind die Abmessungen, die ursprüngliche Position im Koordinatensystem (hier in Pixeln), die Geschwindigkeit (velocity) und die Verschiebung zu den Seiten, wobei die letzteren beiden Werte initial auf 0 gesetzt werden. Jeder Wert wird äquivalent für jede Dimension angegeben. In dieser Szene gibt es nur 2 Dimensionen und zwar x und y.


    Zusätzlich zu den Informationen über das zu bewegende Element braucht es noch Informationen über das Elternelement. In der Spieleprogrammierung spricht man beim Container z.B. eines Levels oder Abschnitts von Szenen, die Szene ist hier die einzige Ausnahme welche in einer seperaten Klasse angelegt wird, eine Referenz wird in die player-Klasse implementiert.



    Jetzt lassen sich bereits mehrere DOM-Objekte als Szenen oder player definieren. Die Bezeichnung player ist leicht irreführend, da es sich eigentlich um simple Objekte handelt, da im Beispiel aber nur der Spieler vorkommt und ein Aufteilen in Player und Object Klassen wie bereits genannt nicht unbedingt praktikabel ist, beschränke ich mich hier mal auf die eigentlich nicht ganz korrekte Bezeichnung.


    JavaScript
    var scene1 = new scene(document.getElementById("scene1"));
    var player1 = new player(document.getElementById("player1"), scene1);
    var player2 = new player(document.getElementById("player2"), scene1);


    Es fehlt die Animation an sich. Nun wäre dies wieder eine neue Klasse, klappt nicht gut, also in die player Klasse implementieren. Man käme nun theoretisch als erstes auf die Idee dafür die Interval oder Timeout-Funktion des window Objektes zu nutzen, das ist jedoch eine blöde Idee, da die Animation dann nicht mit der Bildwiederholungsrate des Anzeigegerätes synchronisiert wurde. Besser zu nutzen ist die requestAnimationFrame Methode.


    Da sich die Animation in der player Klasse befindet und Referenzen dadurch recht schwierig zu erstellen sind, erstelle ich vorher eine nicht objektorientierte Referenz und nutze diese dann simpel in der Update Methode.


    Die Methode an sich überprüft die Position des Objektes,die angegebene Geschwindigkeit und bewegt es dann in die entsprechende Richtung. Wie das funktioniert ist keine Zauberei sondern reine Mathematik. Wenn das Objekt den Rand der Szene erreicht wird die Geschwindigkeit auf 0 gesetzt, andere Collider sind hier nicht notwendig da es laut Spielprinzip nicht zu Kollisionen von Objekten (außer dem Geschoss) kommen muss. Es wird keine Angabe für links oder rechts benötigt. Positive Werte erzeugen Bewegung nach rechts/unten und negative nach links/oben.
    Bsp.:
    Translate: 50px
    Velocity-x: -5px
    Translate neu: 50px + (-5px) = 45px.


    Benutzt wird das CSS transform Attribut mit translate, so verändert sich die reine CSS Position des Objektes nicht. Nach Ablauf der Funktion findet eine Rekursion mittels requestAnimationFrame statt, so wird laufend geprüft ob velocity gesetzt ist oder nicht, dementsprechend wird animiert oder gestoppt, sowohl für die x-als auch für die y-Achse. Interessant ist hier wegen Spielprinzips beim Spieler nur die x-Achse.



    User Input verarbeiten ist nun auch nicht mehr so schwer, einfach je nach Bedingung den Wert für velocity ändern. Dazu ist an der Stelle auch nicht viel zu erklären.



    Erstellt ohne jQuery oder andere Frameworks. Frameworks sind schön, helfen aber beim lernen <0.


    Der ganze Kram kombiniert sieht dann irgendwie so aus: codepen.io velocity
    Pfeiltasten links/rechts oder A/D benutzen um Bewegung nach links oder rechts zu erzeugen. Doppelt drücken erhöht die Geschwindigkeit, bei entgegengesetzter Richtung wird zunächst ein Stillstand erzeugt.


    Solltest du hier jemals wieder rein gucken viel Spaß damit, bei Fragen kann ich auch gerne genauere Erläuterungen liefern.

Jetzt mitmachen!

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