CNDG
Würden Sie gerne auf diese Nachricht reagieren? Erstellen Sie einen Account in wenigen Klicks oder loggen Sie sich ein, um fortzufahren.


Ein Forum, in dem sich neue Clonk Entwickler untereinander austauschen können.
 
StartseiteStartseite  PortalPortal  SuchenSuchen  Neueste BilderNeueste Bilder  AnmeldenAnmelden  LoginLogin  

 

 Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop

Nach unten 
AutorNachricht
Flinti
Kadett
Kadett



Männlich Alter : 31
Anmeldedatum : 07.04.09

Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop Empty
BeitragThema: Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop   Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop EmptyMo Nov 09, 2009 1:38 pm

Willkommen zu meinem zweiten Tutorial über Effekte. Ihr erwartet jetzt sicherlich ein Tutorial über Zauber, aber ich schiebe erstmal noch ein Tutorial über allgemeine Grundlagen der Effekte dazwischen. Dieses Tutorial ist sehr komplex, daher habe ich mich entschieden, Beispielobjekte zu erstellen. Auch ist es wieder nur der erste Teil eines großen Tutorials, da dieses Tutorial einmal "sacken" muss, weil es so komplex ist, und weil ich aus Zeitgründen nicht das vollständige Tutorial fertigstellen kann und ich euch nicht zu lange(bzw ist es ja schon zu lange) vorenthalten möchte. Seht dieses Tutorial als das erste Kapitel eines großen Tutorials. Sollte auch nur der klitzekleinste Problem bestehen, bitte ich nachzufragen, damit ich Unklarheiten schnell beseitigen kann. Irgendwelche Morddrohungen oder Lobgesänge sind hier fehl am Platz Wink

GRUNDVORAUSSETZUNGEN:
-Evtl.: Effekte als Timer
-Funktionsdefinition und -aufruf, Rückgabewerte
-bestenfalls Schleifen (for, for in)
-Objektdefinition vs Objektinstanz
-und natürlich: #STRICT 2!

(Ich verwende Variablen- bzw. Parameternamen als Synonyme für das, was sie bedeuten; so steht idCmdTarget z.B. für eine dort angegebene ID und dementsprechend auch für die damit verbundene Definition)

Einer der größten Vorteile der Effekte ist, dass Effekte theoretisch vollkommen Objektunabhängig sind. Einmal erzeugt, sind sie, falls gewünscht, vollkommen von der Existenz des erzeugenden Objektes unabhängig(genauer: Von der Existenz der Objektinstanz). Selbstverständlich können sie aber auch abhängig vom erzeugenden Objekt sein, falls gewünscht, und sind dann immer noch praktischer als Aktionen, da ein Objekt nahezu unendlich Effekte erhalten kann. Betrachten wir dazu folgende Beispiele, jeweils ein Partikelkreis-Flint, der um alle Objekte im Partikelkreisradius einen Partikelkreis zeichnet, und dies 3 mal im Abstand von 10 Frames:



1. Objekt, Partikelkreisflint mit objektabhängigem Effekt:

Code:

#strict 2


public func Hit()
{
   DrawParticleCircle(this, 70, RGB(0, 255));
   for(var obj in FindObjects(Find_Distance(70), Find_NoContainer(), Find_Exclude(this)))
      AddEffect("IntParticleRing", obj, 1, 90, this, 0);
}

public func DrawParticleCircle(object pTarget, int iRadius, int iClr)
{
   for(var i=1; i <= 360; i+=2)
      pTarget->CreateParticle("NoGravSpark", Cos(i, iRadius), Sin(i, iRadius), 0, 0, 50, iClr, pTarget);
}

protected func FxIntParticleRingTimer(object pTarget, int iEffectNumber, int iEffectTime)
{
   if(iEffectTime > 90*3)
      return -1;
   
   DrawParticleCircle(pTarget, 20, RGB(255));
}


2. Objekt, Partikelkreisflint mit objektunabhängigem Effekt:

