[C++/DX] Level und Kollision in Spielen (Shootern)

Skid

Erfahrenes Mitglied
Hallo,

ich bin derzeit dabei ein eigenes Projekt aufzuziehen, dass auf einem älteren Shooter basiert. Jedoch bin ich mir nicht sicher, was die Levels, die Interaktion und Kollision angeht.

Aber erst mal alles nacheinander:
In Shootern, wie Battlefield oder Quake, werden verschiedene Levels in die Szene geladen. Meine Frage ist jetzt, wie dieses Levels aufgebaut sind ? Das heißt werden diese über einen separaten Level-Editor erzeugt ? Oder einfach nur in Maya zusammengebaut ?
Wie erfolgt das Laden ? Wird das Levelmesh komplett geladen oder die einzelnen Fragmente und Segmente des Levels (Wände, Stühle etc.) ?

Eine weitere Sache, die eigentlich unmittelbar mit dem Level und dem Charakter zusammenhängt ist die Interaktion und Kollision mit dem Level. Als Spieler ist es klar, dass dieser sich auf der Oberfläche des Meshs bewegt und sich ebenfalls nicht durch Wände bewegen kann. Das heißt eine zuverlässige Kollisionabfrage muss realisiert sein. Jetzt habe ich schon einiges darüber gelesen. Simple Sachen wie Kollisionabfragen in 2D-Spielen beispielsweise über Bounding-Boxen bis hin zu Kollisionabfrage in 3D-Welten beispielsweise mit Octrees.
Wie kann ich eine Kollision mit nicht-trivialen (beispielsweise unförmige Objekte, keine Würfel) Weltelementen realisieren ?
Bei dieser Octreesache verstehe ich zwar das Konzept, wenn ich allerdings eine Welt als komplett als Mesh laden würde, dann würde der Spieler doch theoretisch nur mit der ganzen Welt kollidieren können, oder habe ich das falsch verstanden ?

Also wie ihr seht, Fragen über Fragen. Leider können meine Bücher darüber keine Auskunft verleihen, da diese meist in andere Richtungen gehen, was Spieleprogrammierung angeht.

Beste Grüße,
SKiD.
 
Hi

In Shootern, wie Battlefield oder Quake, werden verschiedene Levels in die Szene geladen. Meine Frage ist jetzt, wie dieses Levels aufgebaut sind ? Das heißt werden diese über einen separaten Level-Editor erzeugt ? Oder einfach nur in Maya zusammengebaut ?
Vermute mal, dass jedes größere Spiel einen Leveleditor hat.
Bei Quake (und HalfLife/CounterStrike, die technisch davon abgeleitet sind)
gibts sicher einen.

(
Falls es interessant ist: Valves "Hammer"-Editor.
Speichert die Level zuerst als Koordinaten von den Flächen,
muss dann mit einem zweiten Programm zum Spiel-Level kompiliert werden (kein programmiermäßiges kompilieren, aber eine Verarbeitung eben.
Dann wird uA.auch Beleuchtung berechnet, und eine gewisse Optimierung
(irgendwie berechten, was man von wo aus sehen kann
und was deswegen wann weggelassen werden kann)
Vom Übersetzerteil (Zoners Halflife Tool) gibts auch Quellcode zum reinschauen.
Nicht einfach, aber da kann man sich was abschauen :)
)



Wie erfolgt das Laden ? Wird das Levelmesh komplett geladen oder die einzelnen Fragmente und Segmente des Levels (Wände, Stühle etc.) ?
Wahrscheinlich je nach Spiel anders. Bei den oben genannten kommt das komplette Level,
es wurde aber beim Erstellen (wie gesagt) schon so eine Sichtberechnung gemacht.

Simple Sachen wie Kollisionabfragen in 2D-Spielen beispielsweise über Bounding-Boxen bis hin zu Kollisionabfrage in 3D-Welten beispielsweise mit Octrees.
Methoden gibts viele...
BBoxen kann man genausogut im 3D Verwenden (siehe Bild) .
Ist zwar nicht ganz realitätsnah, aber performancemäßig eventuell ein Vorteil

