1.0 Einführung 

2.0 Die Anfänge

3.0 Der Hauptscript

4.0 Move-Script

5.0 Kamera

6.0DorfbewohnerKI

7.0 Erste Waffen

8.0 Panels

9.0 Der erste Quest

10.0 Partikel

11.0 Menü

12.0 Abschließung

13.0 Downloads

14.0 Codesammlung

15.0 Frei Belegbare

Steuerung

4.0 Das Move Script
 

 

Das Move Script ist ein ganz wichtiger Bestandteil des Spieles! Ohne ihn könne sich der Spieler nicht bewegen und man könnte das Game nicht spielen! Wenn im Bewegungscode Fehler sind haben die meistens leider die Eigenschaft besonders schnell aufzufallen! Daher muss auf den Bewegungscode besonders aufgepasst werden! Allerdings müssen wir auch noch bedenken das die Kamera den Spieler folgen soll und nicht einfach nur auf den Nullpunkt der Mapp herumsteht! Mit diesen Problemen werden wir uns in diesen Kapitel beschäftigen!

4.1 Bewegen und Kamera

In diesen ersten Abschnitt des Kapitels haben wir das Ziel das der Spieler sich bewegen kann und das die Kamera dem Geschehen folgt! Wenn wir dieses Grundgerüstgeschaffen haben können wir getrost den Code weiter ausbauen! Da dieser Teil jetzt aber sehr wichtig ist wird alles genau erklärt! 

Als erstes kommt der Move-Script dran! Ich habe extra keine Erklärungen gemacht! Sie finden sie alle unten wo jede Befehlszeile schritt für schritt durchgegangen wird!(in die move-wdl):

//in die vars.wdl

var friction;

var dist[3];

var force[3];

on_D= NULL; /* Damit mit D nicht die Framerate etc. kommt (ermöglich w,a,s,d steuerung! */

//In die move.wdl

action move_me
{
player=my;
while(1)

force.pan = -10 * key_force.x; 
my.skill14 = time*force.pan + max(1-time*0.7,0)*my.skill14; 
my.pan += time * my.skill14; 
vec_set(temp,my.x);
temp.z -= 1000; 
trace_mode = ignore_me+ignore_sprites+ignore_models+use_box;
result = trace(my.x,temp); 
if(result > 7)||(result==null) 

force.x = 0; 
force.y = 0;
force.z -=time; 
friction = 1;
}
else 

force.x = 5 * key_force.y; 
force.y = 0;
force.z = -result; 
friction = 0.7; 
}
my.skill11 = time*force.x + max(1-time*friction,0)*my.skill11; 
my.skill13 = time*force.z + max(1-time*friction,0)*my.skill13; 
dist.x=time*my.skill11;
dist.y = 0;
dist.z = time*my.skill13; 
move_mode = ignore_passable;
camera.x=player.x;
camera.y=player.y;
camera.z=player.z+20;
camera.pan=player.pan;
camera.tilt=player.tilt;
ent_move(dist,nullvector); 
wait(1);
action move_me2
{
player=my;
while(1)

force.pan = -10 * key_force.x; 
my.skill14 = time*force.pan + max(1-time*0.7,0)*my.skill14; 
my.pan += time * my.skill14; 
vec_set(temp,my.x);
temp.z -= 1000; 
trace_mode = ignore_me+ignore_sprites+ignore_models+use_box;
result = trace(my.x,temp); 
if(result > 7)||(result==null) 

force.x = 0; 
force.y = 0;
force.z -=time; 
friction = 1;
}
else 

force.x = 5 * key_force.y; 
force.y = 0;
force.z = -result; 
friction = 0.7; 
}
my.skill11 = time*force.x + max(1-time*friction,0)*my.skill11; 
my.skill13 = time*force.z + max(1-time*friction,0)*my.skill13; 
dist.x=time*my.skill11;
dist.y = 0;
dist.z = time*my.skill13; 

//Alternative w,a,s,d Steuerung! 