Code:

#strict 2


public func Hit()
{
   DrawParticleCircle(this, 70, RGB(0, 255));
   for(var obj in FindObjects(Find_Distance(70), Find_NoContainer(), Find_Exclude(this)))
      AddEffect("IntParticleRing", obj, 1, 90, 0, GetID());
}

public func DrawParticleCircle(object pTarget, int iRadius, int iClr)
{
   for(var i=1; i <= 360; i+=2)
      pTarget->CreateParticle("NoGravSpark", Cos(i, iRadius), Sin(i, iRadius), 0, 0, 50, iClr, pTarget);
}

protected func FxIntParticleRingTimer(object pTarget, int iEffectNumber, int iEffectTime)
{
   if(iEffectTime > 90*3)
      return -1;
   
   DrawParticleCircle(pTarget, 20, RGB(255));
}


probiert beide Flints aus. Ihr werdet keinen Unterschied in der Funktionsweise bemerken. Fügt nun aber am Ende der Hit-Funktion ein 'RemoveObject();' hinzu; sonst wäre das ganze ja auch kein Flint. Bemerkt ihr jetzt den Unterschied?

Überlegt mal, woran das wohl liegen könnte. Solltet ihr nicht darauf kommen: Die Lösung kommt später!


Im letzten Tutorial hatte ich die Parameter von AddEffect erwähnt. Dies waren aber noch nicht alle. Seht nun das:

AddEffect (string szEffectName, object pTarget, int iPrio, int iTimerIntervall, object pCmdTarget, id idCmdTarget, any var1, any var2, any var3, any var4)


...die ersten Parameter sind und natürlich bereits geläufig(oder werden uns vom C4-scripter angezeigt Very Happy)

idCmdTarget: Bestimmt das Objekt, in dem die Fx*-Funktionen aufgerufen werden sollen. Diesmal allerdings als ID, sodass die Funktionen so ausgeführt werden, als wäre das Objekt gar nicht da. Das heißt, man kann dann nicht auf lokale Variablen zugreifen oder 'this' benutzen.

Die restlichen Parameter sind vorerst noch unwichtig.


Ihr bemerkt, dass der Parameter 'idCmdTarget' anstatt 'pCmdTarget' benutzt wurde. Genau das ist der Unterschied. Einzig und allein dieser Parameterwechsel. Ist nämlich 'pCmdTarget' angegeben, wird der Effekt entfernt, wenn pCmdTarget gelöscht wird(wo sollen auch die Funktionen aufgerufen werden, wenn das Funktionszielobjekt nicht mal mehr existiert? =O), der Timer wird nicht mehr aufgerufen. Natürlich wird der Effekt auch gelöscht, wenn pTarget gelöscht wird (oder stirbt) ist, denn was soll der Effekt dann ohne Zielobjekt? Dies kann man zu seinem Vorteil nutzen: Es gibt eine spezielle Effektfunktion, die beim Löschen des Effektes aufgerufen wird, Fx*Stop. Erweitern wir also das script der beiden Flints um einen Fx*Stop-Callback, sodass jedes Objekt nach dem Erzeugen der Partikelkreise einen Feuerwerksstein abschießt(dieser funktioniert auch wieder mithilfe eines Effektes, dessen AddEffect-Parameter euch sicherlich leicht verwirren):

Code:

protected func FxIntParticleRingStop(object pTarget, int iEffectNumber, int iReason, bool fTemp)
{
   var rock = CreateContents(ROCK, pTarget);
   AddEffect("IntFireworkRock", rock, 1, 1, 0, 0);
   pTarget->Exit(rock, 0, 0, Random(360), RandomX(-2,2), -12);
}

// Zusätzlich Beispiel für globale Effekte
global func FxIntFireworkRockTimer(object pTarget, int iEffectNumber, int iEffectTime)
{
   if(iEffectTime > 30)
      return -1;
   pTarget->CastParticles("SparkL", 4, 2, RandomX(-1,1), RandomX(-1,1), 7*5, 9*5, RGB(255), RGB(255), pTarget);
}

