Framerate
Home Nach oben

 

Nach oben
Dungeons
Detailmap
Einführung
Multitexture Terrain
Plantbox
Aussenlevel (Block)
Tag & Nachtwechsel
KI
Waving Grass
Framerate

Auf dieser Seite erscheinen einfache Tricks um die Framerate innerhalb eines Spieles mit großen Außenleveln und vielen Entities zu verbessern.

 

Entity Cache

Eine große Ansammlung von Entities im Level drückt die Framerate bei der Darstellung erheblich. Um jedoch realistisch wirkende Wälder und Außenlevel aufbauen zu können ist es jedoch unabdingbar eine
große Anzahl von Entities zu verwenden.

Eine einfache Möglichkeit die Framerate zu verbessern ist es Entities, die außerhalb der Sichtweite (bzw. einer einstellbaren Entfernung zum Spieler) liegen auf der Z-Achse nach unten zu verschieben und sobald das Entity wieder in der Sichtweite des Spielers liegt wieder auf der Z-Achse an den angestammten Platz zurückzuschieben.

Es gibt mit Sicherheit wesentlich ausgefeiltere Möglichkeiten, aber diese Methode hat zu einer deutlichen Verbesserung der Framerate geführt und kann sofort in jedem bestehenden Level verwendet werden ohne dass dieses verändert werden müsste.

 

Das Script ist gut geeignet für Aussenlevel in denen die Einstellung von camera.clip_far sehr hoch gewählt werden muss um z.B. die umgebenden Berge sichtbar zu halten und die dennoch eine große Anzahl von Entities (z.B. in Wäldern enthalten).

 

init_tree_buffer()

Mit dieser Methode wird der Buffer mit den Entities gefüllt die durch den Cache berücksichtigt werden sollen. Die Methode muss nur einmalig nach dem laden des Levels eingefügt werden.


Function Main() {

    level_load("level1.wmb");
    wait(1);

    init_tree_buffer();

 

check_trees()

Diese Methode muss in das Bewegungsscript des Spielers eingefügt werden. Die Neuberechnung der Entity Positionen erfolgt jedoch nur wenn sich der Spieler um mehr als 500 Quads zur Position der letzten Berechnung bewegt hat.

treebufdist

Diese Variable dient zur Initialisierung und gibt an ab welcher Entfernung ein Entity durch das Script ausser Sichtweite geschoben werden soll. Dieser Wert muss in jedem Fall kleiner als die Einstellung von camera.clip_far sein da das Script sonst keine Wirkung hat.

 

tree.wdl


var treehandle[10000];                // Buffer für die Entities
var treebufdist=5000;                  // Entfernung in Quads ab der die Entities verschoben werden sollen
var treecount=0;

String tree_dtxt1[256];
String tree_dtxt2[256];

entity* treebufferent;

//
// Initialisiere den Entity-Cache
//
// Diese Funktion muss einmalig nach dem Laden des Levels ausgeführt werden (z.B. in der Main Funktion)


function init_tree_buffer() {
    // Scanne alle Entities des Levels
    treebufferent = ent_next (NULL); 
    while (treebufferent != NULL) { 
        str_for_entname (tree_dtxt1, treebufferent); 

        // Wenn Entity mit tree im Namen gefunden dann Pointer im Cache merken
        if(str_stri(tree_dtxt1,"tree")>0) { 
            treehandle[treecount]=handle(treebufferent);
            treecount+=1;
        }

        // Wenn Entity mit bush5 im Namen gefunden dann Pointer im Cache merken
        if(str_stri(tree_dtxt1,"bush5")>0) { 
            treehandle[treecount]=handle(treebufferent);
            treecount+=1;
        }

        // Hier können noch beliebige weitere Entities über den Namen hinzugefügt werden in
        // dem die Bedingung einfach kopiert wird
        treebufferent = ent_next (treebufferent);
    }

    lasttreepos.x=-100000;
    lasttreepos.y=-100000;

}

//
// Check Trees
//
// Diese Funktion wird in das Bewegungsscript des Spielers eingebaut
//


function check_trees() {
    var dist;
    var i=0;
    var temp;

    lasttreepos.z=player.z;
    dist=vec_dist(player.x,lasttreepos);

    //  Berechne die sichtbaren Entities nur wenn sich der Spieler 500 Quad bewegt hat
    if(dist<500) {
        return;
    }

    lasttreepos.x=player.x;
    lasttreepos.y=player.y;

    // Gehe durch alle Enities im Cache und verschiebe Sie aus der Sichtweite wenn Sie
    // weiter entfernt sind als die maximal sichtbare Entfernung


    while(i<treecount) {
        treebufferent=ptr_for_handle(treehandle[i]);
        temp.x=treebufferent.x;
        temp.y=treebufferent.y;
        temp.z=player.z;
        dist=vec_dist(player.x,temp);
        if(treebufferent.skill50==0) {
            if(dist>treebufdist) {
                treebufferent.skill50=1;
                treebufferent.z-=25000;

                // Der Wert (hier 25000) muss größer als die Sichtbarkeitseinstellung camera.clip_far sein
            }
        }
        else {
            if(dist<treebufdist) {
                treebufferent.skill50=0;
                treebufferent.z+=25000;

                // Der Wert (hier 25000) muss größer als die Sichtbarkeitseinstellung camera.clip_far sein
            }
        }
        i+=1;
    } 
}

 

tree.wdl