首页 > 解决方案 > 即使在使用 beginPath() 和 Closepath() 之后,在画布上绘图时也无法为 fillStyle 使用不同的颜色

问题描述

我试图从类似的问题中找到解决方案,但无济于事,我尝试将 ctx.fillStyle 放在 ctx.beginPath(); 之间 和 ctx.closePath(); 我可以为桨和砖块赋予不同的颜色,但球会从砖块继承颜色,而不是从 randomColor() 函数中获取颜色。以下是代码:-

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
var ballRadius = 10;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2; 
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;


document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

function randomColor() {
  var i = 0;
  var n = 16777215;
  var string = "#"
  var colorDec = rand(i, n);
  var colorHex = colorDec.toString(16);
  var colorCode = string.concat(colorHex);
  return colorCode;
}


function rand(min, max) {
  var min = min || 0,
    max = max || Number.MAX_SAFE_INTEGER;
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

var bricks = [];
for (var c = 0; c < brickColumnCount; c++) {
  bricks[c] = [];
  for (var r = 0; r < brickRowCount; r++) {
    bricks[c][r] = {
      x: 0,
      y: 0,
      status: 1
    };
  }
}

function keyDownHandler(e) {
  if (e.keyCode == 39) {
    rightPressed = true;
  } else if (e.keyCode == 37) {
    leftPressed = true;
  }
}

function keyUpHandler(e) {
  if (e.keyCode == 39) {
    rightPressed = false;
  } else if (e.keyCode == 37) {
    leftPressed = false;
  }
}

function collisionDetection() {
  for (var c = 0; c < brickColumnCount; c++) {
    for (var r = 0; r < brickRowCount; r++) {
      var b = bricks[c][r];
      if (b.status == 1) {
        if (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
          dy = -dy;
          b.status = 0;
          ctx.fillStyle = randomColor();
        }
      }
    }
  }
}

function drawBall() {
  ctx.beginPath();
  ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
  ctx.fill();
  if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
    ctx.fillStyle = randomColor();
  }
  if (y + dy > canvas.height - ballRadius || y + dy < ballRadius) {
    ctx.fillStyle = randomColor();
  }
  ctx.closePath();
}

function drawPaddle() {
  ctx.beginPath();
  ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
  ctx.fill();
  ctx.fillStyle = "#00a6ff";
  ctx.closePath();
}

function drawBricks() {
  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 * (brickHeight + brickPadding)) + brickOffsetTop;
        bricks[c][r].x = brickX;
        bricks[c][r].y = brickY;
        ctx.beginPath();
        ctx.rect(brickX, brickY, brickWidth, brickHeight);
        ctx.fill();
        ctx.fillStyle = "#00a6ff";
        ctx.closePath();
      }
    }
  }
}




function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBall();
  drawPaddle();
  drawBricks();
  collisionDetection();

  if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
    dx = -dx;
  }
  if (y + dy < ballRadius) {
    dy = -dy;
  } else if (y + dy > canvas.height - ballRadius) {
    if (x > paddleX && x < paddleX + paddleWidth) {
      dy = -dy;
    } else {
      alert("GAME OVER");
      document.location.reload();
    }
  }
  if (rightPressed && paddleX < canvas.width - paddleWidth) {
    paddleX += 7;
  } else if (leftPressed && paddleX > 0) {
    paddleX -= 7;
  }

  y += dy;
  x += dx;
}
setInterval(draw, 10);
* {
  padding: 0;
  margin: 0;
}

canvas {
  background: #eee;
  display: block;
  margin: 0 auto;
}
<canvas id="myCanvas" width="480" height="320"></canvas>

标签: javascripthtml5-canvas

解决方案


/* canvas x,y origin (0,0) is top left
setInterval(draw,10);  is the game loop
*/
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
/*x, y location of the ball  */
var x = canvas.width / 2;
var y = canvas.height - 30;
/*dx,dy no of pixels to move at a time, ie each draw */
var dx = 2;
var dy = -2;
var ballRadius = 10;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;

//JC's extra variables
var brickColours = ['#ff0000', '#00ff00', '#0000ff']; //3 rows each with a different colour
var ballColour = '#eeeeee'; //change the colour when collision light grey
var intervalID = 0; //used to stop game

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

