Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ss20:neg_theorie [2020/09/11 19:37] srather [Kollisionen] |
ss20:neg_theorie [2020/09/13 14:05] (aktuell) srather [Kollisionen] |
||
---|---|---|---|
Zeile 6: | Zeile 6: | ||
===== Engine ===== | ===== Engine ===== | ||
- | Die Engine basiert auf Python und Pygame. Pygame macht es einfach eine Steuerung per Maus oder Tastatur zu implementieren. Außerdem gibt es Funktionen zum zeichnen von Formen. Das reicht bereits für eine einfache 2D Engine. | + | Die Engine basiert auf Python und PyGame. PyGame macht es einfach, eine Steuerung per Maus oder Tastatur zu implementieren. Außerdem gibt es Funktionen zum Zeichnen von Formen. Das reicht bereits für eine einfache 2D Engine. |
- | Für die Übersichtlichkeit ist die Implementation der Engine Objektorientiert. Die Klassen sind folgendermaßen strukturiert: | + | Für die Übersichtlichkeit ist die Implementation der Engine objektorientiert. Die Klassen sind folgendermaßen strukturiert: |
{{:ss20:neg_struktur.png?nolink&688}} | {{:ss20:neg_struktur.png?nolink&688}} | ||
- | Damit man einfach und übersichtlich Berechnungen durchführen kann, gibt es die Klassen ''Vector'', ''Matrix'' und ''Ray'' mit entsprechenden methoden. Außerdem haben alle darstellbaren Objekte die Superklasse ''drawable''. Diese ist abstrakt und dient dazu, dass verschiedenste Objekte einheitlich benutzt werden können, da zum Beispiel alle Klassen, die von ''drawable'' erben eine ''draw()'' methode haben. Die Klasse ''drawable'' erbt von der Python Klasse ''list'', da die Methoden von PyGame zum zeichnen Punklisten annehmen. So nehmen sie auch "drawables" an. | + | Damit man einfach und übersichtlich Berechnungen durchführen kann, gibt es die Klassen ''Vector'', ''Matrix'' und ''Ray'' mit entsprechenden Methoden. Außerdem haben alle darstellbaren Objekte die Superklasse ''drawable''. Diese ist abstrakt und dient dazu, dass verschiedenste Objekte einheitlich benutzt werden können, da zum Beispiel alle Klassen, die von ''drawable'' erben eine ''draw()'' Methode haben. Die Klasse ''drawable'' erbt von der Python Klasse ''list'', da die Methoden von PyGame zum zeichnen Punktlisten annehmen. So nehmen sie auch "drawables" an. |
- | Als erstes muss die Engine objekte darstellen. Der Einfachheit halber wird der Spieler immer in der Mitte des Bildes als Kreis dargestellt. So muss beim Zeichnen einfach von der Position der Objekte die Position des Spielers abgezogen werden. | + | Als Erstes muss die Engine Objekte darstellen. Der Einfachheit halber wird der Spieler immer in der Mitte des Bildes als Kreis dargestellt. So muss beim Zeichnen einfach von der Position der Objekte die Position des Spielers abgezogen werden. |
{{:ss20:neg_1.png?nolink&688}} | {{:ss20:neg_1.png?nolink&688}} | ||
- | Da ein nichteuklidischer Raum nicht auf die ebene Bildschirmfläche passt, müssen irgendwie die Unstimmigkeiten kaschiert werden. Die einfachste Methode ist es einfach hinter Objekten zu verstecken. Damit das in 2D funktioniert braucht es also Schatten. | + | Da ein nichteuklidischer Raum nicht auf die ebene Bildschirmfläche passt, müssen irgendwie die Unstimmigkeiten kaschiert werden. Die einfachste Methode ist es, hinter Objekten zu verstecken. Damit das in 2D funktioniert braucht es also Schatten. |
{{:ss20:neg_2.png?nolink&688}} | {{:ss20:neg_2.png?nolink&688}} | ||
- | Nun braucht es noch Portale, die die Engine nichteuklidisch machen (eine genaue Erläuterung findet sich weiter [[#portale|unten↓]]). Dafür sind insbesondere wieder die Schatten wichtig, denn da wo eigendlich der Schatten des Portals wäre, soll nun die Portalwelt dargestellt werden. Dazu müssen die zu malenden Objekte außerdem an linien zerschnitten werden können, um nicht über den Portalbereich hinaus gezeichnet zu werden. Um diese Engine einfach zu halten, wird nicht der Spieler teleportiert, sondern die Welt. | + | Nun braucht es noch Portale, die die Engine nichteuklidisch machen (eine genaue Erläuterung findet sich weiter [[#portale|unten↓]]). Dafür sind insbesondere wieder die Schatten wichtig, denn da, wo eigentlich der Schatten des Portals wäre, soll nun die Portalwelt dargestellt werden. Dazu müssen die zu malenden Objekte außerdem an Linien zerschnitten werden können, um nicht über den Portalbereich hinaus gezeichnet zu werden. Um diese Engine einfach zu halten, wird nicht der Spieler teleportiert, sondern die Welt. |
{{:ss20:neg_3.png?nolink&688}} | {{:ss20:neg_3.png?nolink&688}} | ||
Zeile 28: | Zeile 28: | ||
(Hier ist das Portal hervorgehoben; für eine perfekte Illusion ist dies in der Engine nicht der Fall.) | (Hier ist das Portal hervorgehoben; für eine perfekte Illusion ist dies in der Engine nicht der Fall.) | ||
- | Zu guter letzt sind Kollisionen mit den Objekten in der Engine essentiell (eine genaue Erläuterung findet sich weiter [[#kollisionen|unten↓]]). Jede Illusion würde zerbrechen, wenn man einfach durch die Wand gehen kann. | + | Zu guter Letzt sind Kollisionen mit den Objekten in der Engine essenziell (eine genaue Erläuterung findet sich weiter [[#kollisionen|unten↓]]). Jede Illusion würde zerbrechen, wenn man einfach durch die Wand gehen kann. |
===== Portale ===== | ===== Portale ===== | ||
Ein Portal ist eine Linie -- ein gerader, längst begrenzter "Schnitt" im Raum. Dieser Schnitt hat nun 2 Seiten, die man beide mit verschiedenen Orten verbinden ("zusammenkleben") kann. Betrachtet man nun eine Seite des Portals, so soll man an einem anderen Ort herauskommen können. Also braucht es einen Verschiebungsvektor für die Portalwelt. | Ein Portal ist eine Linie -- ein gerader, längst begrenzter "Schnitt" im Raum. Dieser Schnitt hat nun 2 Seiten, die man beide mit verschiedenen Orten verbinden ("zusammenkleben") kann. Betrachtet man nun eine Seite des Portals, so soll man an einem anderen Ort herauskommen können. Also braucht es einen Verschiebungsvektor für die Portalwelt. | ||
- | Für eine gute Illusion verbindet man normalerweise 2 Portale miteinander, sodass man in beide Richtingen gehen kann und im Bestfall gar nichts davon bemerkt. Diese Portale können aber eine unterschiedliche Ausrichtung haben, also muss ein Portal die Welt auch drehen können. Zusätzlich müsste die Welt gestaucht und gestreckt werden können, um Effekte wie den [[ss20:neg_research#weitere_formen|langen/kurzen Tunnel]] nachzustellen. | + | Für eine gute Illusion verbindet man normalerweise 2 Portale miteinander, sodass man in beide Richtungen gehen kann und im Bestfall gar nichts davon bemerkt. Diese Portale können aber eine unterschiedliche Ausrichtung haben, also muss ein Portal die Welt auch drehen können. Zusätzlich müsste die Welt gestaucht und gestreckt werden können, um Effekte wie den [[ss20:neg_research#weitere_formen|langen/kurzen Tunnel]] nachzustellen. |
Um nicht alle Funktionen einzeln darstellen zu müssen, macht die Engine gebrauch der linearen Algebra. Betrachtet man die Welt als einen Vektorraum, so kann eine Basistransformationsmatrix all diese Transformationen auf einmal erledigen und sogar noch Scherungen. | Um nicht alle Funktionen einzeln darstellen zu müssen, macht die Engine gebrauch der linearen Algebra. Betrachtet man die Welt als einen Vektorraum, so kann eine Basistransformationsmatrix all diese Transformationen auf einmal erledigen und sogar noch Scherungen. | ||
- | Somit kann eine Seite eines Portals mit einer Transformationsmatrix und einem Verschiebungsvektor dargestellt werden. Da hierbei alles linear bleibt, d.h. alle Linien gerade bleiben müssen für Polygone nur die Eckpunkte betrachtet werden. Ist $T$ die Transformationsmatrix und $v$ der Verschiebungsvektor, so lässt sich für einen Eckpunkt am Ort $p$ folgendermaßen seine Position im Portal $p'$ berechnen: | + | Somit kann eine Seite eines Portals mit einer Transformationsmatrix und einem Verschiebungsvektor dargestellt werden. Da hierbei alles linear bleibt, d. h. alle Linien gerade bleiben, müssen für Polygone nur die Eckpunkte betrachtet werden. Ist $T$ die Transformationsmatrix und $v$ der Verschiebungsvektor, so lässt sich für einen Eckpunkt am Ort $p$ folgendermaßen seine Position im Portal $p'$ berechnen: |
$p' ~=~ T·p ~+~ v$ | $p' ~=~ T·p ~+~ v$ | ||
Zeile 49: | Zeile 49: | ||
===== Kollisionen ===== | ===== Kollisionen ===== | ||
- | Die Kollisionen sollen lediglich den Spieler daran hindern durch Objekte zu gleiten, aber nicht dahin zu kommen, wo er hin möchte. Bleibt der Spieler einfach stehen, wenn er ein objekt berührt wird es schnell frustrierend. Ist eine Kollisione ein Physikalisch korrekter elastischer Stoß, so springt prallt der Spieler einfach wie ein Ball von dem Objekt ab, meist in die entgegengesetzte Richtung in die der Spieler eigendlich wollte. | + | Die Kollisionen sollen lediglich den Spieler daran hindern, durch Objekte zu gleiten, aber nicht dahin zu kommen, wo er hin möchte. Bleibt der Spieler einfach stehen, wenn er ein Objekt berührt, wird es schnell frustrierend. Ist eine Kollision ein Physikalisch korrekter, elastischer Stoß, so prallt der Spieler einfach wie ein Ball von dem Objekt ab, meist in die entgegengesetzte Richtung, in die der Spieler eigentlich wollte. |
- | Der Verwendete Ansatz betrachtet den Bewegungsvektor des Spielers und entfernt den Anteil, der senkrecht zum Hinderniss steht. | + | Der verwendete Ansatz betrachtet den Bewegungsvektor des Spielers und entfernt den Anteil, der senkrecht zum Hindernis steht. |
Ist $v$ der Bewegungsvektor $w$ die Richtung der Wand, mit der eine Kollision stattfindet. So gibt es einen Vektor $w'$ mit $w·w' ~=~ 0$ (senkrecht zueinander). Dann gilt: | Ist $v$ der Bewegungsvektor $w$ die Richtung der Wand, mit der eine Kollision stattfindet. So gibt es einen Vektor $w'$ mit $w·w' ~=~ 0$ (senkrecht zueinander). Dann gilt: | ||
Zeile 61: | Zeile 61: | ||
Somit ist der neue Bewegungsvektor $v'$ nach der Kollision: | Somit ist der neue Bewegungsvektor $v'$ nach der Kollision: | ||
- | $v' ~=~ v ~-~ μ·w'$ | + | $v' ~=~ v ~-~ μ·w' ~=~ λ·w$ |
+ | |||
+ | {{:ss20:kollision.png?nolink&688}} | ||
+ | |||
+ | Ist das Hindernis keine Linie, sondern ein Punkt, so wird der Vektor vom Spieler zum Punkt als $w'$ interpretiert. | ||
[[#top|↑ Zurück nach oben]] | [[#top|↑ Zurück nach oben]] | ||