How to change a elements colour - javascript

I made a game of atari breakout of where i want the bricks to be multi coloured. I want it so that each individual brick has its own random colour that is randomly generated. I also dont want the other attributes such as the ball and the paddle to be targeted with this random colour change.
Here are the lines of code:
'use strict';
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 20;
var x = canvas.width/2;
var y = canvas.height-30;
var dx = 3;
var dy = -3;
var paddleHeight = 10;
var paddleWidth = 175;
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 11;
var brickColumnCount = 5;
var brickWidth = 73;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
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 };
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, 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 mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if(relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth/2;
}
}
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;
score++;
if(score == brickRowCount*brickColumnCount) {
alert("YOU WIN, CONGRATS!");
document.location.reload();
}
}
}
}
}
}
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
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 = (r*(brickWidth+brickPadding))+brickOffsetLeft;
var brickY = (c * (brickHeight + brickPadding)) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fill();
ctx.closePath();
}
}
}
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillText("Score: "+score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawLives();
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 {
lives--;
if(!lives) {
alert("GAME OVER");
document.location.reload();
}
else {
x = canvas.width/2;
y = canvas.height-30;
dx = 3;
dy = -3;
paddleX = (canvas.width-paddleWidth)/2;
}
}
}
if(rightPressed && paddleX < canvas.width-paddleWidth) {
paddleX += 7;
}
else if(leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
function hardFunction(){
ballRadius = 8;
paddleWidth = 80;
lives = 1;
dx = 5;
dy = -5;
};
function mediumFunction(){
ballRadius = 15;
paddleWidth = 120;
lives = 2;
dx = 4;
dy = -4;
};
function easyFunction(){
ballRadius = 20;
paddleWidth = 175;
lives = 3;
dx = 3;
dy = -3;
};
draw();
console.log(ctx.fillStyle);
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
button {
border: none;
color: gray;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px 0px 16.67%;
transition-duration: 0.4s;
cursor: pointer
}
.buttonHard:hover {
background-color: red;
color: black;
}
.buttonMedium:hover {
background-color: yellow;
color: black;
}
.buttonEasy:hover {
background-color: green;
color: black;
}
<canvas id="myCanvas" width="960" height="640"></canvas>
<button id="button" class="buttonHard" onclick="hardFunction();">Hard Mode</button>
<button id="button" class="buttonMedium" onclick="mediumFunction();">Medium Mode</button>
<button id="button" class="buttonEasy" onclick="easyFunction();">Easy Mode</button>
<script src="script.js"></script>

After the bricks are drawn reset the ctx.fillStyle back to black to not affect the paddle and ball color.
You can try it like this:
'use strict';
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 20;
var x = canvas.width/2;
var y = canvas.height-30;
var dx = 3;
var dy = -3;
var paddleHeight = 10;
var paddleWidth = 175;
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 11;
var brickColumnCount = 5;
var brickWidth = 73;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
// colors picked from here: https://hightekk.com/tools/swatch
const colors = [
"#d1c4e9",
"#b39ddb",
"#9575cd",
"#7e57c2",
"#673ab7",
"#5e35b1",
"#512da8",
"#4527a0",
"#311b92",
"#b388ff",
"#7c4dff",
"#651fff",
"#6200ea",
];
function getRandomColor(){
return colors[Math.floor(Math.random() * colors.length)];
}
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, color: getRandomColor() };
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, 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 mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if(relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth/2;
}
}
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;
score++;
if(score == brickRowCount*brickColumnCount) {
alert("YOU WIN, CONGRATS!");
document.location.reload();
}
}
}
}
}
}
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
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 = (r*(brickWidth+brickPadding))+brickOffsetLeft;
var brickY = (c * (brickHeight + brickPadding)) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = bricks[c][r].color;
ctx.fill();
ctx.closePath();
}
}
}
ctx.fillStyle = "#000000";
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillText("Score: "+score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawLives();
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 {
lives--;
if(!lives) {
alert("GAME OVER");
document.location.reload();
}
else {
x = canvas.width/2;
y = canvas.height-30;
dx = 3;
dy = -3;
paddleX = (canvas.width-paddleWidth)/2;
}
}
}
if(rightPressed && paddleX < canvas.width-paddleWidth) {
paddleX += 7;
}
else if(leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
function hardFunction(){
ballRadius = 8;
paddleWidth = 80;
lives = 1;
dx = 5;
dy = -5;
};
function mediumFunction(){
ballRadius = 15;
paddleWidth = 120;
lives = 2;
dx = 4;
dy = -4;
};
function easyFunction(){
ballRadius = 20;
paddleWidth = 175;
lives = 3;
dx = 3;
dy = -3;
};
draw();
console.log(ctx.fillStyle);
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
button {
border: none;
color: gray;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px 0px 16.67%;
transition-duration: 0.4s;
cursor: pointer
}
.buttonHard:hover {
background-color: red;
color: black;
}
.buttonMedium:hover {
background-color: yellow;
color: black;
}
.buttonEasy:hover {
background-color: green;
color: black;
}
<canvas id="myCanvas" width="960" height="640"></canvas>
<button id="button" class="buttonHard" onclick="hardFunction();">Hard Mode</button>
<button id="button" class="buttonMedium" onclick="mediumFunction();">Medium Mode</button>
<button id="button" class="buttonEasy" onclick="easyFunction();">Easy Mode</button>
<script src="script.js"></script>

Perhaps the desired result would also want to have some control over the randomized colors.
This basic example generate a random color in hsl with a randomized hue, but keep saturation and lightness the same at a set number.
If needed, further calculation based saturation and lightness can be added for coloring each brick with some patterns. The example includes a basic use of this by generating a gradient in lightness based on rows, but it is totally optional.
Example:
"use strict";
// 👇 Set a range for random color hue,
const minHue = 0;
const maxHue = 360;
// 👇 Set custom saturation and lightness
const saturation = 100;
const lightness = 50;
// 👇 Optional: set lightness as an array for a row gradient
const lightnessList = [30, 40, 50, 60, 70];
const randColor = (minHue, maxHue, saturation, lightness) =>
`hsl(${
minHue + Math.floor(Math.random() * (maxHue - minHue))
} ${saturation}% ${lightness}%)`;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 20;
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 3;
var dy = -3;
var paddleHeight = 10;
var paddleWidth = 175;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 11;
var brickColumnCount = 5;
var brickWidth = 73;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
var bricks = [];
for (var c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
// 👇 Optional: for using lightnessList
const lit = lightnessList?.[c] || lightness;
for (var r = 0; r < brickRowCount; r++) {
bricks[c][r] = {
x: 0,
y: 0,
status: 1,
color: randColor(minHue, maxHue, saturation, lit),
};
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, 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 mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth / 2;
}
}
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;
score++;
if (score == brickRowCount * brickColumnCount) {
alert("YOU WIN, CONGRATS!");
document.location.reload();
}
}
}
}
}
}
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
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 = r * (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = c * (brickHeight + brickPadding) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.fillStyle = bricks[c][r]?.color || "#000";
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fill();
ctx.closePath();
ctx.fillStyle = "#000";
}
}
}
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillText("Score: " + score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillText("Lives: " + lives, canvas.width - 65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawLives();
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 {
lives--;
if (!lives) {
alert("GAME OVER");
document.location.reload();
} else {
x = canvas.width / 2;
y = canvas.height - 30;
dx = 3;
dy = -3;
paddleX = (canvas.width - paddleWidth) / 2;
}
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
function hardFunction() {
ballRadius = 8;
paddleWidth = 80;
lives = 1;
dx = 5;
dy = -5;
}
function mediumFunction() {
ballRadius = 15;
paddleWidth = 120;
lives = 2;
dx = 4;
dy = -4;
}
function easyFunction() {
ballRadius = 20;
paddleWidth = 175;
lives = 3;
dx = 3;
dy = -3;
}
draw();
console.log(ctx.fillStyle);
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
button {
border: none;
color: gray;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px 0px 16.67%;
transition-duration: 0.4s;
cursor: pointer;
}
.buttonHard:hover {
background-color: red;
color: black;
}
.buttonMedium:hover {
background-color: yellow;
color: black;
}
.buttonEasy:hover {
background-color: green;
color: black;
}
<canvas id="myCanvas" width="960" height="640"></canvas>
<button id="button" class="buttonHard" onclick="hardFunction();">Hard Mode</button>
<button id="button" class="buttonMedium" onclick="mediumFunction();">Medium Mode</button>
<button id="button" class="buttonEasy" onclick="easyFunction();">Easy Mode</button>
<script src="script.js"></script>
Hope this will help.

Related

Colors change too fast

So I was making a breakout game for class and finished it, so for fun, my teacher asked before I went off for Christmas break that I make the bricks change color, and yea I did that but it's WAY too fast. He says it's fine how it is- if it was slower, or if the colors changed every time a brick was hit. Can I get some help?
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ballRadius = 10;
x = canvas.width/2;
y = canvas.height-30;
dx = 2;
dy = -2;
const ballColor1 = "#0095DD";
const ballColor2 = "#ff0000";
var ballColor = ballColor1;
paddleHeight = 10;
paddleWidth = 75;
paddleX = (canvas.width-paddleWidth)/2;
rightPressed = false;
leftPressed = false;
const brickRowCount = 5;
const brickColumnCount = 3;
const brickWidth = 75;
const brickHeight = 20;
const brickPadding = 10;
const brickOffsetTop = 30;
const brickOffsetLeft = 30;
let score = 0;
let lives = 3;
const bricks = [];
for(let c=0; c<brickColumnCount; c++) {
bricks[c] = [];
for(let r=0; r<brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1 };
}
}
function randBrick() {
return "#" + ((1 << 24) * Math.random() | 0).toString(16).padStart(6, "0")
}
console.log(randBrick());
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
document.getElementById("startAgain").addEventListener("click", function() {
document.location.reload();
clearInterval(interval);
});
document.getElementById("playAgain").addEventListener("click", function() {
document.location.reload();
clearInterval(interval);
});
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 mouseMoveHandler(e) {
const relativeX = e.clientX - canvas.offsetLeft;
if(relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth/2;
}
}
function collisionDetection() {
for(let c=0; c<brickColumnCount; c++) {
for(let r=0; r<brickRowCount; r++) {
const 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;
score++;
if(score == brickRowCount*brickColumnCount) {
document.getElementById('gameWin').style.display = 'block';
clearInterval(interval);
randBrick();
}
}
}
}
}
}
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
ctx.fillStyle = ballColor;
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function drawBricks() {
for(let c=0; c<brickColumnCount; c++) {
for(let r=0; r<brickRowCount; r++) {
if(bricks[c][r].status == 1) {
const brickX = (r*(brickWidth+brickPadding))+brickOffsetLeft;
const brickY = (c*(brickHeight+brickPadding))+brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = "#" + ((1 << 24) * Math.random() | 0).toString(16).padStart(6, "0");
ctx.fill();
ctx.closePath();
}
}
}
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "#0095DD";
ctx.fillText("Score: "+score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillStyle = "#0095DD";
ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
drawBricks();
drawPaddle();
drawScore();
drawLives();
collisionDetection();
if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
dx = -dx;
if (ballColor == ballColor1) {
ballColor = ballColor2;
} else {
ballColor = ballColor1;
}
}
if(y + dy < ballRadius) {
dy = -dy;
if (ballColor == ballColor1) {
ballColor = ballColor2;
} else {
ballColor = ballColor1;
}
}
else if(y + dy > canvas.height-ballRadius) {
if(x > paddleX && x < paddleX + paddleWidth) {
dy = -dy;
}
else {
lives--;
if(!lives) {
document.getElementById('gameOver').style.display = 'block';
clearInterval(interval);
}
else {
x = canvas.width/2;
y = canvas.height-30;
dx = 3;
dy = -3;
paddleX = (canvas.width-paddleWidth)/2;
}
}
}
if(rightPressed && paddleX < canvas.width-paddleWidth) {
paddleX += 7;
}
else if(leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
draw();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Breakout</title>
<style>
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
border: 5px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="480" height="320"></canvas>
<div id="gameOver" style="display: none; position: absolute; top: 50px; left: 50px; width: 200px;">
<h1>Game Over!</h1>
<button id="startAgain">Try Again?</button>
</div>
<div id="gameWin" style="display: none; position: absolute; top: 50px; left: 50px; width: 200px;">
<h1>You Win!</h1>
<button id="playAgain">Play Again?</button>
</div>
<script src=breakoutCode.js></script>
</body>
</html>
You're changing the color on every block draw. The Math.random() is getting called on every draw to the canvas thus that means it's changing every block's color on each draw.
Possible solutions:
Save the colors in an array + a the time you want to change them
Save the colors in an array and change them randomly
Don't re-draw the blocks on every re-draw (better for performance)
Here's one possible solution that stores the colors in an array and changes them randomly:
let blkColors = []
function drawBricks() {
for(let c=0; c<brickColumnCount; c++) {
for(let r=0; r<brickRowCount; r++) {
if(bricks[c][r].status == 1) {
const brickX = (r*(brickWidth+brickPadding))+brickOffsetLeft;
const brickY = (c*(brickHeight+brickPadding))+brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
if (!blkColors[c] || !blkColors[c][r] || Math.random() > 0.97) { // new color
if (!blkColors[c])
blkColors[c] = [];
ctx.fillStyle = blkColors[c][r] = "#" + ((1 << 24) * Math.random() | 0).toString(16).padStart(6, "0");
} else {
ctx.fillStyle = blkColors[c][r];
}
ctx.fill();
ctx.closePath();
}
}
}
}
On JSFiddle

How to draw a falling text in JS canvas?

I am fairly new to using html canvas. I'm creating a breakout game. I want to implement a fall text when a brick is hit that the paddle at the bottom can catch to increase points.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 4;
var brickColumnCount = 4;
var brickWidth = 50;
var brickHeight = 10;
var brickPadding = 15;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
var reward = { value: 1, x: canvas.width / 2 - 5, y: 20 };
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 };
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
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 mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth / 2;
}
}
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 + 5 > b.x &&
x - 5 < b.x + brickWidth &&
y > b.y &&
y < b.y + brickHeight
) {
reward.value++;
reward.x = b.x;
reward.y = b.y;
// drawReward();
// drawReward(x, y);
ctx.font = "16px Arial";
ctx.fillStyle = "#50b848";
ctx.fillText("1GB", 8, 10);
dy = -dy;
b.status = 0;
score++;
if (score == brickRowCount * brickColumnCount) {
alert("YOU WIN, CONGRATS!");
document.location.reload();
}
}
}
}
}
}
function drawBall() {
// var img = document.getElementById("icon");
// var img = new Image();
// img.src = "/images/glo_icon.png";
// ctx.drawImage(img, x, y, 25, 25);
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#50b848";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#50b848";
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 = r * (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = c * (brickHeight + brickPadding) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = `#50b848`;
ctx.fill();
ctx.closePath();
}
}
}
}
// function drawReward() {
// // ctx.clearRect(reward.x, reward.y, 30, 30);
// ctx.font = "25px Arial";
// ctx.fillStyle = "#ffffff";
// ctx.fillText(reward.value + "GB", canvas.width / 2 - 5, 20);
// if (y >= 300) {
// y = 290; // Set the ball's Y position to the bottom of the canvas
// dy = 0; //And finally this set the falling is zero
// }
// }
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "purple";
ctx.fillText("Score: " + score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.fillText("Lives: " + lives, canvas.width - 65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawLives();
// drawReward();
collisionDetection();
if (x + dx > canvas.width - ballRadius || x + dx < -5) {
dx = -dx;
}
if (y + dy < -5) {
dy = -dy;
}
if (y + dy > canvas.height - ballRadius) {
if (x > paddleX - 10 && x < paddleX + paddleWidth + 10) {
dy = -dy;
} else {
dy = -dy;
lives--;
if (!lives) {
// alert("GAME OVER");
// document.location.reload();
} else {
x = canvas.width / 2;
y = canvas.height - 30;
dx = 3;
dy = -3;
paddleX = (canvas.width - paddleWidth) / 2;
}
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
draw();
<canvas id="myCanvas"></canvas>
when a brick is hit, at text like "2X" should be drawn from that point and drop down to the bottom so the paddle can pick it up.
thanks for the assistance in advance
You need to be able to render multiple rewards; this is because several blocks may be hit within a short period of time, leading to several falling text items at once.
The only real trick here is to create an array of rewards, create another top-level rendering function named drawRewards (in the plural), and within that function, loop through all rewards in our rewards array, and render them. (Oh, and don't forget to actually add new rewards into the array whenever a block is hit!) I've modified your code to do all these things; let me know if this is what you were looking for:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 4;
var brickColumnCount = 4;
var brickWidth = 50;
var brickHeight = 10;
var brickPadding = 15;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
var reward = { value: 1, x: canvas.width / 2 - 5, y: 20 };
let rewards = [];
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 };
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
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 mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth / 2;
}
}
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 + 5 > b.x &&
x - 5 < b.x + brickWidth &&
y > b.y &&
y < b.y + brickHeight
) {
reward.value++;
reward.x = b.x;
reward.y = b.y;
rewards.push({ x: b.x, y: b.y, text: '1GB' });
dy = -dy;
b.status = 0;
score++;
if (score == brickRowCount * brickColumnCount) {
document.location.reload();
}
}
}
}
}
}
function drawBall() {
// var img = document.getElementById("icon");
// var img = new Image();
// img.src = "/images/glo_icon.png";
// ctx.drawImage(img, x, y, 25, 25);
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#50b848";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#50b848";
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 = r * (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = c * (brickHeight + brickPadding) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = `#50b848`;
ctx.fill();
ctx.closePath();
}
}
}
}
function drawRewards() {
for (let reward of rewards) {
reward.y = reward.y + 1;
ctx.font = "12px Arial";
ctx.fillStyle = "#000";
ctx.fillText(reward.text, reward.x, reward.y);
}
// Remove any rewards which fall out of view
rewards = rewards.filter(reward => reward.y < canvas.height);
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "purple";
ctx.fillText("Score: " + score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.fillText("Lives: " + lives, canvas.width - 65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawRewards();
drawLives();
// drawReward();
collisionDetection();
if (x + dx > canvas.width - ballRadius || x + dx < -5) {
dx = -dx;
}
if (y + dy < -5) {
dy = -dy;
}
if (y + dy > canvas.height - ballRadius) {
if (x > paddleX - 10 && x < paddleX + paddleWidth + 10) {
dy = -dy;
} else {
dy = -dy;
lives--;
if (!lives) {
// alert("GAME OVER");
// document.location.reload();
} else {
x = canvas.width / 2;
y = canvas.height - 30;
dx = 3;
dy = -3;
paddleX = (canvas.width - paddleWidth) / 2;
}
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
draw();
<canvas id="myCanvas"></canvas>

How to create a game over screen for a basic HTML/JS game?

I have been making an Atari Breakout inspired game based off of a tutorial. I was wondering how to make a "GAME OVER" screen that will show up once the player dies. The code that I have has a variable that I created called "DrawDeath()". I have it coded so that text appears when you die but for some reason it never shows up.
var interval = setInterval(draw, 10);
var canvas = document.getElementById("myCanvas"); //Variables for the canvas, ball, paddle, keys, and bricks
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
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;
var score = 0;
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 };
}
}
document.addEventListener("keydown", keyDownHandler, false); //Listening for pressed keys
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.code == "ArrowRight") { //If key is pressed
rightPressed = true;
}
if (e.code == 'ArrowLeft') {
leftPressed = true;
}
else if (e.code == 'ArrowDown') {
downPressed = true;
}
}
function keyUpHandler(e) {
if (e.code == "ArrowRight") { //If key is up
rightPressed = false;
}
if (e.code == 'ArrowLeft') {
leftPressed = false;
}
else if (e.code == 'ArrowDown') {
downPressed = 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;
score++;
if (score == brickRowCount * brickColumnCount) {
drawDeath();
}
}
}
}
}
}
function drawDeath() {
ctx.font = "32px Courier New";
ctx.fillStyle = "#000000";
ctx.fillText("HAHA YU LOOZD (pres doun arouw tu x-it)");
if (downPressed = true)
document.location.reload();
clearInterval(interval);
}
function drawScore() {
ctx.font = "16px Courier New";
ctx.fillStyle = "#0E17E8";
ctx.fillText("Scores is: " + score, 8, 20);
}
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2); //Drawing the Ball
ctx.fillStyle = "#32CD32";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight); //Drawing the Paddle
ctx.fillStyle = "#0095DD";
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);
if (randomNumber == 1)
ctx.fillStyle = "#0095DD";
if (randomNumber == 2)
ctx.fillStyle = "#FF0000";
if (randomNumber == 3)
ctx.fillStyle = "#FF8A00";
if (randomNumber == 4)
ctx.fillStyle = "0100FF";
ctx.fill()
ctx.closePath();
}
}
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); //Clears the screen after each motion
drawBall();
drawPaddle();
drawBricks();
drawScore();
collisionDetection();
//dx = dx + (Math.floor(Math.random() * 5 - 2));
var cx = dx + (Math.floor(Math.random() * 5 - 2));
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) { //Bounces the ball
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
if (x > paddleX && x < paddleX + paddleWidth) { //Paddle Collision features
dy = -dy;
dx = cx;
}
else {
Text("HAHA YU LOOZD");
document.location.reload(); //Death Detection
clearInterval(interval);
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) { //Paddle Controls
paddleX += 7;
}
else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Bad Gramarrs</title>
<style>
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
#main {
display: none;
}
#newGame, #creditBtn, #backBtn {
text-align: center;
vertical-align: middle;
border: 2px solid goldenrod;
border-radius: 7px;
background-color: gold;
color: orangeRed;
font-size: 32px;
font-weight: bold;
font-family: "Courier New";
width: 5em;
margin: 5px auto;
}
#theHead {
text-align: center;
margin: unset;
color: orange;
font-size: 2em;
font-family: "Courier New";
}
#credits {
text-align: center;
margin: unset;
color: orange;
font-size: 2em;
font-family: "Courier New";
display: none;
background-color: inherit;
}
#backBtn {
display: none;
}
</style>
</head>
<body>
<div id="theHead">Bad Gramarrs</div>
<div id="newGame" onclick="runGame()" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'">Strt Gaem</div>
<div id="creditBtn" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'" onclick="showCredits()">Credets</div>
<div id="credits">Bad Gramarrs: Maed buy mi</div>
<div id="backBtn" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'" onclick="goBack()">Back</div>
<div id="main">
<canvas id="myCanvas" width="480" height="320"></canvas>
</div>
<script src="atari.js"></script>
<script>
var runGame = function () {
document.getElementById("newGame").style.display = "none";
document.getElementById("theHead").style.display = "none";
document.getElementById("credits").style.display = "none";
document.getElementById("main").style.display = "block";
document.getElementById("creditBtn").style.display = "none";
randomNumber = Math.floor(Math.random() * 4 + 1);
};
var showCredits = function () {
document.getElementById("theHead").style.display = "none";
document.getElementById("creditBtn").style.display = "none";
document.getElementById("newGame").style.display = "none";
document.getElementById("credits").style.display = "block";
document.getElementById("backBtn").style.display = "block";
};
var goBack = function () {
document.getElementById("backBtn").style.display = "none";
document.getElementById("credits").style.display = "none";
document.getElementById("theHead").style.display = "block";
document.getElementById("newGame").style.display = "block";
document.getElementById("creditBtn").style.display = "block";
};
</script>
</body>
</html>
You have some errors in your code so I correct what the console showed. I have also changed the code to use requestAnimationFrame. Once a gameOver status has been triggered the requestAnimationFrame will stop running and setInterval will run the drawDeath function. You also have an error in your game over text as you were missing the x and y coordinates.
Additionally I added the downPressed variable that was missing so you could restart the game.
//var interval = setInterval(draw, 10);
let gameOver = false;
var canvas = document.getElementById("myCanvas"); //Variables for the canvas, ball, paddle, keys, and bricks
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var downPressed = false;
var brickRowCount = 3;
var brickColumnCount = 5;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
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 };
}
}
document.addEventListener("keydown", keyDownHandler, false); //Listening for pressed keys
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.code == "ArrowRight") { //If key is pressed
rightPressed = true;
}
if (e.code == 'ArrowLeft') {
leftPressed = true;
}
else if (e.code == 'ArrowDown') {
downPressed = true;
console.log('down')
}
}
function keyUpHandler(e) {
if (e.code == "ArrowRight") { //If key is up
rightPressed = false;
}
if (e.code == 'ArrowLeft') {
leftPressed = false;
}
else if (e.code == 'ArrowDown') {
downPressed = 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;
score++;
if (score == brickRowCount * brickColumnCount) {
gameOver = true;
}
}
}
}
}
}
function drawDeath() {
ctx.font = "20px Courier New";
ctx.textAlign = 'center';
ctx.fillStyle = "#000000";
ctx.fillText("HAHA YU LOOZD (pres doun arouw tu x-it)", canvas.width/2, canvas.height/2);
if (downPressed == true)
document.location.reload();
}
function drawScore() {
ctx.font = "16px Courier New";
ctx.fillStyle = "#0E17E8";
ctx.fillText("Scores is: " + score, 8, 20);
}
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2); //Drawing the Ball
ctx.fillStyle = "#32CD32";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight); //Drawing the Paddle
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function drawBricks() {
let randomNumber;
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);
if (randomNumber == 1)
ctx.fillStyle = "#0095DD";
if (randomNumber == 2)
ctx.fillStyle = "#FF0000";
if (randomNumber == 3)
ctx.fillStyle = "#FF8A00";
if (randomNumber == 4)
ctx.fillStyle = "0100FF";
ctx.fill()
ctx.closePath();
}
}
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); //Clears the screen after each motion
drawBall();
drawPaddle();
drawBricks();
drawScore();
collisionDetection();
//dx = dx + (Math.floor(Math.random() * 5 - 2));
var cx = dx + (Math.floor(Math.random() * 5 - 2));
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) { //Bounces the ball
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
if (x > paddleX && x < paddleX + paddleWidth) { //Paddle Collision features
dy = -dy;
dx = cx;
}
else {
gameOver = true;
setInterval(drawDeath, 10) //Death Detecti
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) { //Paddle Controls
paddleX += 7;
}
else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
if (!gameOver) requestAnimationFrame(draw)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Bad Gramarrs</title>
<style>
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
#main {
display: none;
}
#newGame, #creditBtn, #backBtn {
text-align: center;
vertical-align: middle;
border: 2px solid goldenrod;
border-radius: 7px;
background-color: gold;
color: orangeRed;
font-size: 32px;
font-weight: bold;
font-family: "Courier New";
width: 5em;
margin: 5px auto;
}
#theHead {
text-align: center;
margin: unset;
color: orange;
font-size: 2em;
font-family: "Courier New";
}
#credits {
text-align: center;
margin: unset;
color: orange;
font-size: 2em;
font-family: "Courier New";
display: none;
background-color: inherit;
}
#backBtn {
display: none;
}
</style>
</head>
<body>
<div id="theHead">Bad Gramarrs</div>
<div id="newGame" onclick="runGame()" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'">Strt Gaem</div>
<div id="creditBtn" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'" onclick="showCredits()">Credets</div>
<div id="credits">Bad Gramarrs: Maed buy mi</div>
<div id="backBtn" onmouseover="this.style.backgroundColor = 'goldenrod'" onmouseout="this.style.backgroundColor = 'gold'" onclick="goBack()">Back</div>
<div id="main">
<canvas id="myCanvas" width="480" height="320"></canvas>
</div>
<script src="atari.js"></script>
<script>
var runGame = function () {
document.getElementById("newGame").style.display = "none";
document.getElementById("theHead").style.display = "none";
document.getElementById("credits").style.display = "none";
document.getElementById("main").style.display = "block";
document.getElementById("creditBtn").style.display = "none";
randomNumber = Math.floor(Math.random() * 4 + 1);
draw();
};
var showCredits = function () {
document.getElementById("theHead").style.display = "none";
document.getElementById("creditBtn").style.display = "none";
document.getElementById("newGame").style.display = "none";
document.getElementById("credits").style.display = "block";
document.getElementById("backBtn").style.display = "block";
};
var goBack = function () {
document.getElementById("backBtn").style.display = "none";
document.getElementById("credits").style.display = "none";
document.getElementById("theHead").style.display = "block";
document.getElementById("newGame").style.display = "block";
document.getElementById("creditBtn").style.display = "block";
};
</script>
</body>
</html>

