2016-06-04 17 views
0

Verwendung von Away3D ... Ich habe dieses Array von Würfeln, die ich generiert habe. Diese Anordnung von Würfeln befindet sich in einem "Sektor", der 50x50x50 Würfel enthält. Das einzige, was der Sektor enthält, sind die Würfelkoordinaten und die Farbe. Sie werden in der Cube-Klasse gespeichert. Ich will nur diejenigen machen, die Luft (zur Zeit „Luft“, die „Farbe“ 0xFFFFFF)Suche nach Würfeln, die Luft berühren .. [Suche nach Elementen in einem Vektor]

Ich habe versucht, berühren Sie diese ... eine interessante Reihe von Möglichkeiten, ...

Meine aktuelle Methode (langsamste) war es, für jedes Objekt vector3D-Punkte zu machen, und dann indexOf auf einer Menge von Vector3Ds zu verwenden, die die Punkte aller Würfel in meinem "Sektor" enthalten.

public function renderSector(sector:Sector):void 
    { 
     trace("init sector render.."); 
     allCubes = sector.cubes; 
     //Render only things touching air. 
     for each (var cube:Cube in sector.cubes) 
     { 
      //If the cube is not an air block 
      if (cube.color != 0xFFFFFF) 
      { 
       var topEstimate:Vector3D = new Vector3D(cube.x + 1, cube.y, cube.z); 
       var bottomEstimate:Vector3D = new Vector3D(cube.x, cube.y +1, cube.z); 
       var leftEstimate:Vector3D = new Vector3D(cube.x + 1, cube.y, cube.z +1); 
       var rightEstimate:Vector3D = new Vector3D(cube.x - 1, cube.y, cube.z); 
       var frontEstimate:Vector3D = new Vector3D(cube.x, cube.y -1, cube.z); 
       var backEstimate:Vector3D = new Vector3D(cube.x, cube.y, cube.z - 1); 

       //If the cube is next to an air block 
       if (checkForAir(topEstimate) || checkForAir(bottomEstimate) || checkForAir(leftEstimate) || checkForAir(rightEstimate) || checkForAir(frontEstimate) || checkForAir(backEstimate)) 
       { 
        var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color)); 
        meshCube.x = (sector.x * 125000) + (10 * cube.x); 
        meshCube.y = (sector.y * 125000) + (10 * cube.y); 
        meshCube.z = (sector.z * 125000) + (10 * cube.z); 

        trace("This cube touches air..rendering"); 

        viewport.scene.addChild(meshCube); 
       } 

      } 

     } 
    } 

    private function checkForAir(point:Vector3D):Boolean 
    { 
     var returnValue:Boolean = new Boolean(false); 
     var index:int = allCubes.indexOf(point); 
     if (index > -1) 
     { 
      if (allCubes[index].color == 0xFFFFFF) 
      { 
       returnValue = true; 
      } 
     } 
     return returnValue; 
    } 

