Pregunta

I started playing around with Dart yesterday and thought I would try to make a simple game engine. I'm also new to the canvas element , so I'm sure I'm making a silly mistake somewhere.

Here is my main game loop.

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);
     }

  }

}

Here is the code for the StartMenu code:

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);
  }
}

For some reason the rectangles are never drawn unless I step through the code. Its almost like the brwoser doesn't have enough time to draw it before the next clear is called. I've tried increasing the draw interval but it doesn't change anything.

Here is how I solved the problem:

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();

}
¿Fue útil?

Solución

The while loop in the main() method never returns to let the browser thread draw. This is why it only works when you step through it.

This alternative works: using window.setInterval, to call a function every 16ms, but it may not be the correct way for a game loop.

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
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top