if(key_a==1) {  dist.y=key_a*time*7.5; }
if(key_d==1) {  dist.y=-(key_d*time*7.5); }
if(key_w==1) {  dist.x=key_w*time*7.5; }
if(key_s==1) {  dist.x=-(key_s*time*7.5); }
if(key_a==1)&&(key_w==1) {  dist.x=key_w*time*5; }
if(key_d==1)&&(key_w==1) {  dist.x=key_w*time*5; }
if(key_d==1)&&(key_s==1) { dist.x=-(key_s*time*5); }
if(key_a==1)&&(key_s==1) { dist.x=-(key_s*time*5); }
if(key_q==1) { force.pan = 10 *key_q; }
if(key_e==1) { force.pan = -10 *key_e; }
if(key_shift==1) { dist.x*=1.5; }
move_mode = ignore_passable;
camera.x=player.x;
camera.y=player.y;
camera.z=player.z+20;
camera.pan=player.pan;
camera.tilt=player.tilt;
ent_move(dist,nullvector); 
wait(1);
}
}

 

Wenn ich richtig liege verstehen sie von den Script herzlich wenig! Daher will ich mal alles Schritt für Schritt durchgehen!

player=my;

Die einfachste Zeile! Sie sagt nur aus das der Player der Spieler ist!

force.pan = -10 * key_force.x; 

Force.Pan soll die Kraft der Rotation sein!! Die soll sein: -10*Key_Force.X! Hier die Erklärung von Key_force.X: (und Y): Key_Force.X umfasst beide Cursortasten nach rechts und links! Wenn Key_Force.X -1 ist dann ist die Taste nach links gedrückt! Wenn sie 1 ist ist die Taste nach rechts gedrückt! Ganz genauso ist es auch bei KEY_force.Y nur da eben mit den Cursortasten nach hinten und vorne!

my.skill14 = time*force.pan + max(1-time*0.7,0)*my.skill14; 

Das ist jetzt eine wirklich schwere Zeile! Die soll bedeuten das my.skill14 die Drehgeschwindigkeit des Spielers ist! Als erstes wird dazu die oben berechnete Kraft der Rotation genommen, das Ergebnis wird dann plus den Positiven Wert von 1-Time*0.7! Wenn Der wert negativ ist wird einfach die 0 genommen!(1-time*0.7,0) ! 

my.pan += time * my.skill14;

Nun wird die Pan Richtung plus my.skill14 mal Time genommen! Nun werden sie sich vielleicht wundern warum sich der Spieler dann nicht immer dreht!! Sie müssen das so sehen: In Force.Pan wird -10 mal KEY_FORCE.X genommen! Nur Key_Force.X ist NULL wenn keine Taste gedrückt ist! 

vec_set(temp,my.x);

Die Zeile heißt das der Vektor my.X in den Vordefinierten Vektor temp kopiert wird! 

temp.z -= 1000; 

Nun wird die Z Achse des Vektors um 1000 Quants verringert!

trace_mode = ignore_me+ignore_sprites+ignore_models+use_box;
result = trace(my.x,temp); 

Hier wird getraced! Falls sie das noch nicht kennen oder gut können schauen sie sich am besten das Kapitel 4.1.1 an! Für alle anderen: Hier wird als erstes der Trace Mode gesetzt und danach wird die Variable result auf das Ergebnis gesetzt! 

if(result > 7)||(result==null) 

force.x = 0; 
force.y = 0;
force.z -=time; 
friction = 1;
}

Wenn nun das Ergebnis größer als 7 Quants ist oder Null Quants (Wenn das Ergebnisse null ist heißt das nicht das der Abstand Null ist sondern das trace nichts gefunden hat! Also das der abstand zum Boden größer als 1000 Quants ist!) ist dann soll er auf der Z Achse den Spieler nach unten bringen! Außerdem wird die Friktion variable (oben definiert) auf 1 gesetzt um die Bodenaziehungkraft zu verstärken!!

else 

force.x = 5 * key_force.y; 
force.y = 0;
force.z = -result; 
friction = 0.7; 
}

Wenn das nicht der Fall ist soll die Vorwärtskraft key_force.y sein und die Kraft nach unten den minus Wert von result! Friktion wird auf normale 0.7 verringert!