Pause/Play button for my breakout-clone on Javascript

I am trying to code a Pause/Play button for my breakout-clone because I have some text and links planned for the site on which the game will be, so you can pause the game while reading the text or interacting with links. My code is written in JS and mostly consists of "function" and "var". If the CSS or the HTML file is needed for an answer then please contact me. This is my first time asking anything on stackoverflow and I would be glad for any help.
var canvas = document.getElementById("TheCanvas");
var ctx = canvas.getContext("2d");
var x = canvas.width/2;
var y = canvas.height-50;
var dx = 2
var dy = -2;
var ballRadius = 10;
var paddleHeight = 15;
var paddleWidth = 80;
var paddleX = (canvas.width-paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 6;
var brickColumnCount = 4;
var brickWidth = 90;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 15;
var score = 0;
var lives = 99;
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 };
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
function mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if(relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth/2;
}
}
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;
score++;
if(score == brickRowCount*brickColumnCount) {
alert("YOU WIN, WELL DONE!");
document.location.reload();
clearInterval(interval); // <- This is needed for the browser to end the game \\
}
}
}
}
}
}
function drawScore() {
ctx.font = "16px OCR A";
ctx.fillStyle = "#00ffd9"
ctx.fillText("Score: "+score, 8, 20);
}
function drawLives() {
ctx.font = "16px OCR A"
ctx.fillStyle = "00ffd9"
ctx.fillText("Lives: "+lives, canvas.width-85, 20);
}
function drawBall() {
// drawing code \\
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
ctx.lineWidth=3
ctx.strokeStyle = "#00ff00";
ctx.stroke();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height-15, paddleWidth, paddleHeight);
ctx.lineWidth=2
ctx.fillStyle = "#ff0000";
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.strokeStyle = "#33FFFF";
ctx.stroke();
ctx.closePath();
}
}
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawLives();
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 {
lives--;
if(!lives) {
alert("Game Over! Press 'Ok' to reload!");
document.location.reload();
clearInterval(interval); // Is needed for Browser to end the game \\
}
else {
x = canvas.width/2;
y = canvas.height-30
dx = 2;
dy = -2;
paddleX = (canvas.width-paddleWidth)/2;
}
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 3;
} else if (leftPressed && paddleX > 0) {
paddleX -= 3;
}
x += dx;
y += dy;
}
var interval = setInterval(draw, 9);
var checkbox = document.getElementById('darkmode');
function darkmode() {
if (checkbox.checked == true){
document.documentElement.style.setProperty('--primary-background', 'black');
document.documentElement.style.setProperty('--primary-color', 'white');
} else {
document.documentElement.style.setProperty('--primary-background', 'white');
document.documentElement.style.setProperty('--primary-color', 'black');
}
}
checkbox.addEventListener('click', darkmode);
darkmode();

