javascript - 即使在使用 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>
解决方案
/* 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>
推荐阅读
- neo4j - 如何在 NEO4J 的路径中获取不同的节点?
- python - 具有多个元素的数组的真值是不明确的。使用 ReLu 函数使用 a.any() 或 a.all() python numpy
- google-sheets - 如何计算 ArrayFormula 内每行最后 7 行的总和?
- php - 尝试使用 ---location 参数在 PHP 中发出 cURL 请求
- jenkins - Jenkins管道groovy:我怎样才能获得另一个工作构建的工作空间
- html - 如何根据下拉菜单显示不同的文本?
- javascript - paramMap 项目总是使用 Angular 8 路由返回 null
- go - Go-Gorm 有一个始终为空的子表
- java - 如何在 JavaFX 中隐藏和取消隐藏折线图中的数据点?
- jquery - 单选按钮不适用于 jquery 中继器