Closed fehren1a closed 6 years ago
Hallo Jonas,
das Hauptproblem ist dass du event.target.clientX
aufrufst, aber clientX
garnicht Teil des targets
ist sondern zum event
gehört.
Korrekt ist also event.clientX
. Das wird dich aber auch nicht ganz glückglich machen, denn clientX/Y
ist immer relativ zum Ursprung des Browserfenster. Du suchst ja allerdings Koordinaten relativ zum Ursprung des Canvas. Auch da gibts eine Lösung innerhalb des events
. Ich weiß nicht, ob du dabei warst, aber im Tutorium haben wir darüber gesprochen.
Welchen Typecast benötige ich dann in diesem Fall? Denn für das HTMLCanvasElement gibt es für das event ja nicht die Option clientX, zumindest bei mir wird es nicht angezeigt.
Ich komme gerade bei deinem Schritt vom Canvas zum Event nicht mit.
Das Canvas hat mit der Eventinformation erstmal nichts zu tun, darum kümmert sich allein das Eventobjekt, welches wiederum wenn es durch einen Klick ausgelöst wird vom Typ MouseEvent
ist.
Vielen Dank Sascha für die Hilfestellung, das Programm läuft nun so wie ich es mir vorgestellt habe! ;-)
Hatte als Parameter in der Funktion kein MouseEvent
und habe jetzt mit _event.offsetX
gearbeitet.
Hätte dennoch eine allgemeine Frage zur Abschlussaufgabe. Was ist mit der Vorgabe "Es ist eine während des Programmverlaufs variable Anzahl von Objekten zu erkennen" bei der Aufgabenstellung gemeint?
Ist dies dann in meinem Fall erfüllt? https://fehren1a.github.io/EIA2/abschluss_aufgabe/abschluss.html
Wenn ich jetzt kleinlich wäre würde ich ich sagen nein, da du ja fest definiert hast, dass es einen Ball und einen Balken gibt. Du könntest z.B. darüber nachdenken, dass pro 5 Punkte etwa ein zusätzlicher Ball ins Spiel kommt.
Grundsätzlich müsste die Frage aber Herr Dell'Oro beantworten.
Das wäre auch meine Antwort gewesen. Es geht darum dynamisch Objekte zu erzeugen, zu zerstören und mit Hilfe der entsprechenden Strukturen zu verwalten.
Dynamisch erzeugen würde dann bedeuten, dass ich ein Array habe und darin den Ball beispielsweise verwalte oder?
Ja, aber das ergibt natürlich nur Sinn, wenn die Option auf mehrere Bälle existiert.
Habe nun versucht, diese Vorgabe zu erfüllen und habe in der main.ts
den Ball in ein Array gespeichert.
Dabei sind jedoch leider neue Probleme aufgetreten, die ich mir nicht erklären kann:
Sobald der zweite Ball sichtbar ist, d.h. counter == 2
, beschleunigen beide Bälle schlagartig, sodass die Geschwindigkeit viel zu hoch ist. Die Geschwindigeit sollte jedoch durch den neu erzeugten Ball nicht erhöht werden und der ursprüngliche Ball soll sich unabhängig davon wie davor weiterbewegen.
Durch den neuen (zweiten) Ball wird über die Punktezahl geschrieben, d.h. beim neuen Ball beginnt die Punktezahl bei 0. Ziel ist es jedoch, dass es nur eine Punktezahl gibt und diese fortgeführt wird, auch wenn der zweite Ball das Panel trifft, bedeutet beispielsweise: Ball1 trifft Panel (--> counter += 1
| Points: 1), Ball2 trifft Panel (--> counter += 1
| Points: 2) usw.
Nachdem "Game Over" erscheint, passiert nichts mehr bzw. das Spiel wird nicht mehr zurückgesetzt. Bedeutet, dass kein Panel, keine Punktezahl (resetet) und auch kein einzelner Ball erscheint.
Kann mir hierbei jemand helfen und das Problem lösen?
Link zur Ansicht: https://fehren1a.github.io/EIA2/abschluss_aufgabe/abschluss.html
Moin moin, ich hab mich da mal etwas durchgewühlt:
[...]
else {
s.update();
p.draw();
}
window.setTimeout(animate, 0.01);
}//Ende for-Schleife
}//Ende animate
Hier haben wird die Wurzel des Problems der Beschleunigung in deiner main.ts
. Der neue Timeout wird so oft gesetzt wie es Bälle gibt. Kein Problem so lange es einer ist, sobald es mehr werden krachts.
Dann wäre da noch die länge deines Timeouts mit 0.01ms. Das ist etwas arg kurz. 20ms und die daraus resultierenden 50 FPS reichen für unsere Zwecke völlig. Ich nehme mal stark an dir ging es dabei hauptsächlich um die Geschwindigkeit des Balls. Um die anzupassen hast die xspeed und yspeed in deiner Ball.ts
.
Das Problem mit den überlappenden Highscores ensteht aus der Tatsache heraus, dass jeder deiner Bälle einen eigenen Highscore besitzt, diesen zählt und ausgibt. Diese Funktionalität musst du ins Hauptprogramm verschieben.
Den Spielneustart habe ich auch wieder zum Laufen gebracht und ich war auch etwas verwirrt über das Verhalten von TS/JS an der Stelle. In die Details würde ich an der Stelle jetzt nicht gehen, da wirds etwas zu technisch, aber du kannst dir meinen Pullrequest anschauen und vergleichen, was ich an der Stelle anders mache.
Der Spieleablauf funktioniert jetzt soweit und habe nun den counter
ins Hauptprogramm verlegt und der zweite Ball hat nun auch das richtige Bewegungsverhalten. Danke schonmal hierfür! :)
Als letzten Schritt möchte ich nun noch mit TypeScript erreichen, dass es ein Menü gibt und ich nur darüber mit Klick auf die entsprechende Option zum Spiel gelange. Für dieses Menü habe ich eine Datei namens gui.ts
erstellt, welche auch als erstes aufgerufen wird. In dieser werden die jeweiligen Menüpunkte gezeichnet und über eine switch (anzeige)
soll geregelt werden, welche Funktionen aufgerufen werden. In case 1
wird beispielsweise die init()
aufgerufen, welche sich in der Pong.ts
befindet und das eigentliche Spiel bzw. die Spielfunktionalität regelt. Folgende Probleme gilt es zu beheben:
Wie kann ich den Menüpunkten jeweils einen EventListener("click")
dranhängen, sodass ich bei Klick auf "Start Game" bzw. "Help" zum gewünschten Ergebnis komme und die cases ausgeführt werden?
Bei der ehemaligen main.ts
(Hauptprogramm) hat das Spiel reibungslos funktioniert. Nachdem ich diese nun zu einer Klasse umgebaut habe, jedoch den Inhalt nicht verändert habe, funktioniert das Spiel beim Aufruf der init()
nicht mehr, d.h. kein animierter Ball, Panel usw.. Die init()
ruft ja wierderum die animate()
auf, weshalb eig. etwas passieren sollte.
Benötige daher dringend Hilfe, um auch dies noch gelöst zu bekommen.
Link zum Repo: https://github.com/fehren1a/EIA2/tree/master/abschluss_aufgabe
Hier kommen mir zwei Alternativen in den Sinn
Ich kann leider keine Klasse in main.ts erkennen...
Okay, wären denk ich leichtere Optionen. Also mit der main.ts
meinte ich, dass man diese nicht mehr berücksichtigen braucht und ich stattdessen die Pong.ts
habe.
Hmmm.... und wo wird jetzt ein Pong-Objekt instanziert?
In der gui.ts
wird das getan.
Bin gerade noch an einer zweiten Version, werde diese gleich noch hochladen.
Habe nun dieses Problem behoben und bin das Problem mit einem Click auf den Canvas umgangen, was aber in diesem Falle ausreicht.
Da ich bei einer Punktezahl von 1 (counter == 1
) einen zusätzlichen Ball in das Array reinpushe würde mich interessieren, wie ich diesen wieder gelöscht bekomme im Falle von GameOver. Muss ich hier in der if (s.gameOver)
mit .pop
arbeiten?
Link zur Ansicht: https://fehren1a.github.io/EIA2/semesteraufgabe/abschluss.html
Link zum Repository: https://github.com/fehren1a/EIA2/tree/master/semesteraufgabe
Ja, mit .pop wird das letzte Element des Arrays herausgenommen. Vielleicht ist es aber viel einfacher und geschickter, einfach ein neues, leeres Array zuzuweisen. Das alte wird dann automatisch komplett aus dem Speicher gelöscht.
Komme leider immer noch nicht ganz dahinter, wie ich das einbauen soll.
Angenommen das leere Array heißt Collector{}
. Dann habe ich ja in der animate()
eine if(s.gameOver){}
. Würde das dann bedeuten, dass ich in der if-Bedingung Collector.push(ball)
schreibe und in deren else amount = 0
? Und wird das Spiel dann auch wieder richtig geladen mit einem Ball oder fehlt da noch irgendwas?
Um da helfen zu können, müsste ich erst die gegenwärtige Struktur verstehen und akzeptieren. Da kommen zunächst Fragen bzw. Korrekturnotwendigkeiten auf
Das werde ich noch umändern, damit es aussagekräftiger wird. GameOver
hatte ich ursprünglich in der Ballklasse deklariert, weil ich hier auch gesagt habe, dass sich der Zusatnd zu true
ändert, wenn der Ball das Spielfeld unten verlässt. Also damit hätte jeder Ball ein individuelles gameOver
.
Wenn der Ball das Spielfeld verlässt, erscheint es mir intuitiver, wenn er einfach aus der Berechnung heraus genommen, also gelöscht wird. Sind keine Bälle mehr im Spielfeld, das Ball-Array also leer, dann ist das Spiel vorbei.
Danke, ich werde es probieren umzusetzen.
Problem mit dem Ball ist gelöst
Wunderbar!
Hallo zusammen, ich würde bei meiner Abschlussaufgabe gerne die Position auf dem Canvas ermitteln, wo geklickt wird. Habe dabei versucht mit "target" und "clientX" zu arbeiten, jedoch funktioniert das nicht. Ziel ist es, dass das schwarze Panel sich am unteren Spielfeldrand dahin bewegt, wo geklickt wird und somit der Ball dort abprallen kann.
Meine Aufgabe ist hier zu finden: https://github.com/fehren1a/EIA2/blob/master/abschluss_aufgabe/abschluss.html
Link zum Repository: https://github.com/fehren1a/EIA2/tree/master/abschluss_aufgabe
Danke im Voraus schonmal! :)