Nichts passiert. Ich bekomme keine Würfel (lassen Sie es für etwa 2 Minuten laufen), die einen Luftblock neben ihnen mit einem 3DVevtor haben. Ich versuche also, alle meine Würfel erneut zu durchlaufen, während ich eine Liste von Würfeln abrufe, die "neben" meinem aktuellen Würfel liegen. Ich vergleiche jeden Würfel mit einem gespeicherten 3DVector in meiner Sektorklasse.

 public function renderSector(sector:Sector):void 
    { 
     //Render only things touching air. 
     for each (var cube:Cube in sector.cubes) 
     { 
      //If the cube is next to an air block and is not an air block, render it. 
      if (cube.color != 0xFFFFFF) 
      { 
       var touchesAir:Boolean = new Boolean(false); 

       //Search touching cubes 
       var touchingCubes:Vector.<Cube> = new Vector.<Cube>(); 

       for each (var possibleCube:Cube in sector.cubes) 
       { 
        if ((possibleCube.x == cube.x + 1 && possibleCube.y == cube.y && possibleCube.z == cube.z) || 
         (possibleCube.y == cube.y + 1 && possibleCube.x == cube.x && possibleCube.z == cube.z) || 
         (possibleCube.z == cube.z + 1 && possibleCube.x == cube.x && possibleCube.y == cube.y) || 
         (possibleCube.x == cube.x - 1 && possibleCube.y == cube.y && possibleCube.z == cube.z) || 
         (possibleCube.y == cube.y - 1 && possibleCube.x == cube.x && possibleCube.z == cube.z) || 
         (possibleCube.z == cube.z - 1 && possibleCube.x == cube.x && possibleCube.y == cube.y)) 
        { 
         touchingCubes.push(possibleCube); 
        } 
       } 

       for each (var touchingCube:Cube in touchingCubes) 
       { 
        if (touchingCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 

       if (touchesAir) 
       { 
        var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color)); 
        meshCube.x = (sector.x * 125000) + (10 * cube.x); 
        meshCube.y = (sector.y * 125000) + (10 * cube.y); 
        meshCube.z = (sector.z * 125000) + (10 * cube.z); 

        trace("This cube touches air..rendering"); 

        viewport.scene.addChild(meshCube); 
       } 


      } 
     } 

Es works..but es etwa 15 Sekunden dauert es, einen zu finden .... Die aktuelle Spezifikation des Sektors eine Ebene von 50x25x50 Gras farbigen Blöcken ist. Also würde das eine Weile dauern.

Meine erste Methode (und oh Mann war das ungefähr eine Stunde + Brainstorming zurück) war, die Positionen jedes Würfels zu holen, die [i] würde neben meinem Haupt sein Würfel, indem ich es auf die Renderreihenfolge in meiner Weltgeneratorfunktion basiere. [Unten gesehen]

public static function generateSector(type:String, position:Vector3D):Sector 
    { 
     var returnSector:Sector; 
     var grassArray:Vector.<uint> = new Vector.<uint>(); 
     grassArray.push(new uint(0x56b000)); 
     grassArray.push(new uint(0x63c900)); 
     grassArray.push(new uint(0x6fe300)); 
     grassArray.push(new uint(0x7cfc00)); 

     //Current types...grass field 
     switch(type) 
     { 
      case "grass": 
       var cubeArray:Vector.<Cube> = new Vector.<Cube>(); 

       for (var x:int = 0; x < 50; x++) //Moving right 
       { 
        for (var z:int = 0; z < 50; z++) //Headed out. 
        { 
         for (var y:int = 0; y < 50; y++) //From bottom up. 
         { 
          if (y < 25) 
          { 
           var color:uint = grassArray[Math.floor(Math.random() * 4)]; 
          } 
          else 
          { 
           var color:uint = 0xFFFFFF; 
          } 

          cubeArray.push(new Cube(x,y,z,color)); 
         } 
        } 
       } 
       returnSector = new Sector(position.x, position.y, position.z, cubeArray); 
       break; 
     } 

     return returnSector; 
    } 

Y Gebäude erstes (unten nach oben) dann X dann

Z

So einfach oder? Basierend auf der Reihenfolge der Würfel, sollte ich in der Lage sein, zum Beispiel den Würfel über meinem aktuellen Würfel zu ziehen, indem ich 1 zum Index meines aktuellen Würfels hinzufüge, nicht wahr? (Kennenlernen der anderen Würfel jeweils bezogen auf die Reihenfolge natürlich und Fangfehler für alle Würfel, die außerhalb meines 50x50x50 Gitter wäre)

public function renderSector(sector:Sector):void 
    { 
     //Render only things touching air. 
     var counter:int = 0; 
     for each (var cube:Cube in sector.cubes) 
     { 
      //If the cube is next to an air block and is not an air block, render it. 
      if (cube.color != 0xFFFFFF) 
      { 
       var touchesAir:Boolean = new Boolean(false); 

       try 
       { 
        var topCube:Cube = sector.cubes[counter + 1]; 
        if (topCube.color == 0xFFFFFF) 
        { 
         touchesAir == true; 
        } 
       } 
       catch(rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var bottomCube:Cube = sector.cubes[counter - 1]; 
        if (bottomCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var leftCube:Cube = sector.cubes[counter - (50 * 50)]; 
        if (leftCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var rightCube:Cube = sector.cubes[(50 * 50) + counter]; 
        if (rightCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var frontCube:Cube = sector.cubes[counter - 50]; 
        if (frontCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 
       //------- 
       try 
       { 
        var backCube:Cube = sector.cubes[counter + 50]; 
        if (backCube.color == 0xFFFFFF) 
        { 
         touchesAir = true; 
        } 
       } 
       catch (rangeError:RangeError) 
       { 

       } 

       if (touchesAir) 
       { 

        var meshCube:Mesh = new Mesh(new CubeGeometry(10, 10, 10), new ColorMaterial(cube.color)); 
        meshCube.x = (sector.x * 125000) + (10 * cube.x); 
        meshCube.y = (sector.y * 125000) + (10 * cube.y); 
        meshCube.z = (sector.z * 125000) + (10 * cube.z); 

        trace("This cube touches air..rendering"); 

        viewport.scene.addChild(meshCube); 
       } 


      } 
     } 
    } 

Dieses in rendert etwa 4 Sekunden! Obwohl tatsächlich keine Würfel auf dem Bildschirm erscheinen ... und die Trace-Anweisung wird nie ausgelöst. Ich hatte kein Glück herauszufinden, warum.

TL; DR Nehmen wir an, Sie haben ein Gitter aus Würfeln. Wie renderst du nur diejenigen, die draußen stehen?

Oder (großartige Alternative) nur Netze, die Sie "sehen" können. (Ich brauche die Meshs nicht zusammengefügt, weil ich Hörer haben muss, um sie zu entfernen oder neue Meshes hinzuzufügen, wenn neben oder neben ihnen angeklickt)

Antwort

0

Sie kennen diese Momente, wenn Sie vergessen zu schlafen und dann vergessen Sie hinzuzufügen Zähler auf Ihre für jeden Schleifen, da Sie einen Zähler in ihm referenzieren?

counter = sector.cubes.indexOf(cube); 

müssen dafür sorgen, dass der Zähler (was ich sollte indexItem umbenennen) den Index des aktuellen Cube abgestimmt, dass ich durch in meinem bedingt ausgeführt wird, wenn der Würfel „Luft“ überprüft, ist oder nicht.

Natürlich bekomme ich jetzt einen Ressourcen-Limit-Fehler, aber das kann behoben werden, indem die Sektorgröße reduziert und ein paar Meshes kombiniert werden.

[Fault] exception, information=Error: Error #3691: Resource limit for this resource type exceeded.