更新和渲染时锁定游戏数据

时间:2016-07-30 17:59:01

标签: javascript html5 canvas

我正在做一个node.js游戏,我的客户端数据更新/渲染逻辑实现如下:

   var rendering = false;
   var waiting_for_data = true;
   var data_update = false;

  socket.on('update', function(data){

      if(rendering)console.log("rendering");

      data_update = true;
      game_data = data;
      data_update = false;

      if(waiting_for_data){
        waiting_for_data = false;
        render();
      }


    });

    window.requestAnimFrame = (function(){
          return  window.requestAnimationFrame       ||
                  window.webkitRequestAnimationFrame ||
                  window.mozRequestAnimationFrame    ||
                  window.oRequestAnimationFrame      ||
                  window.msRequestAnimationFrame     ||
                  function(/* function */ callback, /* DOMElement */ element){
                    window.setTimeout(callback, 1000 / 60);
                  };
    })();


    function render(){


      while(data_update){
        console.log("waiting" + data_update);
      }

      if(game_data == null )console.log(game_data);

      rendering = true;
        //mapa.draw(context, game_data.player_position);
        renderer.draw(game_data);
      rendering = false;

      window.requestAnimFrame(render);
    }

  }

我可以看到屏幕每隔几秒闪烁一次我元素的随机位置。当我在console.log数据和对象位置时,它们看起来很好。我应该使用某种锁或别的东西吗?我的渲染var和data_update var是否可以安全地更新数据。还有一件事,服务器正在发出更新'每秒60次。

1 个答案:

答案 0 :(得分:0)

您的代码看起来像是在尝试线程安全。没有必要。

JavaScript是单线程的。它一次只能运行一条指令。它一次只能运行一个功能。该功能不能被中断,没有其他事件,在当前功能完成之前不会更改其他数据。 Javascript是线程安全的终极因素,因为它只是顺序执行。执行代码时不能中断。所有事件(如socket.on和requestAnimationFrame)必须等待当前执行才能运行。

   // var rendering = false; // not needed
   var waiting_for_data = true;
   // var data_update = false; // not needed

   socket.on('update', function (data) {
       // this will never run if render is running
       //data_update = true; // nothing will see this
       game_data = data;  // ONLY this will ever happen between the line above and below
       // data_update = false; // nothing will see this

       if (waiting_for_data) {
           waiting_for_data = false;
           render();
       }

   });


   function render() {
       // if data_updata is true
       // then the while loop will have no way to exit and nothing 
       // can change data_update while this loop is running except some code in the loop
       // JavaScript is single threaded and can only do one thing at a time.
       //while (data_update) {
       //    console.log("waiting" + data_update);
       //}

       // again single thread. Only code in this function can run NOTHING else
       // can do anything until this function has exited all the way out
       //rendering = true;  
       renderer.draw(game_data);
       //rendering = false;

       requestAnimationFrame(render);
   }