Canvas.getContext : changing the colour of an object once an event happens

I'm trying to get my head around using javascript in the html < canvas >, and I started with the MDN Breakout game tutorial. Here is how the complete game looks like. I'm stuck with one of the exercises and I really could not find any solution to my issue after an hour of googling!! :((. The following code generates a ball on the canvas.
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = '#FFFFF';
ctx.fill();
ctx.closePath();
I needed the ball to change its colour after it collides with one of the bricks. In order to achieve that, I created a variable to store the colour value: let colour = '#FFFFF';, and later in a function which detects collisions, changed the value of this variable. It worked fine, however, whenever the ball changed its colour, so did the bricks and the paddle. As I tried to fix this, I found out that whenever I manually change the colour of either a ball, a brick or a paddle (all of which are set in different functions), all of the objects change the colour as well.
This is very strange, because if in an emply .js file I make just two shapes and colour them differently it works fine:
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();
But with all the game code I have right now, I can not assign different colour to different objects, they all change colour instead! I have no idea how to fix this and change just the colour of the ball! Anyone knows what might be causing the issue? Please help, thank you so much in advance 🙏
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>
Looks like a minor error with the colour hex codes you're using for your fillStyle, which are invalid. See the corrections in the snippet below from:
let colour = '#FFFFF'; // Six characters invalid
To:
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>
Also, consider using fillRect() as shown above, for a slightly simpler implementation. Hope that helps!

Categories