my.skill11 = time*force.x + max(1-time*friction,0)*my.skill11; 
my.skill13 = time*force.z + max(1-time*friction,0)*my.skill13; 
dist.x=time*my.skill11;
dist.y = 0;
dist.z = time*my.skill13; // Distanz vertikal

Die ersten beiden Zeilen sind genauso wie oben bei der Drehkraft schon! Die kraft der Vorwärtsbewegung wird auf skills gebracht und geglättet! Nun werden diese Skills auf den Vektor dist (oben definiert) gesetzt!!

if(key_a==1) {  dist.y=key_a*time*7.5; }
if(key_d==1) {  dist.y=-(key_d*time*7.5); }
if(key_w==1) {  dist.x=key_w*time*7.5; }
if(key_s==1) {  dist.x=-(key_s*time*7.5); }
if(key_a==1)&&(key_w==1) {  dist.x=key_w*time*5; }
if(key_d==1)&&(key_w==1) {  dist.x=key_w*time*5; }
if(key_d==1)&&(key_s==1) { dist.x=-(key_s*time*5); }
if(key_a==1)&&(key_s==1) { dist.x=-(key_s*time*5); }
if(key_q==1) { force.pan = 10 *key_q; }
if(key_e==1) { force.pan = -10 *key_e; }
if(key_shift==1) { dist.x*=1.5; }

Dies ist eine alternative Steuerung auf W,S,D,Q,R und A! Die Werte von dist werden neu gesetzt genauso wie die Werte von force.pan!  Auf Q und E wird gedreht ( der force.pan wird verändert! ), auf a und d wird gestrafed und auf S und W wird nach vorne bzw. zurück gelaufen!  Wenn gestrafed wird und gelaufen bewegt man sich nur langsamer nach vorne! Wenn shift gedrückt ist, erhöht sich die Geschwindigkeit um das Einandhalb fache! Auf diese Steuerung bauen die späteren Programmteile auf aber ich verspreche ihnen das sie keine Problem haben werden alles auf die Pfeiltasten Steuerung umzubauen wenn sie wollen!

move_mode=ignore_passable;

Der Move-Mode wird so gesetzt das der Player Passable Blöcke ignoriert!

camera.x=player.x;
camera.y=player.y;
camera.z=player.z+20;
camera.pan=player.pan;
camera.tilt=player.tilt;

Diese Befehle sind einfach nur dazu da das das die X,Y,Z,Tilt und Pan Achse immer die gleichen wie die des Spielers sind!

ent_move(dist,nullvector);

Diese Letzte Anweisung bewegt den Spieler um die dist Werte mit Kollisionserkennung!

Wir haben jetzt einen größeren Schritt gemacht und endlich einen Move-Script geschrieben! Ihnen werden sicher noch viele Fehler Auffallen wie z.B. das man die Kamera mit der Maus nicht bewegen kann! Oder das es keine Animationen oder Walksounds gibt! Dies alles und mehr werden wir jetzt noch machen! Über die Kamera erfahren sie im Sechsten Kapitel mehr!

 

4.1.1 Tracen mit temp!

In diesem Code kommt einmal Ein Trace vor! In diesen Abschnitt versuche ich Ihnen Trace näher zu bringen! 

Trace ist eigentlich nichts weiter als ein dünner Strahl der von einer zu einer bestimmten Position ausgesandt wird und wenn dieser Strahl etwas trifft wird die result variable auf den Wert gesetzt wie weit das Hindernis entfernt ist! In unseren Move-Code kommt Trace in der Beziehung vor das von den Spieler um 4000 Quants nach unten getraced wird! Mit diesem Bildern versuch ich es ihnen mal zu verdeutlichen: 

Noch mal eine Erklärung für die Zeichnung: 

  • Der Vector der Spieler Position wird in Tempo gespeichert ( vec_set(temp,player.X)  )
  • Tempo wird um 4000 Quants an Höhe verringert! Also 4000 Quants unter den Spieler!
  • Jetzt wird zwischen den beiden Positionen getraced ( result=trace(player.x,temp) )
  • Der Abstand zwischen Boden und Player ist jetzt Result!
  • Wenn der Abstand größer als 5 Quants ist soll die Z Position des Spielers verringert! 

