3
\$\begingroup\$

So here I made a little shooter game just to play around with and on my pc it runs fine but for people with worse internet/less powerful computers (e.g at school/few friends of mine) it is quite laggy and this is my first canvas game so I'm not to sure of the usual techniques of optimisation.

I'm sending the clients information and then the rest of the players information(only the minimum that the client needs) to the client 60 times a second in my game loop through a socket.

Sorry for this question being a little vague, just looking for tips on optimisation basically. If any more code is needed just ask! Thanks!

Here is my draw function:

  function draw() {
    ctx.clearRect(0, 0, canvas.width,canvas.height);
    //grey background
    ctx.fillStyle="rgba(128, 128, 128, 0.15)";
    ctx.fillRect(0, 0,canvas.width, canvas.height);
    //drawing background grid
    for(var pos = 25;pos<5000;pos+=25)
    {
      ctx.beginPath();
      ctx.strokeStyle = "rgba(128, 128, 128, 0.75)";
      ctx.lineWidth="1";
      ctx.moveTo(0, pos-player.y+pos);
      ctx.lineTo(canvas.width, pos-player.y+pos);
      ctx.stroke();
    }
    for(var pos = 25;pos<5000;pos+=25)
    {
      ctx.beginPath();
      ctx.strokeStyle = "rgba(128, 128, 128, 0.75)";
      ctx.lineWidth="1";
      ctx.moveTo(pos-player.x+pos, 0);
      ctx.lineTo(pos-player.x+pos, canvas.height);
      ctx.stroke();
    }
    //drawing the clients player
    if(player != '')
    {
      ctx.save();
      ctx.translate((window.innerWidth/2), (window.innerHeight/2));
      ctx.font = '11px Roboto';
      ctx.textAlign="center";
      ctx.fillStyle="black";
      ctx.fillText(player.health, 0, 42);
      ctx.rotate(player.look * (Math.PI / 180));
      var circle = new Path2D();
      circle.arc(0, 0, 30, 0, 2.5 * Math.PI);
      ctx.fillStyle="black";
      ctx.fill(circle);

      ctx.beginPath();
      ctx.strokeStyle="red";
      ctx.lineWidth="4";
      ctx.moveTo(0, -10);
      ctx.lineTo(0, -30);
      ctx.stroke();

      ctx.restore();
      ctx.save();
      ctx.translate((window.innerWidth/2), (window.innerHeight/2));
      ctx.rotate(0);

      ctx.font = '12pt Roboto';
      ctx.textAlign="center";
      ctx.fillStyle="white";
      ctx.strokeStyle="black";
      ctx.strokeText(player.name, 0, 4);
      ctx.fillText(player.name, 0, 4);


      ctx.restore();

      if(player.bullets != 'undefined')
      {
        for(var j = 0;j<player.bullets.length;j++)
        {
          ctx.save();
          ctx.translate((window.innerWidth/2)+(player.bullets[j].playerX - player.x), (window.innerHeight/2)+(player.bullets[j].playerY - player.y));
          ctx.rotate(player.bullets[j].attack * (Math.PI/180));
          ctx.fillStyle = 'black';
          ctx.fillRect(player.bullets[j].traveled, 0, 6, 2);
          ctx.restore();
          ctx.rotate(0);
        }
      }
      ctx.restore();
    }
    //drawing every other player
    for(var i = 0;i<playerArr.length;i++)
    {
      if(player.id  != playerArr[i].id)
      {
        ctx.save();
        ctx.translate((window.innerWidth/2)+(playerArr[i].x - player.x), (window.innerHeight/2)+(playerArr[i].y - player.y));

        ctx.font = '11px Roboto';
        ctx.textAlign="center";
        ctx.fillStyle="black";
        ctx.fillText(playerArr[i].health, 0, 42);

        ctx.rotate(playerArr[i].look * (Math.PI / 180));
        var circle = new Path2D();
        circle.arc(0, 0, 30, 0, 2.5 * Math.PI);
        ctx.fillStyle="black";
        ctx.fill(circle);

        ctx.beginPath();
        ctx.strokeStyle="red";
        ctx.lineWidth="4";
        ctx.moveTo(0, -10);
        ctx.lineTo(0, -30);
        ctx.stroke();

        ctx.restore();
        ctx.save();
        ctx.translate((window.innerWidth/2)+(playerArr[i].x - player.x), (window.innerHeight/2)+(playerArr[i].y - player.y));
        ctx.rotate(0);

        ctx.font = '12pt Roboto';
        ctx.textAlign="center";
        ctx.fillStyle="white";
        ctx.strokeStyle="black";
        ctx.strokeText(playerArr[i].name, 0, 4);
        ctx.fillText(playerArr[i].name, 0, 4);

        ctx.restore();

        for(var j = 0;j<playerArr[i].bullets.length;j++)
        {
          ctx.save();
          ctx.translate((window.innerWidth/2)+(playerArr[i].bullets[j].playerX - player.x), (window.innerHeight/2)+(playerArr[i].bullets[j].playerY - player.y))
          ctx.rotate(playerArr[i].bullets[j].attack * (Math.PI/180));
          ctx.fillStyle = 'black';
          ctx.fillRect(playerArr[i].bullets[j].traveled, 0, 6, 2);
          ctx.restore();
          ctx.rotate(0);
        }
      }
    }
    //drawing trees
    for(var i = 0;i<treeArr.length;i++)
    {
      ctx.save();
      ctx.translate((window.innerWidth/2)+(treeArr[i].x - player.x), (window.innerHeight/2)+(treeArr[i].y - player.y));
      ctx.drawImage(tree, 0, 0, 108, 108);
      ctx.restore();
    }
    if(playing)
    {
      requestAnimationFrame(draw);
    }
  }
\$\endgroup\$
  • \$\begingroup\$ Lag is more of a latency on the connection issue? Are you having issues with the connection? Or actually with the fps? First thing I see, but don't know how much difference it will make, is that you do a lot of calculations over and over again. While you only need to do them when they change. E.a. window.height/2 . I would have a Boolean for each of those calculations. Calculate them once and set the Boolean to true. Then in a window change event or something else that changes the calculation, set the Boolean to false, so it will recalculate once. \$\endgroup\$ – therebelcoder May 21 '17 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.