Da viele gefragt haben, wie man ein Tor auf Kommando öffnen und wieder
schliesen lassen kann, ist hier ein Tutorial entstanden. Hier wird ein
Schwenktor beschrieben. Dieses ist sehr viel schwerer als ein Schiebetor
zu erstellen!
Drehung in einem 2-Dimensionalen Raum
Um ein Tor zu programmieren braucht man ein paar Mathematische
Kenntnisse. Das Große Problem bei einem Tor ist, wenn man mit der
Funktion SetObjectRot
dreht, der Drehpunkt von den Objekt fast immer in der Mitte ist.
Genauso wie bei unseren Tor (Objectid: Linkes_Tor:985 Rechtes_Tor:986).
Wir nehmen für unser Beispiel blos 1ne Torhälfte wegen der Einfachheit.
Wie gesagt, dass Objekt dreht sich um sein Mittelpunkt, bei der Skize
rechts um den Punkt M. Wir gehen mal davon aus das wir unser Tor um 90°
öffnen wollen. Die Folge davon wäre, dass das Tor am Ende wie die Gelb
gestrichelte Linie dastehen würde. Das wäre natürlich nicht schön.
Jetzt müssen wir eine Lösung finden wie wir den Objekt sagen können,
dass es um den Punkt Z drehen soll. Schön wäre es wenn es eine Funktion
geben würde wie zb: TurnObjectToPoint. Leider gibt es so
eine Funktion nicht und wir müssen uns selber Gedanken machen wie wir
das Objekt drehen lassen können um ein Punkt. Also ab ich im Netz etwas
rumgewühlt und habe diese Formel gefunden:
Sie sieht zwar auf den ersten Blick etwas komisch aus, ist aber richtig.
Das ist eine Matrex-version, von der Drehung um einen Punkt mit den
Koordinaten (0/0). Jetzt wirst du dich wundern: "Warum um den Punkt
(0/0)? Wir wollen doch um einen Beliebigen Punkt irgendwo drehen!" Das
ist mir auch bekannt, deshalb müssen wir sie noch für unsere Zwecke
anpassen:
Nun habe ich die Matrex aufgelöst. Für x und y müssen wir jetzt unsern
Vektor ZM einsetzten. Jetzt muss man nachdenken, wie man den Vektor ZM
rausbekommt (Realschule: 7. Klassse). Natürlich Spitze minus Fus. Das
heist wir müssen die x Koordinaten von M minus die x Koordinaten von Z
und das ganze dann auchnoch für y. Am ende muss man natürlich noch die x
und y Koordinaten von Z dazuzählen. Wenn man das alles richtig gemacht
hat bekommt man den Punkt M'. Und so sieht die Formel dazu aus:
Drehung in einem 3-Dimensionalen Raum (Nicht Wichtig)
Ihr werde ich euch auchnoch die Formel für die Drehung im 3-Dimensionalen Raum vorstellen. Aber sie wird für das Toröffnen nicht gebraucht!.
Also wer keine Lust auf weitere Mathematik hat kann den Teil getrost
überspringen. Für die die irgenwas in 3 Dimensionen drehen wollen, ist
diese Matrize hilfreich:
Ab hier müsst ihr aber alleine zurechtkommen. Zum ersten braucht man ja
wie gesagt die Formel nicht für das Tor und 2. wäre es viel zu
langwierig um alle Details zu erklären und 3. ist die Formel ja auch
fast selbsterklärend.
Wir wollen ein Tor machen. Schon in San Andreas enthaltene Objekte kann
man nicht nutzen! Dafür müssen wie ein geeignetes Objekt einfügen. z.b:
975 - normales Tor
985 - ein rechtes Torstück
986 - ein linkes Torstück
Wir brauchen für unser Test ein Linkes Torstück. Zudem gebe ich geignete Koordinaten für ein Spawn-Punkt an, damit man es schnellstmöglich testen kann und nicht lange suchen muss. Das alles kommt in public OnGameModInit()
AddPlayerClass(0,962.4860,-1109.3821,23.6934,223.7676,0,0,0,0,0,0);
Tor = CreateObject(985,952.55,-1107.5,24,0,0,270);
Wie man schon sieht braucht man auserdem ein Paar Variabelen. Hier wird auf die Variabele Tor die Objekt-ID des Objektes gespeichert. Die Variabelen definierst du gleich hinter #include<a_samp>
new Tor;
new TimerOpen;
new TimerClose;
new Float:drehpunktx = 952.8;
new Float:drehpunkty = -1111.5;
forward TorOpen();
forward TorClose();
Also drehpunktx ist die x Koordinate des Drehpunktes, drehpunkty ist die y Koordinate das Drehpunktes. TimerOpen bekommt die Timer-ID damit man in auch wieder löschen kann, genauso wie Timer Close.
Auserdem werden 2 Funktionen Resaviert. Du kannst sie natürlich umbenennen, musst sie aber im weiteren Verlauf auch immer umbenennen!
Wir machen es jetzt so das man wärend des Spieles einfach /open oder /close eingibt, damit sich das Tor öffnet. Also ab in public OnPlayerCommandText(playerid, cmdtext[]) und das ergänzene:
if (strcmp("/open", cmdtext, true, 10) == 0)
{
KillTimer(TimerOpen);
KillTimer(TimerClose);
TimerOpen = SetTimer("TorOpen", 50, 1);
return 1;
}
if (strcmp("/close", cmdtext, true, 10) == 0)
{
KillTimer(TimerOpen);
KillTimer(TimerClose);
TimerOpen = SetTimer("TorClose", 50, 1);
return 1;
}
Mann muss immer erst beide Timer beenden, weil es sonst passieren kann
das 2 Timer Parallel gehen. Das wäre sehr schlecht, weil sich das Tor
entweder doppelt so schnell dreht, oder beide Timer gegeneinader
abreiten und keiner Gewinnt (Tor ruckelt hin und her, geht aber nicht
auf und zu).
Danach wird immer 1 Timer definiert, der das Tor alle 50 Millisekunden
bewegt. Wer es schneller will muss die Zahl kleiner machen, wer es
langsamer haben will der soll sie Größer machen. Also so:
x = klein dann geht es schneller (aber größere Rechenleistung)
x = groß dann geht es langsamer