c_move(ENTITY* entity,VECTOR* reldist,VECTOR* absdist,var mode)

Bewegt eine Entity über eine bestimmte Entfernung und führt dabei eine Kollisionserkennung, das Auslösen von Kollisions-Events sowie das Entlanggleiten an Hindernissen aus.

Der erste Vektor, reldist, gibt eine relative Stecke und Richtung in gedrehten Entity-Koordinaten, d.h. in Blickrichtung der Entity, an. Der zweite Vektor absdist gibt eine absolute Strecke und Richtung in Weltkoordinaten an. Die daraus resultierende Bewegung besteht aus einer Kombination beider Strecken. Üblicherweise wird der erste Vektor für die Antriebsgeschwindigkeit der Entity und der zweite für äußere Kräfte, wie etwa Schwerkraft und Drift, benutzt. Um einen dieser Vektoren auf Null zu setzen, kann der vordefinierte nullvector angegeben werden.

Die Funktion liefert den Wert der zurückgelegten Entfernung zurück. Wird die Entity von Hindernissen blockiert und konnte sich überhaupt nicht bewegen, wird ein negativer Wert oder 0 zurückgegeben. Sind die Kollisions-Events aktiviert, werden Sie sowohl für die Entity, als auch für das Hindernis ausgelöst. Im Verlauf eines Kollisions-Events werden zur Angabe des Kollisions-Typus einige vordefinierte Variablen gesetzt (siehe unten). Diese können in der Event-Funktion zu jeglicher Art von Beeinflussung des Kollisions- bzw. Abprallverhaltens ausgewertet werden..

Parameter:

entity Zu bewegende Entity
reldist Vektor der Bewegungsstrecke in Entity-Koordinaten (relativer Bewegungsvektor)
absdist Vektor der Bewegungsstrecke in Welt-Koordinaten (absoluter Bewegungsvektor)
mode Kollisionsmodus, siehe unten

Die folgenden mode-flags können kombiniert werden:

IGNORE_YOU Ignoriert die you-Entity bei der Kollisionserkennung (s. Kommentar).
IGNORE_FLAG2  A7.10 Ignoriert alle Entities mit gesetztem FLAG2.
IGNORE_PASSABLE Ignoriert alle passablen Blocks und Entities.
IGNORE_PASSENTS

Ignoriert passable Modell- und Sprite-Entities, nimmt jedoch noch Wasser-Entities (passable rechteckige Maps oder passable Terrains) wahr. Es setzt die vordefinierten Flag s in_passable und on_passable . Der vordefinierte Pointer passable_ent wird auf die erkannte Wasser-Entity gesetzt. So lässt sich das Playerverhalten beispielsweise auf Schwimmen umschalten.

IGNORE_WORLD Ignoriert alle Level-Blocks und Terrains.
IGNORE_MAPS Ignoriert alle Map- und Terrain-Entities
IGNORE_MODELS Ignoriert sämtliche Models
IGNORE_SPRITES Ignoriert sämtliche Sprites
IGNORE_PUSH Ignoriert alle Entities mit einem niedrigeren push- oder gleichem group-Wert als bzw. wie dem der gegebenen Entity und löst bei diesen Entities den Kollisions-Event EVENT_PUSH aus.
IGNORE_CONTENT Ignoriert Wasser-Entities (s.o.). Die Anweisung wird dadurch etwas schneller ausgeführt.
ACTIVATE_TRIGGER Aktiviert EVENT_TRIGGER während der Bewegung
ACTIVATE_PUSH

 A7.10 Löst bei der getroffenen Entity unabhängig von deren push- oder group-Wert den Kollisionsevent EVENT_PUSH aus. Liefert die Event-Funktion 1 zurück, wird die getroffene Entity als Hindernis betrachtet, ist der Rückgabewert 0, wird sie ignoriert. So lassen sich individuelle Kollisionsgruppen definieren.

ACTIVATE_SHOOT

A7.10 Ermöglicht EVENT_SHOOT-Triggering der getroffenen Entity und verhindert alle anderen Kollisionsevents.