Wie kann ich eine Kollision mit nicht-trivialen (beispielsweise unförmige Objekte, keine Würfel) Weltelementen realisieren ?
Die bestehen ja auch nur aus Flächen/Dreiecken.
Aber, um welche Methode gehts jetzt eigentlich?
 

Anhänge

  • aut.mdl.JPG
    aut.mdl.JPG
    25,8 KB · Aufrufe: 26
(
Falls es interessant ist: Valves "Hammer"-Editor.
Speichert die Level zuerst als Koordinaten von den Flächen,
muss dann mit einem zweiten Programm zum Spiel-Level kompiliert werden (kein programmiermäßiges kompilieren, aber eine Verarbeitung eben.
Dann wird uA.auch Beleuchtung berechnet, und eine gewisse Optimierung
(irgendwie berechten, was man von wo aus sehen kann
und was deswegen wann weggelassen werden kann)
Vom Übersetzerteil (Zoners Halflife Tool) gibts auch Quellcode zum reinschauen.
Nicht einfach, aber da kann man sich was abschauen :)
)

Stimmt vollkommen. Der Hammer Editor wird z.B. auch bei Portal bzw. Portal 2 benutzt.
Zumindestens da (vermutlich aber bei allen "Hammer"-Spielen) wurde noch eine andere,
meiner Meinung nach sehr interessante Technik benutzt.
Es gibt spezielle Objektgruppen. Eine wäre z.B. die Statische. Zu dieser gehören Wände, Boden und Decke, aber auch "Verschönerungen" wie Schaltkästen an den Wänden.
Dann gibt es auch noch Dynamische Objekte. Mit ihnen Kann der Spieler agieren.
Ich denke damit kann man auch einiges an Performance rausholen. Somit berechnet man z.B. eine Lightmap für die Statischen Objekte. JE nach Qualitätseinstellung berechnet man die für Dynamische zu Laufzeit, oder lässt sie ganz weg und beleuchtet das Objekt mit einer (ortsbedingten) Durchschnists-Heligkeit. Ich bin mir nicht sicher ob das nun so bei Portal gemacht wird, aber ich denke schon. Und selbst wenn nicht denke ich das es die Berechnungen beschleunigen kann.
Natürlich solltest du mehr als nur zwei Gruppen haben. Ich bin mir nicht sicher aber ich glaube Portal hat 4. So könnte man habel und Knöpfe in eine Packen (unbeweglich, interagierbar), Zugbrücken, Türen, Fallen in eine andere (beweglich, interagierbar/ereignisgesteuert)

Ich hoffe ich konnte helfen.
Nico
 
Bei mir läuft das so, dass ein Level aus mehreren Statischen Objekten aufgebaut ist, oder einfach als ein Modell. Die dynamischen Objekte mache ich mit dem Editor. Das ganze wird in eine Map gespeichert und kann von der Engine geladen werden. Bei Kollision verwende ich einfach Newton Game Dynamics. Ist Kostenlos, gut, schnell, und ist auch sehr gut als Physikengine zu gebrauchen ;)
MfG
 
Guten Morgen! ;) Danke euch für die Antworten.

Also wird im Grunde generell mehr mit Engines gearbeitet, statt von Scratch (zumindest was große Spiele/Entwickler angeht) ?
Mich hätte die Geschichte, auch im Rahmen eines Projektes interessiert, jedoch frage ich mich häufig, ob manch eine Lösung auch gleichzeitig effektiv ist.