4.2 Erweiterung des Codes 

Nun haben wir es geschafft ein Grundgerüst dafür zu schaffen das der Spieler sich bewegen kann! Jetzt wollen wir den Code erweitern, da es doch arg langweilig ist wenn der Spieler sich nur bewegen kann! Der Code soll enthalten

  • Eigenschaft Schwierigkeit
    Springen Mittel bis Schwer
    Ducken Mittel bis schwer
    Schleichen Schwer
    Klettern Einfach bis Mittel

 Wie immer der Code mit allen wichtigen Erklärungen:

4.2.1 Springen

Der Code für Springen ist grundsätzlich nicht so schwer aber er soll in einer Zeichnung verdeutlich werden! :

Hier noch mal Punkt für Punkt

  • Wenn Enter UND Sprungbegrenzung Null ist 
  • Erhöhe die Z Achse und Sprungbegrenzung!
  • Wenn Sprungbegrenzung 25 ist höre auf die Z Achse des Spielers zu erhöhen
  • Durch das Tracen im ersten Teil des Codes wird der Spieler wieder auf die erde zurückgebracht
  • Wenn der Spieler auf der Erde ist setzt Sprungbegrenzung wieder auf null! 

//in die vars.wdl

var sprungbegrenzung=0; //wie hoch man springen darf

//in die move.wdl, in die Player Aktion!
if(key_space==1)&&(sprungbegrenzung<=25)&&(my.erlaube_springen==on)
{
my.skill22=0;
while(my.skill22<100)
{
my.bewegungsart=springen;
//bewege dich nach oben!
dist.z=1;
if(key_a==1) { dist.y=key_a*time*my.geschwindigkeit_skill_springen; } /*Da das hier in einer whileschleife steht 
und andere Funktionen in dieser aktion abgebrochen werden muss man das hier nochmal schreiben! */
if(key_d==1) { dist.y=-(key_d*time*my.geschwindigkeit_skill_springen); }
if(key_w==1) {dist.x=key_w*time*my.geschwindigkeit_skill_springen; }
if(key_s==1)&&(mouse_left==0) { dist.x=-(key_s*time*my.geschwindigkeit_skill_springen); }
if(key_a==1)&&(key_w==1) { dist.x=key_w*time*5; }
if(key_d==1)&&(key_w==1) { dist.x=key_w*time*5; }
if(key_d==1)&&(key_s==1) { dist.x=-(key_s*time*5); }
if(key_a==1)&&(key_s==1) { dist.x=-(key_s*time*5); }
sprungbegrenzung+=1; //erhöhe bei jedem Tick die Variable Sprungbegrenzung
ent_cycle("jump",my.skill22); //Spiele die Anitmation ab (in nächsten Kapitel ausführlich besprochen!)
my.skill22+=time*8; //Anitmationsgeschwindigkeit
camera.x=player.x; //Die Kamera soll beim Spieler bleiben!
camera.y=player.y;
camera.z=player.z+20;
ent_move(dist,nullvector); //Bewege dich um eins nach oben (dist.z=1) 
wait(1);
}
}

 

4.2.2 Klettern

Beim Klettern werden wir eigentlich nicht viel verändern! Wir machen es nur so das wenn der Spieler z.b. Eine Leiter berührt wird dist.X,y und den Neigungswinkel der Leiter ( Für jede Leiter wird ein eigener Skill gemacht) verändert und der Z Achse wird nach oben gebracht! Dabei wird noch eine Animation abgespielt!

//in die vars.wdl

var kletter_geschwindigkeit_hoch[3] = 0, 0, 1; /* Die geschwindigkeit nach oben! 
Die letzte Zahl ist die Z richtung! Also nach oben!! */
var kletter_geschwindigkeit_runter[3] = 0, 0, -1; /* Die Geschwindigkeit
nach unten */