ACTIVATE_SONAR

A7.10 Ermöglicht EVENT_SONAR-Triggering der getroffenen Entity und verhindert alle anderen Kollisionsevents.

USE_POLYGON

Benutzt eine polygonale Hülle aller Zielentities auch dann, wenn ihr POLYGON-Flag nicht gesetzt ist.

GLIDE Gleitet beim Auftreffen an Wänden und Entities entlang.

Abhängig von:

move_friction Reibungsfaktor zum Entlanggleiten an Wänden.
move_min_z Maximale Stufenhöhe (nur OBB).
disable_z_glide Schaltet das Hinaufgleiten an Schrägen ab (nur OBB)

Rückgabewerte:

> 0 zurückgelegte Entfernung.
<= 0 Entity konnte nicht bewegt werden, z.B. wg. Hindernissen

Modifiziert:

entity.x, y, z Entity-Position.
hit.x Position eines der Kollisionskontakte (es kann einige geben).
hit.nx Normalen-Vektor einer der kollidierenden Oberflächen.vector of one of the colliding surfaces.
hit.flags Das Makro HIT_TARGET ist ungleich Null wenn etwas getroffen wurde.
in_passable Auf ungleich Null gesetzt, wenn der Start- oder Endpunkt innerhalb einer Wasser-Entity liegt.
on_passable Auf ungleich Null gesetzt, wenn das getroffene Ziel eine Wasser-Entity ist..
passable_ent Ist in_passable oder on_passable gesetzt, ist dieser Pointer auf das ermittelte Wasser-Terrain gesetzt (nur im OBB-System)
event_type Event-Typ bei Auslösung.

Bemerkungen:

Geschwindigkeit:

Langsam

Beispiel (lite-C)::

// simple function for walking over ground
// control the player with the WASD keys
// player origin must be at the model center
// bounding box must be smaller than the player!
action player_walk()
{ 
// if necessary, adjust the bounding box to give the entity 'floor room' (see remarks) 
// my.min_z *= 0.5;

   var speed_down = 0;   // downward speed by gravity
   var anim_percent = 0; // animation percentage
   VECTOR vFeet;
   vec_for_min(vFeet,me); // vFeet.z = distance from player origin to lowest vertex

   while (1)
   {
// rotate the player using the [A] and [D] keys      
      my.pan += 5*(key_a-key_d)*time_step; 

// determine the ground distance by a downwards trace
      var dist_down; 
      if (c_trace(my.x,vector(my.x,my.y,my.z-5000),IGNORE_ME | IGNORE_PASSABLE | USE_BOX) > 0)
         dist_down = my.z + vFeet.z - target.z; // get distance between player's feet and the ground
      else
         dist_down = 0;

// apply gravity when the player is in the air
      if (dist_down > 0)  // above floor, fall down with increasing speed
         dist_down = clamp(dist_down,0,accelerate(speed_down,5,0.1));
      else                // on or below floor, set downward speed to zero
         speed_down = 0;

// move the player using the [W] and [S] keys      
      var dist_ahead = 5*(key_w-key_s)*time_step;
      dist_ahead = sign(dist_ahead)*(abs(dist_ahead) + 0.5*dist_down); // adapt the speed on slopes
      c_move(me,vector(dist_ahead,0,0),vector(0,0,-dist_down),IGNORE_PASSABLE | GLIDE); // move the player

// animate the player according to its moved distance
      if (dist_ahead != 0) // player is moving ahead
      {
         anim_percent += 1.3*dist_ahead; // 1.3 = walk cycle percentage per quant
         ent_animate(me,"walk",anim_percent,ANM_CYCLE); // play the "walk" animation
      }
      else // player stands still
      { 
         anim_percent += 5*time_step; 
         ent_animate(me,"stand",anim_percent,ANM_CYCLE); // play the "stand" animation
      }
      wait(1);
   }
}

Siehe auch:

c_rotate, c_trace, move_min_z, move_friction, collisions, model animation, pXent_move

► Aktuelle Version Online