Pinball-Game / JavaScript: Wie kann ich die Kollisionserkennung implementieren?
Hallo zusammen,
ich muss für die Uni ein kleines Single Page 2D-Spiel entwickeln. Die Backend REST-API mit Python, das Frontend mit HTML/CSS, die Logik mit JavaScript. Die Animationen sollen wir selbst entwickeln und nicht z.B. von canvas-Objekten übernehmen.
Ich versuche zurzeit ein Pinball-Spiel (Flipper-Automaten) und habe das Grundgerüst mit CSS gebaut. Nur habe ich mir die Kollisionserkennung deutlich leichter vorgestellt, als sie wahrscheinlich ist.
So sieht das Spielfeld momentan aus:
Die JavaScript-Logik sodass der Ball im Spielfeld bleibt, ist ja recht simpel:
var ball = document.getElementById('ball');
var playArea = document.getElementById('play-area');
var ballRadius = 10;
var playAreaWidth = playArea.offsetWidth; // 600
var playAreaHeight = playArea.offsetHeight; // 820
var ballX = playAreaWidth / 2; // Startposition des Balls in der Mitte des Spielfelds
var ballY = playAreaHeight / 2; // X = 300, Y = 410
var ballSpeedX = 3; // Geschwindigkeit des Balls in horizontaler Richtung
var ballSpeedY = 3; // Geschwindigkeit des Balls in vertikaler Richtung
function updateBallPosition() {
// Aktualisiere die Position des Balls basierend auf der aktuellen Geschwindigkeit
ballX += ballSpeedX;
ballY += ballSpeedY;
if (ballX + ballRadius > playAreaWidth || ballX - ballRadius < 0) {
ballSpeedX *= -1; // Richtungswechsel in der horizontalen Richtung
}
if (ballY + ballRadius > playAreaHeight || ballY - ballRadius < 0) {
ballSpeedY *= -1; // Richtungswechsel in der vertikalen Richtung
}
// Setze die neue Position des Balls
ball.style.left = ballX + 'px';
ball.style.top = ballY + 'px';
}
// Aktualisiere die Position des Balls alle 16 Millisekunden (ca. 60 Frames pro Sekunde)
setInterval(updateBallPosition, 16);
}
Aber wie man es implementiert, sodass der Ball von den Hindernissen und Banden richtig abprallt, sodass ein Richtungswechsel entsteht, habe ich noch nicht wirklich verstanden. Hätte da jemand eine Idee oder Erfahrung, wie man hier an die Kollisionserkennung herangehen könnte?
LG und danke im Voraus. :)
1 Antwort
Du hast einen Zeitschritt t.
In diesem Zeitschritt bewegt sich deine Kugel von x(t-1) zu x(t). (Wir vernachlässigen einmal andere bewegte Objekte, wird etwa skomplizierter damit ist aber noch recht ähnlich).
Es entsteht ein Liniensegment zwischen x(t-1) und x(t). Du suchst jetzt Schnittpunkte mit allen deinen Objekten (also mit deren äußeren Hülle). Oder mit allen Objekten in der Nähe des Liniensegmentes.
Wenn du den Schnittpunkt gefunden hast, dann kannst du eine Kollisionsbehandlung durchführen. Wie genau die aussieht hängt davon ab, wie du die implementieren möchtest und ob du nur lineare Geschwindigkeiten hast oder auch anguläre.
Im Grunde musst du aber ein Gleichungssystem lösen, sodass die neuen Geschwindigkeiten gleich sind.
Oder aber du machst das ohne explizit ein Gleichungssystem aufzustellen, siehe dafür auch:
https://en.wikipedia.org/wiki/Collision_response
Auch hilfreich:
https://en.wikipedia.org/wiki/Elastic_collision
Also man kann an sich, recht kompliziert, schauen, ob sich Elemente im Browserfenster überlappen. Das bringt dir aber eher weniger.
Ich kenne keine Javascript Physics-Bibliotheken. Allzuschwer ist das auch nicht zu implementieren, man kann ja z.b. auch anstatt impulsbasierte Kollision einfach nur die Richtung ändern oder so.
Danke dir! Ja, die Grundidee habe ich erstmal verstanden. Ich hätte allerdings gedacht, dass es leichter wäre die Kollisionserkennung mit der Hülle der Css-Elemente zu implementieren (z.B. dass es eine direkte Möglichkeit gibt, sofern der Ball mit zB dem roten Trapez in Berührung kommt einen Richtungswechsel durchführt, je nachdem mit welcher Seite des Trapezes, ändert sich die Laufbahn des Balls entsprechend. Kennst du vielleicht physics Bibliotheken, die für so etwas geeignet sind, oder hättest du eine andere Idee wie man an das Ganze rangehen könnte?
Ein Teil der Playarea sieht zurzeit so aus:
html: https://prnt.sc/36OkEqZzDZVd
css: https://prnt.sc/NOrsIfE-zPI9