2

木や岩などのランダムなオブジェクトが周りにある大きな世界を歩くゲームを開発しています。

今の私の目標は、世界のオブジェクトの総量がゲームの速度に影響を与えないようにすることです.. そのため、オブジェクトの配列が必要かもしれないと考えました. 各オブジェクトには独自の位置があります.どれが近い/遠いかをループして確認します次に、それぞれaddChild/removeChildを使用しますが、大量のオブジェクトを含む配列を常に通過するのはあまり良くないため、このアプローチは問題になると思います..

だから皆さんに聞いてみようと思いました.. この仕事にどのように取り組みますか? そして、コード例は非常に高く評価されます 事前に感謝します

4

2 に答える 2

3

世界が2Dまたは3Dであるかどうかに応じて、 octree/quadtreeなどのデータ構造が必要になると思います。これは、世界生成フェーズですべての静的オブジェクトで埋められます。動的なもの (モンスターなど) はすべて、このツリーのノードを独自に移動します。表示には、半径アプローチを使用して、プレイヤーから特定のツリー セルの距離にあるオブジェクトのみをレンダリング (表示) します。このアプローチでは、プレーヤーがツリー セル間の境界を越えた場合にのみ表示リストを変更する必要があります。removeChild()現在セル内にあるすべてのオブジェクトと、addChild()現在表示範囲内にあるオブジェクトに対して a を実行します。

編集:さらに良いことに、世界にあるオブジェクトのリストと実際の位置などを含む2D配列を使用できるため、クワッドツリーが提供する可変粒度の代わりに、各セルがより多くを保持できる均一なグリッドが得られます単一のオブジェクトよりも。このグリッドは、隣接する要素の位置を自然に保持するため、四分木よりも簡単に移動できます。これは、プレーヤーがグリッドを連続的に移動するときに最も必要となります。ほとんどが疑似コードですが、実際のグリッドがどのように見えるかについてのヒントを与えることができる例:

class World {
    var GRID:Vector.<Vector.<Vector.<GameObject>>>; // the grid
    const GRAN:int=100; // this many x this many is one GRID cell
    var gridWidth:int;
    var gridHeight:int;
    public function World(w:int,h:int) { // size in pixels, for example. This depends on how you display objects
        gridWidth=1+Math.floor(w/GRAN);
        gridHeight=1+Math.floor(h/GRAN);
        GRID=new Vector.<Vector.<Vector.<GameObject>>>(gridWidth,true); // fixed size, it optimizes performance
        var i:int; var j:int;
        for (i=0;i<gridWidth;i++) {
            GRID[i]=new Vector.<Vector.<GameObject>>(gridHeight,true); // again fixed size
            for (j=0;j<gridHeight;j++) GRID[i][j]=new Vector.<GameObject>(); 
            // ^ variable size, as initially the world is empty, and it will get 
            //filled with stuff dynamically. But we need to allocate the data structure
        }
    }
    public function PlaceObject(ob:GameObject):void {
        // puts an object into grid and assigns it grid position to refer the grid
        var gx:int=Math.floor(ob.x/GRAN);
        var gy:int=Math.floor(ob.y/GRAN);
        ob.gridX=gx;
        ob.gridY=gy;
        GRID[gx][gy].push(ob);
        // error control is absent, but should be.
    }
    public function MoveObject(ob:GameObject):void {
        // called if game engine moves an object. It has its X&Y changed, but grid position must be updated
        var gx:int=Math.floor(ob.x/GRAN);
        var gy:int=Math.floor(ob.y/GRAN);
        if ((ob.gridX==gx)&&(ob.gridY==gy)) return; // this object didn't leave its grid node
        GRID[ob.gridX][ob.gridY].splice(GRID[ob.gridX][ob.gridY].indexOf(ob),1);
        // will break if the object is not in GRID, so integrity check is needed here
        ob.gridX=gx;
        ob.gridY=gy;
        GRID[gx][gy].push(ob);
    }       
    ...
}     

このクラスの外に、プレーヤーの GRID 位置を持つレンダラーを配置し、指定された半径で GRID からデータを取得し、オブジェクトを表示リストに配置します。

于 2013-02-28T09:26:25.157 に答える
0

オブジェクトが「ビュー」の外にあるときに永続化する必要がない場合は、プレーヤーのビュー距離の外側の範囲でオブジェクトを生成して、アクティブなオブジェクトのみをループするようにすることができます。オブジェクトがプレイヤーから一定の距離を離れると、オブジェクトは削除されます。オブジェクトを永続化したい場合は、何らかのシステムを使用して、オブジェクトを更新する必要があるかどうかを判断できます。たとえば、各オブジェクトに「ゾーン」プロパティを与えることができます。プレイヤーのゾーンとプレイヤーのゾーンに隣接するゾーンにあるオブジェクトが更新されます。隣接していないものは、更新する必要はありません。

于 2013-02-28T09:56:58.413 に答える