Search code examples
javascriptfunction2d-games

JavaScript Redraw bricks when totalbrick == 0


I am new to both Stackoverflow and JS. I have an assignment from my coding class where I chose to create games in JS. I have created a simple breakout game with JS only, for now. My problem now is that I want the game to be somewhat endless so when the ball has collided with all the bricks, the bricks will be redrawn but the score will remain. I tried to do something, one was this:

function redrawBricks(){
  if(brickColumnCount * brickRowCount < 1){
  for(var c=0; c<brickColumnCount; c++){
    for(var r=0; r<brickRowCount; r++){
      if(bricks[c][r].status == 1){
      var brickX = (c*(brickWidth+brickPadding)+brickOffsetleft);
      var brickY = (r*(brickHight+brickPadding)+brickOffsetTop);
      bricks[c][r].x = brickX;
      bricks[c][r].y = brickY;
      ctx.beginPath();
      ctx.rect(brickX, brickY, brickWidth, brickHight);
      ctx.fillStyle = "red";
      ctx.fill();
      ctx.closePath;
        }
      }
    }
  }
}

Where the test after the first if-statement is the same as the original drawBricks. I then took that function and placed it where I call my functions.

I simply can't get this to work. But my idea was to make a new function with an if statement, so if the brickColumn * brickRow < 1 then draw this(the bricks)

If you need to see the code, you can see it here but note that my language is danish, so the comments you will probably not understand xD And I did not write it clean yet, so it might not live up to the standards


Solution

  • Looking at the code in the link, I can see you set status to 0 on colliding with a brick. This means it is not rendered. In this code design, a solution could be to check when all brick.status are 0, and then set them back to 1.

    function loop2DArray(arr, rows, cols, cb){
      for(let c = 0; c < cols; c++){
        for(let r = 0; r < rows; r++){
          cb(arr[c][r])
        }
      }
    }
    function redrawBricks(){
      let bricksRemaining = 0;
      loop2DArray(bricks, brickRowCount, brickColumnCount, brick => {
        if(brick.status == 1){
          bricksRemaining ++;
          var brickX = (c*(brickWidth+brickPadding)+brickOffsetleft);
          var brickY = (r*(brickHight+brickPadding)+brickOffsetTop);
          bricks[c][r].x = brickX;
          bricks[c][r].y = brickY;
          ctx.beginPath();
          ctx.rect(brickX, brickY, brickWidth, brickHight);
          ctx.fillStyle = "red";
          ctx.fill();
          ctx.closePath;
        }
      });
      // if all bricks gone, recreate all of them
      if(bricksRemaining === 0){
        loop2DArray(bricks, brickRowCount, brickColumnCount, brick => {
          brick.status = 1;
        });
      }
    }

    However, you can notice many loops, with many unused iterations. This is inefficient and confusing code. A better solution would be to store the bricks in a more sensible data structure which is easier to iterate.

    For example, you could store them in a flat array, and store their x, y coordinates, instead of generating them from the row / column indexes. You would have a function which generates this flat array of bricks. Then your collision function would be used to remove the brick from the array, so that when looping the array, it does not need a conditional and will have fewer iterations the fewer bricks there are. Finally, to check if all bricks are gone, just check the bricks array length, and now you can call the initial function which generates all the bricks in the flat array.

    Good luck.