Canvas.getContext: изменение цвета объекта при возникновении события - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь разобраться, используя javascript в html , и я начал с учебника по MDN Breakout . Вот как выглядит полная игра. Я застрял в одном из упражнений и действительно не мог найти решения своей проблемы после часа поиска в Google !! : ((. Следующий код генерирует шар на холсте.

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 голосов
/ 08 января 2019

Похоже, незначительная ошибка с цветными шестнадцатеричными кодами, которые вы используете для 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(), как показано выше, для немного более простой реализации. Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...