//Die Parameter iReason und fTemp werden später erklärt, da sie für die absoluten Grundlagen unwichtig sind
global func FxIntFireworkRockStop(object pTarget, int iEffectNumber, int iReason, bool fTemp)
{
   pTarget->Explode(10);
}

Zusätzlich seht ihr globale Fx*-Funktionen. Solche Funktionen werden aufgerufen, wenn sowohl idCmdTarget als auch pCmdTarget 0 sind(Also ist der Effekt keinem Objekt zugeordnet, sondern halt einfach global). Jedes Objekt, sowie das Szenarioscript(sowie natürlich die Engine-Konsole), kann also einen Effekt, der global ist, erzeugen. Es reicht also, wenn ihr in einem der Beiden Beispielflints die globalen Funktionen für den Feuerwerksstein angebt, und in dem anderen nur den Effekt "IntFireworkRock" erzeugt. Die Beispielflints sind auf genau diesem Stand. Jetzt könnt ihr Beispielsweise auch testen, ob Fx*Stop() aufgerufen wird, wenn pCmdTarget gelöscht wird(Überlegt zuerst aber - kann eine Funktion in einem gelöschten Objekt aufgerufen werden? Wink ).


Aber gehen wir weiter auf idCmdTarget und pCmdTarget ein. Wird pCmdTarget angegeben, werden die Fx*-Funktionen als Object-Calls ausgeführt. Das heißt, dass die Funktionen ganz simpel im angegebenen Objekt ausgeführt werden, wie z.B. Hit. Man kann auf lokale Variablen zugreifen und this verwenden. Wird allerdings idCmdTarget angegeben, werden die Fx*-Funktionen als Definition-Call ausgeführt: Die Funnktionen stehen in dem Objekt, haben aber keinerlei Zugriff auf den this-Zeiger oder lokale Variablen, da sie aufgerufen werden, ohne dass sie irgendeinen Bezug zu einer Objektinstanz hätten, sie haben nur etwas mit der Definition gemeinsam, nämlich dass sie im script der Definition stehen XD.
Der Vorteil von Definition-Calls gegenüber Objekt-Calls liegt auf der Hand: Es interessiert weder die Engine, noch irgendeinen Toten, ob irgendein Objekt vom Typ des idCmdTargets im Szenario existiert (Um es genauer zu sagen: Ob irgendeine Instanz dieses Objektes existiert).


Soweit also zu id- und pCmdTarget, globalen Effekten und (teilweise) Fx*Stop.

Darüberhinaus entschuldige ich mich schonmal für die Rächtschraipfeela. Ich werde sie mit der Zeit beseitigen Smile


-> Tutorial 2.2: Effektvariablen - Effekte als Datenspeicher und Blindeffekte ohne Fx*-Funktionen - sinnlos?
Nach oben Nach unten
Flinti
Kadett
Kadett



Männlich Alter : 31
Anmeldedatum : 07.04.09

Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop Empty
BeitragThema: Re: Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop   Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop EmptyDi Nov 10, 2009 3:00 pm

Arg, wie dämlich. Hab doch gleich die Beispiele vergessen. Hier sind sie;:

http://cndg-hochlader.bplaced.net/Partikelflints.c4d



EDIT: Außerdem fällt mir auf, dass manche Grundvoraussetzungen gar nicht in irgendeinem Tutorial behandelt werden - doof :/
Nach oben Nach unten
 
Flinti Tutorial 2.1: Von pCmdTarget und idCmdTarget, globalen Effekten und Fx*Stop
Nach oben 
Seite 1 von 1
 Ähnliche Themen
-
» Problem mit den Effekten
» Vertices Tutorial
» Haus Bau Tutorial
» WettRennen Tutorial

Befugnisse in diesem ForumSie können in diesem Forum nicht antworten
CNDG :: Fortgeschrittene :: Tutorials-
Gehe zu: