Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

11

21.04.2011, 09:12

Schon klar. Aber für die Kollision muss von nem Trigger ja irgendwie ne Position und ein Radius oä gespeichert werden. Das passier ja normal in irgendeiner art von "Objekt". Das meinte ich damit;) Wie du das dann genau ausbaust ist ja relativ egal.


Naja nicht unbedingt. Sicher, es kommt auf die Engine an die du verwendest. Ich nutze hier Irrlicht / IrrEdit und erstelle einfach "Empty Scene Nodes" (Leere Knoten). Aus diesen Scene Nodes kannst du anhand ihres Namens, ihrer maximalen Ausdehnung bzw. ihrer BoundingBox alles wichtige errechnen (zumindest für einfache Trigger). So machst du es für den Mapper sehr einfach. Die Scene Nodes kann ich dann nachdem ich die Map gelesen habe einfach verwerfen, da sie ja nur Triggerinformationen darstellen. Alternativ könnte man hier auch noch Lua zu Hilfe ziehen und diese Trigger durch bestimmte Aufrufe implementieren. Bei den Events (z.B. Spieler Tod) mache ich das auch.

Objekte sind immer nicht leere Scene Nodes (z.B. Meshes). Aber sicher ist es nur meine eigene Semantik und nicht auf jedes x-beliebige System übertragbar, da gebe ich dir recht.

Zum Thema DLL:
BlueCobold hat Recht, so etwas gehört normalerweise nicht in eine DLL. Eine Map besteht immer aus zwei Teilen. Einmal den statischen, wo die Welt, die Objekte, die Startpositionen oder ähnlich gespeichert sind. Dieser Teil wird meist mit Editoren modelliert. Der dynamische Teil besteht darin, bestimmte Verhaltensweisen deiner Objekte, eventuelle Regeln in der jeweiligen Map oder Siegbedingungen zu definieren. Diesen Teil kann man bequem in ein Skript (z.B. Lua) auslagern. In einem meiner Projekte kann man bei einem solchen Skript sogar spezielle Regeln für das Spiel definieren - es ist hier dir als Programmierer überlassen wie viel Macht du den Mappern gibst. Meistens ist aber auch ein Event-System oder ähnliches wichtig um Skripte effektiv aufbauen zu können. In C++ gibt es ein solches System nicht, C# hat bereits ein Event-System integriert.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »koschka« (21.04.2011, 09:19)


12

21.04.2011, 18:11

Zitat

Ist ja dann in etwa wie bei WC3 oder nicht?


da ich mich mit wc3 mapping sehr gut auskenne, will ich hierauf noch kurz ne ergänzung/ne information zur verfügung stellen.

im warcraft 3 world editor (editor zum spiel) triggert man mit einer eigens entwickelten scriptsprache (=jass) (wenn wir mal von der script gui absehen).

im trigger editor (teil des world editors) kann man sich dann "triggerblätter" erstellen, die man mit code füllt (meistens eben trigger).

einem trigger kann man dann diverse events registrieren, z.b. call TriggerRegisterUnitEvent( meineEinheit, PLAYER_UNIT_EVENT_DAMAGED ) um einem leeren trigger das event hinzuzufügen, sodass der trigger auslöst, wenn "meineEinheit" schaden nimmt.

des weiteren kann man dann jedem trigger eine condition und eine action funktion hinzufügen, wobei imo die unterteilung hier wenig sinn macht:
call TriggerAddCondition( meinTrigger, Condition( function meineCondFunction ) )
call TriggerAddAction( meinTrigger, function meineActionFunction )

dadurch ruft der trigger automatisch die funktion meineCondFunction auf, wenn das Event auslöst. Sofern diese funktion dann true zurück gibt, wird auch die meineActionFunction ausgeführt. der typ einer condition funktion ist immer:
function meineCondFunction takes nothing returns boolean

hat also keine argumente und gibt eben einen boolwert zurück, ob die bedingung eintrat oder nicht. um nun auf meineEinheit z.b. zuzugreifen, gibt es weitere funktionen, wie z.b. GetTriggerUnit(), die die einheit zurückgibt, die das event ausgelöst hat oder GetEventDamageSource() um die einheit zu erhalten, die meineEinheit verletzt hat.

action funktionen haben immer dne typ:
function meineActionFunction takes nothing returns nothing

hat also keine argumente und keinen rückgabewert. in ihr wird dann der tatsächliche code ausgeführt (z.b. schaden reflektieren, oder die einheit von der angreifenden einheit wegteleportieren, usw.).


zusammengefasst:
trigger basieren auf dem ECA (event, condition, action) prinzip. einem trigger registriert man immer events, bei denen er auslösen soll, eine cond function, die true zurückgeben muss um die actionfunction auszulösen.

das event wird dann im bsp. von meineEinheit ausgelöst. irgendwann wird ja dann eine funktion ausgeführt, die den schaden an meineEinheit verteilt und dort werden dann alle trigger notified (denke mal,das geht über observer), bei denen meineEinheit über TriggerRegisterUnitEvent registriert wurde.