2

我昨天开始玩 Dart,并想尝试制作一个简单的游戏引擎。我也是 canvas element 的新手,所以我确定我在某个地方犯了一个愚蠢的错误。

这是我的主要游戏循环。

class FunTime {

FunTime(){

   gameTime = new Date.now();

   gameState = new List<IDrawableGameComponent>();

   StartMenu startMenu = new StartMenu();

   gameState.add(startMenu);

   CanvasElement _canvas = document.query('#canvas');

   context = _canvas.getContext('2d');

 }

 List<IDrawableGameComponent> gameState;
 Date gameTime;
 CanvasRenderingContext2D context;


}

void main() {

  var exit = false;

  FunTime game = new FunTime();

  Date previousDraw = new Date.now();

  while (!exit){

    game.gameTime = new Date.now();

    //update
    game.gameState.last().update(game.gameTime);

     int elapsed = game.gameTime.difference(previousDraw).inMilliseconds;
     //draw (60 fps)
     if(previousDraw == null || elapsed > 16){

       //print("Draw Called{$elapsed}");
       previousDraw = game.gameTime;
       game.gameState.last().draw(game.gameTime, game.context);
     }

  }

}

下面是 StartMenu 代码的代码:

class StartMenu implements IDrawableGameComponent{
  num positionX = 0;
  StartMenu(){

  }
  void load(){

  }
  void update(Date gameTime){
    //if(positionX < 200)
     // positionX++;
  }
  void draw(Date gameTime, CanvasRenderingContext2D ctx){
    ctx.clearRect(0, 0, 800, 600);
    ctx.fillStyle = 'black';
    ctx.fillRect(0,0,800,600);
    ctx.fillStyle = 'white';
    ctx.fillRect(positionX, 50, 400, 200);
  }
}

出于某种原因,除非我单步执行代码,否则永远不会绘制矩形。几乎就像在调用下一个清除之前,浏览器没有足够的时间来绘制它。我试过增加绘制间隔,但它没有改变任何东西。

这是我解决问题的方法:

class FunTime {

FunTime(){

    gameTime = new Date.now();

    gameState = new List<IDrawableGameComponent>();

    StartMenu startMenu = new StartMenu();

    gameState.add(startMenu);

    canvas = document.query('#canvas');

    context = canvas.getContext('2d');

    _previousDraw = 0;

    animate(0);

  }

  animate(int time){

    int elapsed = time - _previousDraw;

    if( _previousDraw == 0 || elapsed > 16){

      this.gameState.last().draw(time, this.context);

      _previousDraw = time;

    }

    this.gameState.last().update(time);

    window.webkitRequestAnimationFrame(animate, this.canvas);
  }

  int _previousDraw;

  List<IDrawableGameComponent> gameState;

  Date gameTime;

  CanvasRenderingContext2D context;

  CanvasElement canvas;

}

void main() {

  FunTime game = new FunTime();

}
4

1 回答 1

4

main() 方法中的 while 循环永远不会返回让浏览器线程绘制。这就是为什么它只有在您逐步完成时才有效。

这种替代方法有效:使用 window.setInterval,每 16 毫秒调用一次函数,但它可能不是游戏循环的正确方法。

void main() {
  var exit = false;
  FunTime game = new FunTime();
  Date previousDraw = new Date.now();

  window.setInterval(   () {   //note the callback
    game.gameTime = new Date.now();
    //update
    game.gameState.last().update(game.gameTime);

    int elapsed = game.gameTime.difference(previousDraw).inMilliseconds;
    //draw (60 fps)
    if(previousDraw == null || elapsed > 16){

      previousDraw = game.gameTime;
      game.gameState.last().draw(game.gameTime, game.context);
    }
  }, 16);  //16 ms
}
于 2012-04-08T19:25:17.990 回答