6

現在、オンライン ゲームに取り組んでおり、パフォーマンス上の理由から、HTML5 のキャンバスではなく webgl を使用することにしました。私は three.js フレームワークを使用しています。私の意図は、アニメーション化されたスプライトを動かすことです。スプライト自体はスプライトシートに配置され、UVOffset と UVScale を使用して適切なアートを使用し、時間経過中にスプライトのアートを切り替えます。このコードのパフォーマンスを改善する方法があるかどうか疑問に思っていました。現在、フィールド上で同時に約 300 人の「プレーヤー」で速度が低下し始めているためです。

よろしく

以下は、私のコードの最も重要な部分です。

var image = THREE.ImageUtils.loadTexture( "img/idlew.png" );

  function addPlayer(){
    var mesh = new THREE.Sprite({map:image});//, affectedByDistance: false, useScreenCoordinates: false});
    images.push(mesh);
    mesh.position.set(Math.floor(Math.random() * 500), Math.floor(Math.random() * 500), 10);
    scene.add(mesh);
    mesh.uvScale.x = 96/1152;
    mesh.scale.x = 0.1;
    mesh.scale.y = 0.1;
  }


var imgBackground  = new THREE.MeshLambertMaterial({
      map:THREE.ImageUtils.loadTexture('img/grass.jpg')
  });


   var background = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000),imgBackground);


  scene.add(background);



  scene.add(camera);
camera.rotation.x = -(Math.PI/2);
scene.add(new THREE.AmbientLight(0xFFFFFF));

addPlayer();

  renderer.render(scene, camera);
  var moveUp = false;
  tick();
  var ticker = 0;
  var usedOne = 0;

  function tick(){
    ticker++;
    if(ticker%10==0){
      for (var i = 0; i < images.length; i++) {
        images[i].uvOffset.x = usedOne * 0.0835;
      };
        usedOne++;
        if(usedOne == 12) usedOne = 0;
        addPlayer();
        addPlayer();
        addPlayer();
        console.log(images.length);
    }
    requestAnimationFrame( tick );

      renderer.render(scene, camera);
  }
4

2 に答える 2

9

アニメーション化されたテクスチャを表示するコードの例を作成しました。ライブの例は次のとおりです。

http://stemkoski.github.com/Three.js/Texture-Animation.html

ソースは次の場所で入手できます。

http://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Texture-Animation.html

便利な部分は、オフセットを自動的に処理するために私が書いた関数です。関数 (上記のリンクから抽出) は次のとおりです。

function TextureAnimator(texture, tilesHoriz, tilesVert, numTiles, tileDispDuration) 
{   
    // note: texture passed by reference, will be updated by the update function.

    this.tilesHorizontal = tilesHoriz;
    this.tilesVertical = tilesVert;

    // how many images does this spritesheet contain?
    //  usually equals tilesHoriz * tilesVert, but not necessarily,
    //  if there at blank tiles at the bottom of the spritesheet. 
    this.numberOfTiles = numTiles;
    texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
    texture.repeat.set( 1 / this.tilesHorizontal, 1 / this.tilesVertical );

    // how long should each image be displayed?
    this.tileDisplayDuration = tileDispDuration;

    // how long has the current image been displayed?
    this.currentDisplayTime = 0;

    // which image is currently being displayed?
    this.currentTile = 0;

    this.update = function( milliSec )
    {
        this.currentDisplayTime += milliSec;
        while (this.currentDisplayTime > this.tileDisplayDuration)
        {
            this.currentDisplayTime -= this.tileDisplayDuration;
            this.currentTile++;
            if (this.currentTile == this.numberOfTiles)
                this.currentTile = 0;
            var currentColumn = this.currentTile % this.tilesHorizontal;
            texture.offset.x = currentColumn / this.tilesHorizontal;
            var currentRow = Math.floor( this.currentTile / this.tilesHorizontal );
            texture.offset.y = currentRow / this.tilesVertical;
        }
    };
}       

(例)を使用してマテリアルを初期化できます。

var runnerTexture = new THREE.ImageUtils.loadTexture( 'images/run.png' );
// a texture with 10 frames arranged horizontally, display each for 75 millisec
annie = new TextureAnimator( runnerTexture, 10, 1, 10, 75 ); 
var runnerMaterial = new THREE.MeshBasicMaterial( { map: runnerTexture } );

次を使用して、各レンダリングの前に更新します。

var delta = clock.getDelta(); 
annie.update(1000 * delta);

お役に立てれば!

于 2012-07-03T02:38:04.243 に答える
2

配置することでコードを大幅に改善できることに気づき、自分の質問に答えました。

renderer.render(scene, camera); 

必要なときにのみ呼び出されるように、適切な場所にコーディングします。

于 2012-07-02T13:37:47.857 に答える