In "großen" Spielen, wie Portal, Half-Life, Dungeon Defenders oder Unreal werden denke ich sicherlich extra erstellte Level-Editoren verwendet. Die Sache ist aber die, dass ich mich nicht unbedingt damit beschäftigen möchte, einen Editor zu bauen, sondern viel mehr damit, ein Spiel zu entwickeln. ;)
Deswegen fragte ich auch, in welche Richtungen so gearbeitet wird und ob es besser sei eher das Level Elementweise zu laden, statt komplett. Die BBox-Methodik ist mir auch (u.a. durch das Praktikum) bekannt und wahrscheinlich auch eines der einfachsten Methoden. Wahrscheinlich könnte ich darauf auch zurück greifen, weil ich nicht unbedingt eine Engine verwenden möchte (es soll ja kein Mega-Spiel werden, sondern nur etwas als "Einstieg").

Was mich dabei jedoch interessieren würde, wenn es um diese Kollision geht und der Bewegung auf der Oberfläche. Wie realisiert man, dass ein Spieler wirklich auf einer Oberfläche läuft ? Misst man permanent den Abstand zwischen Kamera und dem Boden ? Was passiert bei Treppen ? Werden dann die Bounding-Boxen betrachtet ?

Werden Lightmaps auch in 3D-Spielen verwendet ? Ich dachte immer, dass das extra für 2D-Spiele entwickelt sei, beziehungsweise nur dort funktionieren kann ?
Wahrscheinlich muss ich mich dann nochmal genauer mit der Beleuchtung und der Aufgliederung der zu beleuchtenden Objekte befassen. Die Techniken sind mir dabei bisher noch weniger bekannt, kenne aber schon traditionelle Sachen.

Ich habe auch schon in einigen Büchern gestöbert und geschaut, aber irgendwie ist das alles eher unpassend, da man sich eher mit der Programmierung von expliziten Spielen befasst, statt mit den Techniken, Mitteln und Möglichkeiten.

Methoden habe ich bisher noch nicht implementiert. Ich habe bisher nur das Grundgerüst (Implementierung DirectX etc.). Das liegt daran, dass ich nicht unbedingt Zeit in die falschen Dinge investieren möchte, was dazu führt, dass ich evtl. nochmal alles umbauen muss. :)
 
Naja, da du ja vermutlich ein 3D Spiel schreiben willst würde ich schon auf eine Engine setzten. Zumindestens eine Physik Engine. Den abstand zum Boden und zur Kamera immer zu messen ist meiner Meinung nicht wirklich eine gute Idee. Ok, wenn der Boden nie tiefer wird, kann man es so machen (habe ich bei meinen ersten veruschen in "Liberty BASIC" auch gemacht ;D ) allerdings wird das ganze dadurch recht statisch. Das was ich damals gemacht habe war nur 2D und trotzdem nicht wirklich schön.
Ich würde für das ganze Boundingboxen und eine schnelle und gute Physikengine nehmen.
Des weiteren würde ich es ähnlich wie bei Portal (2) machen, und immer ein paar Level zusammenpacken (je nachdem wie komplex bzw. groß ein Level ist auch nur ein einziger). Dieser wird dann komplett geladen. Du musst nur aufpassen das, wenn du mehrere LEvel in eins zusammenpackst, das ganze nicht zu groß wird. Größere Spiele packen die Story meistens direkt in die Leveldatei. Das macht das ganze Dynamischer, benötigt aber auch ein eigenes (Datei-)Format für Level. Ich vermute mal du willst einen kleienn Ego-Shooter schreiben, oder? Wenn du nicht gerade Türen haben willst die sich erst dann öffnen, wenn man z.B. einen Knopf gedrückt hast oder eine gewisse Anzahl von Gegnern umgebracht werden muss, solltest du das Level am besten mit Blender oder einer anderen 3D Software erstellen. Dabei würde ich jedoch alles nur aus Würfeln zusammenbauen. Wenn du fertig bist, musst du dann aber eine zweite Datei anlegen, in der du dann in einem von dir ausgedachten Format die 3D Daten der Würfel reinpackst und so später im Spiel Bounding Boxen zu generieren. Oder du generierst die Bounding Boxen beim Laden des Levels was allerdings etwas schwieriger sein könnte. Da könnte man es aber so machen, das man nur extrem einfache 3D-Modelle herstellt, z.B. Würfel mit den Maßen 1x1x1 oder 1x10x50, etc. und in deiner Leveldatei nur verweise auf diese Modelle speicherst. Das ist den zwar etwas schwerer das Level ohne Level-Editor zu bauen, macht es dir aber im Spiel selbst einfacher die Bounding Boxen zu erstellen.

