Schnelles FoV-System

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Schnelles FoV-System

      Hi Community,
      heute will ich ein schnelles Field of View - System für TopDown-Spiele vorstellen. Ich will schon mal vorwegnehmen, dass dieses Tutorial/Example nicht für Anfänger geeignet ist!

      1) Allgemein
      Was ist eigentlich ein FoV-System? Das ist leicht erklärt. Einige von euch haben sich sicher schon gewundert, wie man eine Art Fog of War in TopDown-Spielen implementieren kann, damit der Spieler Teile der Welt oder Gegner, die außerhalb des Sichtbereichs sind, nicht sehen kann. Natürlich könnte man einfach mittels collision_line() checken, ob ein Gegenstand hinter einer Wand ist und diesen dann unsichtbar machen. Jedoch ist dies langsam und auch unschön, da man so keinen Nebel implementieren kann, der das Sichtfeld anzeigt. Ein gutes Beispiel für ein FoV-System ist CS2D.

      2) Theorie
      Dieses System setzt ein Zellensystem vorraus. D.h. der Raum ist in Boolean-Zellen eingeteilt, die angeben, ob eine bestimmte Zelle blockiert oder passierbar ist. Nun brauchen wir ein zweites Boolean-Feld, das angibt welche Zellen im View sichtbar sind. Für dieses verwende ich ein Grid, weil ich in jedem Step alle Zellen auf einen Standardwert zurücksetzen muss (Grids sind in diesem Bereich schneller als Arrays).
      Das System muss man sich jetzt so vorstellen: Das FoV-Grid liegt über dem View und der Spieler befindet sich genau in der Mitte des Views. Nun werden alle Zellen des Grids auf false (= nicht sichtbar) gestellt. Jetzt wird es interessant: Man schickt einen Strahl zu jeder Randzelle und setzt jede Zelle, die man passiert, auf true (= sichtbar) bis man am Ende ist oder eine Wand trifft (= wenn ein False-Wert im Raumfeld auftritt). Die Strahlen werden mit Hilfe des Bresenham-Algorithmus berechnet. Nun hat man ein Grid, das angibt welche Zellen im View sichtbar sind. Mit Hilfe dessen kann man auch das Ganze recht einfach zeichnen und Sichtbarkeitschecks durchführen.

      3) Umsetzung
      Bei dieser reinen GM-Umsetzung habe ich etwas getrickst, damit die Performance akzeptabel bleibt. Bei dieser werden die Strahlen nur einmal berechnet und gespeichert. Daraus folgt leider, dass der Spieler immer in der Mitte des Views sein muss, dafür ist das ganze schneller.

      Bitte ladet euch die *.gmk runter und seht euch den Code an, damit ihr wisst wovon ich spreche:

      Im Room-Creation Code wird das FoV-Grid erstellt und das Surface, welches wir für den Fog verwenden. Das Grid ist größer als der View, da es sonst zu Problemen kommt, wenn sich der View bewegt.
      Im Creation-Event von obj_fov werden die Strahlen berechnet. Zur Erinnerung: Sie werden aus der Mitte des Views zu den Randzellen des Views geschickt. cast_ray() ist nur eine Bresenham-Implementierung, die auch die Strahlen in jeweils ein Array speichert. Zusätzlich wird die Richtung des Strahls in Grad gespeichert. Dies ist wichtig, wenn das Sichtfeld nicht 360° beträgt, sonder eingeschränkt ist.

      Der nächste Schritt ist der wichtigste und wird jeden Step im obj_fov ausgeführt. Er berechnet die sichtbaren Felder und zeichnet diese gleichzeitig auf ein Surface.
      Im Grunde werden alle Strahlen durchlaufen und, wie oben beschrieben, alle Zellen auf sichtbar gesetzt, die passiert werden. Die Richtungschecks sind dafür da, dass nur die Strahlen durchlaufen werden, die für das Sichtfeld relevant sind (Hier beträgt das Sichtfeld 75°).

      Schließlich wird das Surface im Draw-Event von obj_fov, das im Step-Event gezeichnet wurde, über den View gelegt um das Ganze zu visualisieren.

      4) Bessere Variante
      Alle die, die imstande sind eine DLL zu erstellen, können sich jetzt freuen. Anstatt, die Strahlen am Anfang zu berechnen, kann man diese auch jeden Step berechnen, um das System flexibler zu machen. Ich hab das ganze in Delphi realisiert, um eine gute Performance zu erzielen. Im GM könnte diese Methode kritisch sein und die Performance killen. Einen gewaltigen Nachteil hat eine DLL-Implementierung jedoch: Man kann nicht gleichzeitig die sichtbaren Zellen berechnen und auf das Surface zeichnen. Dieses Problem habe ich durch die Verwendung von Quadtrees gedämpft. Näher möchte ich jedoch nicht darauf eingehen.

      5) Quellen
      Grundlage für dieses System bat diese Seite. Den Bresenham-Algorithmus habe ich mit Hilfe von Wikipedia implementiert. dirdiff() ist von GMLScripts.com und das einzige Sprite ist von MasterXY.



      Ich hoffe dieses Tutorial hat einigen geholfen.
      Dateien
      • FoV.zip

        (28,43 kB, 466 mal heruntergeladen, zuletzt: )

      © 2008 by Teamgrill Productions

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Soul Reaver ()

    • Sehr schön, aber ich hätte an deiner Stelle den Code etwas besser kommentiert, damit es verständlicher wird, was genau du da gemacht hast. Ohne Kommentare ist das Einarbeiten in einen fremden Quelltext nicht gerade leicht.

      Aber trotzdem gutes Tutorial.

      MfG Trixt0r

      Albert Einstein schrieb:

      Probleme kann man niemals mit derselben Denkweise lösen, durch die sie entstanden sind.
    • Das ist zwar jetzt weniger ein Tutorial als ein Example aber trotzdem sehr gut. Eventuell das beste was man performant im GM hinkriegen kann auch wenn es nicht so smooth aussieht wegen der zellenstruktur.

      Willst du auf diese Drachen und -eier klicken?
      Sie werden sich freuen ;)
    • Danke für die Antworten,
      ich habe den Quelltext jetzt etwas besser kommentiert. Klar, dass es nicht ganz smooth ist, aber einen entscheidenden Vorteil hat das ganze dann doch: Man kann sehr einfach feststellen, ob der Spieler einen Gegenstand im View sehen kann und das ohne collision_line(). Man könnte es eventuell smoother machen, indem man 8px*8px Zellen verwendet, jedoch bezweifle ich, dass der GM das mitmacht.

      © 2008 by Teamgrill Productions
    • Ich bin in den Credits :D Das wär doch nicht nötig gewesen :love: ^^

      Naja ich kenn dein System ja schon länger. Jetz weiß ich immerhin ein BISSCHEN besser, wie es funktioniert :P

      © 2008 by Teamgrill Productions