Canvas.getContext:事件发生后更改对象的颜色

时间:2019-01-07 22:43:45

标签: javascript html5-canvas

我正在尝试使用html 中的javascript,我从MDN Breakout game教程开始。 Here is how the complete game looks like.我被其中一项练习所困扰,经过一个小时的谷歌搜索,我真的找不到解决我问题的方法! :((。以下代码在画布上生成一个球。

ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = '#FFFFF';
ctx.fill();
ctx.closePath();

我需要球与砖块之一碰撞后改变颜色。为了实现这一点,我创建了一个变量来存储颜色值:let colour = '#FFFFF';,随后在一个检测碰撞的函数中,更改了该变量的值。但是,无论何时球变色,效果都很好,砖块和球拍也是如此。在尝试解决此问题时,我发现,每当我手动更改球,砖块或球拍的颜色(所有这些颜色均设置为不同的功能)时,所有对象也会更改颜色。

这很奇怪,因为如果在一个emply .js文件中,我仅制作两个形状并用不同的颜色对其进行着色,则效果很好:

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');    

    ctx.beginPath();
    ctx.rect(0, 0, 20, 40);
    ctx.fillStyle = 'cyan';
    ctx.fill();
    ctx.closePath();


    ctx.beginPath();
    ctx.arc(50, 50, 20, 0, Math.PI*2);
    ctx.fillStyle = 'black';
    ctx.fill();
    ctx.closePath();

但是使用我现在拥有的所有游戏代码,我无法为不同的对象分配不同的颜色,而是它们都改变了颜色!我不知道如何解决这个问题,只改变球的颜色!有人知道是什么原因引起的吗?请帮忙,非常感谢

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

//Ball variables
const radius = 10;
let colour = '#FFFFF';
let x = canvas.width / 2;
let y = canvas.height - 30;
let dx = 2;
let dy = -2;

//Paddle
const paddleHeight = 10;
let paddleWidth = 100;
let paddleX = (canvas.width - paddleWidth) / 2;

//Paddle movement
var rightPressed = false;
var leftPressed = false;

//Bricks
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
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 draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBall();
  drawPaddle();
  drawBricks();
  collisionDetection();
  x += dx;
  y += dy;
  if (rightPressed && paddleX < canvas.width - paddleWidth) {
    paddleX += 7;
  } else if (leftPressed && paddleX > 0) {
    paddleX -= 7;
  }
}

function drawBall() {
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2);
  ctx.fillStyle = colour;
  ctx.fill();
  ctx.closePath();

  //Bounce off the walls
  if (x + dx > canvas.width - radius || x + dx < radius) {
    dx = -dx;
  }
  if (y + dy < radius) {
    dy = -dy;
  } else if (y + dy > canvas.height - radius) {
    //Collision detection (ball + paddle)
    if (x > paddleX && x < paddleX + paddleWidth) {
      dy = -dy;
    } else {
      //alert("GAME OVER");
      document.location.reload();
    }
  }
}


function drawPaddle() {
  ctx.beginPath();
  ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
  ctx.fillStyle = '#FFFFF';
  ctx.fill();
  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.fillStyle = "#FFFFF";
        ctx.fill();
        ctx.closePath();
      }
    }
  }
}

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

function keyDownHandler(e) {
  if (e.key == "Right" || e.key == "ArrowRight") {
    rightPressed = true;
  } else if (e.key == "Left" || e.key == "ArrowLeft") {
    leftPressed = true;
  }
}

function keyUpHandler(e) {
  if (e.key == "Right" || e.key == "ArrowRight") {
    rightPressed = false;
  } else if (e.key == "Left" || e.key == "ArrowLeft") {
    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;
          colour = '#ff9ecb';
        }
      }
    }
  }
}

var interval = setInterval(draw, 10);
<!DOCTYPE html>
<html>
<head>

<title>Breakout Game</title>

</head>
<body>

<canvas id='canvas' height='320' width='480'></canvas>
<script src="app.js"></script>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

您在fillStyle上使用的彩色十六进制代码看起来像是一个小错误,无效。请参阅以下代码段中的更正:

let colour = '#FFFFF'; // Six characters invalid

收件人:

let colour = '#FF0000'; // Seven characters valid

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

//Ball variables
const radius = 10;

// Fix colour
let colour = '#FF0000';
let x = canvas.width / 2;
let y = canvas.height - 30;
let dx = 2;
let dy = -2;

//Paddle
const paddleHeight = 10;
let paddleWidth = 100;
let paddleX = (canvas.width - paddleWidth) / 2;

//Paddle movement
var rightPressed = false;
var leftPressed = false;

//Bricks
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
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 draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBall();
  drawPaddle();
  drawBricks();
  collisionDetection();
  x += dx;
  y += dy;
  if (rightPressed && paddleX < canvas.width - paddleWidth) {
    paddleX += 7;
  } else if (leftPressed && paddleX > 0) {
    paddleX -= 7;
  }
}

function drawBall() {
   // Update to valid colour
  ctx.fillStyle = colour;
  
  ctx.beginPath();  
  ctx.arc(x, y, radius, 0, Math.PI * 2);
  ctx.fill();
  ctx.closePath();
  
  //Bounce off the walls
  if (x + dx > canvas.width - radius || x + dx < radius) {
    dx = -dx;
  }
  if (y + dy < radius) {
    dy = -dy;
  } else if (y + dy > canvas.height - radius) {
    //Collision detection (ball + paddle)
    if (x > paddleX && x < paddleX + paddleWidth) {
      dy = -dy;
    } else {
      //alert("GAME OVER");
      document.location.reload();
    }
  }
}


function drawPaddle() {
   // Update to valid colour
  ctx.fillStyle = '#00FF00'; 
  // Consider using fillRect
  ctx.fillRect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
}

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;
        
        // Update to valid colour
        ctx.fillStyle = "#FFFFaa";
        // Consider using fillRect
        ctx.fillRect(brickX, brickY, brickWidth, brickHeight); 
      }
    }
  }
}

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

function keyDownHandler(e) {
  if (e.key == "Right" || e.key == "ArrowRight") {
    rightPressed = true;
  } else if (e.key == "Left" || e.key == "ArrowLeft") {
    leftPressed = true;
  }
}

function keyUpHandler(e) {
  if (e.key == "Right" || e.key == "ArrowRight") {
    rightPressed = false;
  } else if (e.key == "Left" || e.key == "ArrowLeft") {
    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;
          colour = '#ff9ecb';
        }
      }
    }
  }
}

var interval = setInterval(draw, 10);
<!DOCTYPE html>
<html>
<head>

<title>Breakout Game</title>

</head>
<body>

<canvas id='canvas' height='320' width='480'></canvas>
<script src="app.js"></script>
</body>
</html>

另外,请考虑使用如上所述的fillRect(),以实现更简单的实现。希望有帮助!