Bei den Lightmaps so wie ich sie kenne hab ich nur eine sehr grobe Vorstellung wie man die überhaupt in 2D benutzen könnte (wobei, langsam versteh ich es ;D ) Lightmapping ist wunderbar für 3D geeignet. Wenn man zu viele Lichtquellen hat wird es an einem gewissen Punkt sogar ehr notwendig eine zu benutzen, da es ansonsten ruckelt. Da du ja nur ein kleines Spiel für den Einstieg machen willst bräuchte man nicht unbedingt eine. Wenn du wirklich nichts dolles haben willst würde ich ehr ein Ambiente hinzufügen. Erstens kann man damit eine Szene relativ einfach einfärben, so das man eine gewisse Stimmung erzielen kann, zum anderen kann man damit relativ schnell eine Szene beleuchten und muss in seiner Leveldatei nicht einmal Eigenschaften für Punktbasierende Lichter einbauen. Dann könnte man ganz einfach die Stärke und die Farbei des Anbients im Header der Leveldatei angeben. Nur ist es eben recht unrealistisch und auch nicht wirklich schön. Für größere Sachen sollte man unbedingt eine nehmen.

Grüße und viel Glück für dein Projekt,
Nico
 
Also wird im Grunde generell mehr mit Engines gearbeitet, statt von Scratch (zumindest was große Spiele/Entwickler angeht) ?
Mich hätte die Geschichte, auch im Rahmen eines Projektes interessiert, jedoch frage ich mich häufig, ob manch eine Lösung auch gleichzeitig effektiv ist.
Es muss ja auch auf die Kosten geachtet werden...
alles neu machen dauert länger.
Aber die Engine kann ja von den Spieleentwicklern sein,
und dann für mehrere Spiele verwendet werden...

Beispiel von oben: Die für Quake entwickelte "GoldSrc"-Engine
ist der Kern von HalfLife, Counterstrike und allen Ableger davon
(insgesamt 12 kommerzielle Spiele plus einige Fanprojekte)
(Ab HL2/CSS ist aber was anderes im Einsatz)
 
Nochmal zum Spielablauf: Ich habe es mit 3 Dateien gelöst. 1. Map für das Level und die Grafik. 2. Eine Script Datei (Lib: Angelscript/Angelcode) 3. Nodedatei für KI.
Zu 2: Man hat dort einen C++ ähnlichen Syntax und kann Funktionen registrieren. Dann kann man in seinem Level eine Fläche machen und sagen wenn der Spieler da rein geht wird die Funktion im Script aufgerufen.
Hier mal ein Beispiel(nicht von mir):
Code:
///////////////////////////////////
// BEGIN GALLERY DOOR SWING OPEN
///////////////////////////////////

//---------------------------------------------

/*When in hall4 gallery door swings open slowly
 */
void CollideAreaGalleryDoor(string &in asParent, string &in asChild, int alState)
{
	SetSwingDoorClosed("door_gallery", false, false);
	SetSwingDoorDisableAutoClose("door_gallery", true);
	
	PlaySoundAtEntity("creaking_door", "joint_door_move_special.snt", "door_gallery", 1.0 / 0.7f, false);
	
	AddTimer("door_gallery", 0.01f, "TimerSwingDoor");
	
	AddDebugMessage("Boho, the gallery door creaks open.", false);	
	
	AddTimer("stopcreak", 2.0f, "TimerStopCreak");
}
(C)2010 FrictionalGames - Amnesia

MfG
 
Zurück