function klettern()
{
wait (1); 
exclusive_global; //einmalig aufrufen!
if (event_type == event_impact && you == player)
{
//Wenn der Spieler die Leiter etc. rammt
while (my.skill5 < my.skill6) 
{
/*Solange die maximale distance zwischen den Spieler und der Leiter nicht überschritten wird!(Setze die Skills im Wed) */
my.skill7 = abs(my.x - player.x) + abs(my.y - player.y); 
if (key_w == 1 && my.z + (my.max_z - my.min_z) / 2 > player.z - (player.max_z - player.min_z) / 2) 
{
//Wenn w gedrückt ist 
move (player,kletter_geschwindigkeit_hoch, nullvector); /*bewege dich nach oben! */
}
if (key_s == 1)
{
/*Wenn s gedrückt ist gehe nach unten */
move (player,kletter_geschwindigkeit_runter, nullvector);
}
wait (1);
}
}
my.skill15 = 0; // Setze die Distanz zwischen Leiter und Spieler wieder auf null!
}

action Leiter
{
my.enable_impact = on;
my.event = klettern;
}

Das sollte eigentlich jedem verständlich sein!

4.3 Animationen und Sounds

4.3.1 Animationen

Nachdem wir es geschafft haben einen halbwegs vernünftigen Move-Code zu Scripten wollen wir es auch noch schaffen das der Spieler sich währen des laufens springens etc. sich auch wirklich bewegt und nicht immer starr bleibt! Dieser Teil läuft eigentlich nur auf die Anweisung

ent_cycle(" Animationsname ", Prozent der Animation)

heraus! Aber über die erfahren sie jetzt mehr:!

 

[code+Erklärung für ent_cycle und Code selbst für Sounds etc.] 

4.3.2 Sounds

Nun bewegt sich der Spieler zwar schon allerdings fehlen noch die Bewegungssounds! Die sind eigentlich mit ein paar if Sätzen leicht einzusetzen! 

Das hier kommt in die var.wdl

var soundzaehler=0; 
sound tap = <tap.wav>; //Diese Datei muss sich natürlich auch in ihren Ordner befinden!
sound drehen = <drehen.wav>;  //Diese auch!

Das hier kommt in den Move-Code ganz nach oben in die While-Schleife

if(key_w==1)||(key_d==1) { soundzaehler+=1; if(soundzaehler>=30)
{ ent_playsound(my,tap,100); soundzaehler=0; } }
if(key_s==1)||(key_a==1) { soundzaehler+=1; if (soundzaehler>=35)
{ ent_playsound(my,tap,100); soundzaehler=0; } }

Im Grunde sind ja Sounds nicht so schwer wenn man sie nicht auf Wege abstimmt (das wird später in diesen Tutorial noch gemacht!), trotzdem nochmal eine kleine Erklärung:

if(key_w==1)||(key_d==1) { soundzaehler+=1; if(soundzaehler>=25)>

{  ent_playsound(tap,100); soundzaehler=0; } }

Das hier heißt ganz einfach das wenn die Taste nach vorne oder nach hinten gedrückt ist soll er den bewegungsound abspielen; (ent_playsound(entity,sound,volume) ) aber erst nachdem Soundzahler größer gleich 16 ist da er sonst versuchen würde 16 mal pro Sekunde einen Sound abzuspielen und das hört sich nicht gut an...!

if(key_a==1)||(key_s==1) { soundzaehler+=1; if (soundzaehler>=20)

{ ent_playsound(my,drehen,100); soundzaehler=0; } }

Hier ist eigentlich das gleiche nur hier soll der Sound gespielt werden wenn sich der Spieler zu Seite dreht! ( Also es wird natürlich ein anderer Sound gespielt den sie allerdings auch haben müssen!)

Mit Ducken etc. ist ja das gleiche also werde ich es nicht noch einmal durchgehen! Nur noch eine wichtige Sache:

if(key_any==0) { soundzaehler=0; } 

Das muss man schreiben damit der soundzaehler nicht manchmal mitten im nach oben zählen aufhört und bei der nächsten Aktion mit z.b 40 statt Null anfängt!  Noch mal als Erklärung: Key_any heiß alle Tasten! Also wenn keine Taste gedrückt ist ist der Soundzähler 0! 

 

                                            Seite(4/20)  zurück   weiter