function randomColor() {
  var i = 0;
  var n = 16777215;
  var string = "#"
  var colorDec = rand(i, n);
  var colorHex = colorDec.toString(16);
  var colorCode = string.concat(colorHex);
  //console.log('colorCode ', colorCode);
  return colorCode;
}


function rand(min, max) {
  var min = min || 0,
    max = max || Number.MAX_SAFE_INTEGER;
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

var bricks = [];

for (var c = 0; c < brickColumnCount; c++) {
  bricks[c] = [];
  for (var r = 0; r < brickRowCount; r++) {
    bricks[c][r] = {
      x: 0,
      y: 0,
      status: 1
    };
  }
}

function keyDownHandler(e) {
  if (e.keyCode == 39) {
    rightPressed = true;
  } else if (e.keyCode == 37) {
    leftPressed = true;
  }
}

function keyUpHandler(e) {
  if (e.keyCode == 39) {
    rightPressed = false;
  } else if (e.keyCode == 37) {
    leftPressed = false;
  }
}

function collisionDetection() {
  for (var c = 0; c < brickColumnCount; c++) {
    for (var r = 0; r < brickRowCount; r++) {
      var b = bricks[c][r];
      if (b.status == 1) {
        //mark brick as deleted          
        if (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
          dy = -dy;
          b.status = 0;
          //next 2 lines needed? - change colour on collision
          ballColour = randomColor();
          ctx.fillStyle = ballColour;
        }
      }
    }
  }
}

function drawBall() {
  //if ball is offscreen redraw with a random colour    
  ctx.beginPath();
  ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
  ctx.fillStyle = ballColour;
  //ctx.fill();
  //if moves off screen left or right
  if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
    ballColour = randomColor();
    ctx.fillStyle = ballColour;
  }
  //if moves off screen down or up
  if (y + dy > canvas.height - ballRadius || y + dy < ballRadius) {
    ballColour = randomColor();
    ctx.fillStyle = ballColour;
  }
  ctx.fill();
  ctx.closePath();
}

function drawPaddle() {
  //always draw with the same colour    
  ctx.beginPath();
  ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
  //ctx.fill();
  ctx.fillStyle = "#00a6ff";
  ctx.fill();
  ctx.closePath();
}

function drawBricks() {
  /* work through array of bricks and draw all those present, same colour  */

  for (var c = 0; c < brickColumnCount; c++) {
    for (var r = 0; r < brickRowCount; r++) {
      //set each row to a different colour
      ctx.fillStyle = brickColours[r];


      //if brick is not deleted draw it
      if (bricks[c][r].status == 1) {
        var brickX = (c * (brickWidth + brickPadding)) + brickOffsetLeft;
        var brickY = (r * (brickHeight + brickPadding)) + brickOffsetTop;
        bricks[c][r].x = brickX;
        bricks[c][r].y = brickY;
        ctx.beginPath();
        ctx.rect(brickX, brickY, brickWidth, brickHeight);
        //ctx.fill();
        //ctx.fillStyle = "#00a6ff";
        ctx.fill();
        ctx.closePath();
      }
    }
  }
}



//draw is the main loop that drives the game
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBall();
  drawPaddle();
  drawBricks();
  collisionDetection();

  if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
    dx = -dx;
  }
  if (y + dy < ballRadius) {
    dy = -dy;
  } else if (y + dy > canvas.height - ballRadius) {
    if (x > paddleX && x < paddleX + paddleWidth) {
      dy = -dy;
    } else {
      alert("GAME OVER, reload page to start again");
      clearInterval(intervalID);
      //document.location.reload();
    }
  }

  //move paddleX left or right if in range
  if (rightPressed && paddleX < canvas.width - paddleWidth) {
    paddleX += 7;
  } else if (leftPressed && paddleX > 0) {
    paddleX -= 7;
  }

  y += dy;
  x += dx;
}
* {
  padding: 0;
  margin: 0;
}

canvas {
  background: #eee;
  /* grey */
  display: block;
  margin: 0 auto;
}
<h1>breakout problem</h1>
<button onclick="intervalID=setInterval(draw, 10);">Play</button>
<canvas id="myCanvas" width="480" height="320"></canvas>


推荐阅读