-1

I have a problem with my game in that it starts off fast and after a few seconds in it has noticeably slowed down, I have taken out bits of code and added them in one at a time to see what is slowing it down, and it is when I create the array of blocks and print them to the screen that is causing the lag.

//Block section

-Loop from 1 to 10 -Create shape object -push on array -end

-Loop through Array -Paint Shape to screen

There is a lot of bugs in the game , its still in the process of being completed :) :)

http://jsfiddle.net/s2NCx/1/

var canvas;
 var ctx;
 var dx = 5;
 var dy = 5;
 var x = 460;
 var y = 480;
 var a = 500;
 var b = 570;
 var WIDTH = 1000;
 var HEIGHT = 600;
 var x1 = 0,
     y1 = 0;
 var dx1 = 5,
     dy1 = 5;
 var myblocks = [];
 ball = new setcircle(x, y, 10, "purple");
 //paddel = new square(x,y,100,20,"purple");

//initate
 function init() {
     canvas = document.getElementById("canvas");
     ctx = canvas.getContext("2d");
     return setInterval(draw, 10);

 }

//creates an array of blocks and prints to screen
 function block() {


     var p = 40;
     for (var i = 0; i < 10; i++) {

         myblocks.push(new Shape(p, 10, 90, 20, "#333"))
         p = p + 91;
     }

     for (i in myblocks) {
         oblock = myblocks[i];
         ctx.fillStyle = oblock.fill1;
         ctx.fillRect(oblock.a, oblock.b, oblock.w, oblock.h);

     }
 }

 //draws and moves ball
 function movecircle(ball) {

     ball.x += dx;
     ball.y += dy;
     if (ball.x <= 0) dx = 5;
     else if (ball.x >= 980) dx = -5;
     if (ball.y <= 0) dy = 5;
     else if (ball.y >= 590) dy = -5;
     ctx.beginPath();
     ctx.fillStyle = ball.fill;
     ctx.arc(ball.x, ball.y, 10, 0, Math.PI * 2, true);
     ctx.fill();



 }

// checks if collides
 function isCollide(r, c) {

     // copyed from stackoverflow
     var cx = Math.abs(c.x - r.a - r.w / 2);
     var xDist = r.w / 2 + c.r;
     if (cx > xDist) return false;
     var cy = Math.abs(c.y - r.b - r.h / 2);
     var yDist = r.h / 2 + c.r;
     if (cy > yDist) return false;
     if (cx <= r.w / 2 || cy <= r.w / 2) return true;
     var xCornerDist = cx - r.w / 2;
     var yCornerDist = cy - r.h / 2;
     var xCornerDistSq = xCornerDist * xCornerDist;
     var yCornerDistSq = yCornerDist * yCornerDist;
     var maxCornerDistSq = c.r * c.r;
     return xCornerDistSq + yCornerDistSq <= maxCornerDistSq;
 }

//ball object
 function setcircle(x, y, r, fill) {

     this.x = x;
     this.y = y;
     this.r = r;
     this.fill = fill;
 }
//shape object
 function Shape(a, b, w, h, fill) {

     this.a = a;
     this.b = b;
     this.w = w;
     this.h = h;
     this.fill1 = fill;

 }
//keyboard inout
 function doKeyDown(evt) {
     switch (evt.keyCode) {
         case 38:
             /* Up arrow was pressed */
             if (b - dy > 0) {
                 b -= dy;
             }
             break;
         case 40:
             /* Down arrow was pressed */
             if (b + dy < HEIGHT) {
                 b += dy;
             }
             break;
         case 37:
             /* Left arrow was pressed */
             if (a - dx > 0) {
                 a -= dx;
             }
             break;
         case 39:
             /* Right arrow was pressed */
             if (a + dx < WIDTH) {
                 a += dx;
             }
             break;
     }
 }

 function changedirection(ball) {
     dy = -dy;






 }

 function update() {


     //check if ball hits paddle
     if (isCollide(paddel, ball)) {
         changedirection(ball);
         ctx.fillStyle = "purple";
         ctx.fillRect(200, 200, 100, 100);
     }
     //check if ball hits block
     for (i in myblocks) {
         if (isCollide(myblocks[i], ball)) {
             changedirection(ball);
             ctx.fillStyle = "purple";
             ctx.fillRect(200, 200, 100, 100);

         }
     }

 }



 function draw() {
     ctx.clearRect(0, 0, canvas.width, canvas.height);
     movecircle(ball);
     block();
     paddel = new Shape(a, b, 100, 20, "purple");
     ctx.fillStyle = paddel.fill1;
     ctx.fillRect(paddel.a, paddel.b, paddel.w, paddel.h);
     update();
 }
 init();
 window.addEventListener('keydown', doKeyDown, true);

//UPDATE:

I have removed the initalisation of the blocks and placed into the init method and this has speed up the game significantly.

4

3 回答 3

4

Running your code and using the profiler built in to chrome shows that your app is spending more than 50% of it's time in the block function.

enter image description here

Looking at a heap snapshot taken after a while show that a lot of the heap space is taken up by Shape objects.

enter image description here

Looking at the source of block we see that you're pushing 10 new Shape objects each time block is called. That is why your app is slowing down. You should check out these profiling tools as it is a very good way to learn where the bottlenecks are in an application.

As for a simple way to at least make the application not slow down so quickly you could add:

myblocks = [];

in the begining of the block function.

于 2013-10-13T11:21:28.127 回答
2

The size of myblocks increases by 10 in block() which is called every 10 milliseconds (your setInterval) by draw(). After one second you have 1000 blocks.

于 2013-10-13T11:11:41.997 回答
2

The slowdown is caused by the fact that you are re-calling

 block();
 paddel = new Shape(a, b, 100, 20, "purple");

(that recreate the paddle shape and blocks) at every iteration of draw(), called every 10 ms

于 2013-10-13T11:11:49.950 回答