Unable to draw to canvas - javascript

I have a project where I have to create a block breaking game in canvas, but for some reason the code has stopped drawing in the canvas and I haven't been able to find a solution to the problem.
//global variable
//setting the canvas state
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//Boolean variables for each stage of the game
var startscreen = true;
var gameplaying = false;
var Game_over = false;
//Setting the ball position and size
var ball_x = canvas.width / 2;
var ball_y = canvas.height - 30;
var ballRadius = 5;
//Setting the ball movement
var dx = 2;
var dy = -2;
//PLayer paddle size
var p_height = 10;
var p_width = 100;
//Player paddle start position
var Paddlex = (canvas.width - p_width) / 2;
var Paddley = canvas.height - p_height;
//making sure the paddle doesnt move on its own
var paddleright = false;
var paddleleft = false;
//Set up the target blocks
var brickRowCount = 5;
var brickColumnCount = 13;
var brickWidth = 24;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var rowColours = ["#2294B2", "#FF3175", "#17CEFF", "#CCBF27", "#B2A507"];
var bricks = [];
for (c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
for (r = 0; r < brickRowCount; r++) {
bricks[c][r] = {
x: 0,
y: 0,
status: 1
};
}
}
//setting the event listeners to detect keypresses
document.addEventListener("Keydown", keyDownHandler, false);
document.addEventListener("Keyup", keyUpHandler, false);
//Detecting the key press
function keyDownHandler(e) {
if (e.keyCode == 39) {
paddleright = true;
}
if (e.keyCode == 37) {
paddleleft = true;
}
}
//Detecting the Key press has stopped
function keyUpHandler(e) {
if (e.keyCode == 39) {
paddleright = false;
}
if (e.keyCode == 37) {
paddleleft = false;
} else if (e.keyCode == 13) {
startscreen = false;
gameplaying = true;
Game_over = false;
}
}
//drawing the ball
function ball() {
ctx.beginPath();
ctx.arc(ball_x, ball_y, ballRadius, 0, Math.pi * 2);
ctx.fillstyle = "red";
ctx.fill();
ctx.closePath();
}
//drawing player paddle
function paddle() {
ctx.beginPath();
ctx.rect(Paddlex, Paddley, p_width, p_height);
ctx.fillstyle = "green";
ctx.fill();
ctx.closePath();
}
//Drawing the blocks
function drawBricks() {
for (c = 0; c < brickColumnCount; c++) {
for (r = 0; r < brickRowCount; r++) {
ctx.fillstyle = rowColours[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.closePath();
}
}
}
}
//drawing the above functions to the screen
function draw() {
//Startscreen and main menu
if (startscreen) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Set background colour
var gradient = ctx.createLinearGradient(0, 0, 170, 0);
gradient.addcolorstop(0, 'blue');
gradient.addcolorstop(0, 'orange');
ctx.fillstyle = gradient;
ctx.fillRect(0, 0, 500, 500);
//Welcome title
ctx.font = '20px verdana';
ctx.fillstyle = "white";
ctx.fillText("Block Breaker", 50, 50);
//Welcome tagline
ctx.fillText("Break some blocks", 50, 100);
//Rules of play text
ctx.fillText("How to play:", 80, 200);
ctx.fillText("To play, move the paddle", 80, 280);
ctx.fillText("with the left and right arrow keys", 80, 310);
ctx.fillText("Press ENTER to begin.", 80, 250);
// Call key up function
keyUpHandler();
}
//Game play
if (gameplaying) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
//calling the ball, paddle and blocks in the draw function
ball();
paddle();
drawBricks();
//bounce off the walls
if (ball_x + dx > canvas.width - ballRadius || ball_x + dx < ballRadius) {
console.log("Ball bounced off the side");
sx = -dx;
}
//if the ball hits the top
if (ball_y + dy < ballRadius) {
console.log("Ball bounced off the top");
}
//If the ball hits the bottom
if (ball_y + dy > canvas.height - ballRadius) {
//If the ball hits the player1 paddle
if (ball_y + dy > Paddley && ball_x > Paddlex && ball_x < Paddlex + p_width) {
console.log("Ball hit the player paddle");
dy = -dy;
}
//the ball hits the base
else if (ball_y + dy > canvas.height) {
console.log("Ball hit the bottom of the screen");
gameplaying = false;
Game_over = true;
}
}
}
//Gameover screen
if (Game_over) {
var gradient = ctx.createLinearGradient(0, 0, 0, 170);
gradient.addcolorstop(0, "blue");
gradient.addcolorstop(0, "orange");
ctx.fillstyle = gradient;
ctx.fillRect(0, 0, 500, 500);
//Welcome title
ctx.font = '20px verdana';
ctx.fillstyle = "white";
ctx.fillText("Game Over", 50, 50);
//Main Text body
ctx.fillText("Press Enter to return tot the main menu", 80, 200);
//Reload the game
function keyUpHandler(e) {
if (e.keyCode == 13) {
startscreen = true;
Game_over = false;
}
}
}
//If the ball hits a block
if (ball_x)
//Movement speed of the paddle
if (paddleright && Paddlex < canvas.width - p_width) {
Paddlex += 5;
} else if (paddleleft && Paddlex > 0) {
Paddlex -= 5;
}
ball_x += dx;
ball_y += dy;
//Setting the framerate
setInterval(draw, 10);
}
<canvas id="canvas"></canvas>

move the following line down two lines (so it is not inside draw())
setInterval(draw, 10);
Also, I would strongly encourage you to change 10 to (1000 / FPS), where FPS is frames per second. You probably won't be able to finish executing draw() within 10ms thus creating a drag on the CPU

Related

HTML5 Canvas game not working as expected

Good afternoon.
I'm currently developing a simple 2D game using HTML5. The objective of the game is the following: the player (a green ball of size "n") has to move around the map (using the right, left, up and down arrow) and collect the smaller-sized balls. Every time the user collects a ball, its size increases a 25%. The game finishes when the ball gets so big that it's barely impossible to see any balls in the map, in which case a "Game over" text is loaded onto the canvas.
The problem that I'm having is that, in order to know if a player has collected a certain ball I calculate the distance between the user and said ball. If it is less than 3, it counts as collected. To calculate that distance I use a math formula. The thing is, it doesn't work properly. Sometimes the ball disappears when the user is definitely further than a distance of 3. I would like to modify the code so that the ball disappears only when the user touches it. I tried by putting distance === 0, but that's still giving unexpected results.
Here's the source code:
const canvas = document.getElementById("gameArea");
const ctx = canvas.getContext("2d");
let x = 100;
let y = 100;
let radius = 50;
let speed = 10;
let upPressed = false;
let downPressed = false;
let leftPressed = false;
let rightPressed = false;
let gameOver = false;
let points = [ [300, 500], [400, 700], [100, 600], [469, 586], [578, 234], [587, 489] ];
var gAccess = 0;
var multiplier = 1;
let counter = 0;
function drawGame() {
requestAnimationFrame(drawGame);
clearScreen();
inputs();
boundryCheck();
drawGreenBlob();
drawNextTarget();
checkCollision();
}
function checkCollision() {
let b = points[gAccess][0] - x;
let a = points[gAccess][1] - y;
var c = Math.sqrt(a * a + b * b);
if (c < 220) {
gAccess = (gAccess + 1) % points.length;
multiplier += 0.25;
counter++;
console.log(counter);
}
if (counter >= 25) {
gameover = true;
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
drawgameOver();
}
}
function drawNextTarget() {
if (gameOver === true) return;
ctx.beginPath();
ctx.arc(points[gAccess][0], points[gAccess][0], radius / 3, 0, Math.PI * 2);
ctx.fill();
}
function drawgameOver() {
var ctx = canvas.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
grd.addColorStop(0, "black");
grd.addColorStop(1, "gray");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, canvas.width, canvas.height);
var ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.font = "36px Arial";
ctx.fillText("Game Over!", 50, 50);
}
function boundryCheck() {
//up
if (y < radius) {
y = radius;
}
//down
if (y > canvas.height - radius) {
y = canvas.height - radius;
}
//left
if (x < radius) {
x = radius;
}
//right
if (x > canvas.width - radius) {
x = canvas.width - radius;
}
}
function inputs() {
if (upPressed) {
y = y - speed;
}
if (downPressed) {
y = y + speed;
}
if (leftPressed) {
x = x - speed;
}
if (rightPressed) {
x = x + speed;
}
}
function drawGreenBlob() {
ctx.fillStyle = "green";
if (upPressed) {
ctx.fillStyle = "red";
}
if (downPressed) {
ctx.fillStyle = "blue";
}
if (leftPressed) {
ctx.fillStyle = "yellow";
}
if (rightPressed) {
ctx.fillStyle = "purple";
}
ctx.beginPath();
ctx.arc(x, y, radius * multiplier, 0, Math.PI * 2);
ctx.fill();
}
function clearScreen() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
document.body.addEventListener("keydown", keyDown);
document.body.addEventListener("keyup", keyUp);
function keyDown(event) {
//up
if (event.keyCode == 38) {
upPressed = true;
}
//down
if (event.keyCode == 40) {
downPressed = true;
}
//left
if (event.keyCode == 37) {
leftPressed = true;
}
//right
if (event.keyCode == 39) {
rightPressed = true;
}
}
function keyUp(event) {
//up
if (event.keyCode == 38) {
upPressed = false;
}
//down
if (event.keyCode == 40) {
downPressed = false;
}
//left
if (event.keyCode == 37) {
leftPressed = false;
}
//right
if (event.keyCode == 39) {
rightPressed = false;
}
}
drawGame();
<canvas id="gameArea" width=800 height=800></canvas>
Thank you very much for your help and for your attention.
Just like #ChrisG mentioned you need to include the radius on the checkCollision if statement:
if (c < radius * multiplier + radius / 3) {
the radius * multiplier is the radius of our player
the radius / 3 is the radius of the balls
This is technically making the collision when the two perimeters touch if you want to make something different you can change that math, for example if instead of a plus we change it to a minus we create the illusion on the player swallowing the balls.
You also have a bug on the function drawNextTarget() you did not pick the right coordinate:
ctx.arc(points[gAccess][0], points[gAccess][0],
VS
ctx.arc(points[gAccess][0], points[gAccess][1],
All looks good now:
const canvas = document.getElementById("gameArea");
const ctx = canvas.getContext("2d");
let x = 100;
let y = 100;
let radius = 50;
let speed = 10;
let upPressed = false;
let downPressed = false;
let leftPressed = false;
let rightPressed = false;
let gameOver = false;
let points = [ [300, 500], [400, 700], [100, 600], [469, 586], [578, 234], [587, 489] ];
var gAccess = 0;
var multiplier = 1;
let counter = 0;
function drawGame() {
requestAnimationFrame(drawGame);
clearScreen();
inputs();
boundryCheck();
drawGreenBlob();
drawNextTarget();
checkCollision();
}
function checkCollision() {
let b = points[gAccess][0] - x;
let a = points[gAccess][1] - y;
var c = Math.sqrt(a * a + b * b);
if (c < radius * multiplier + radius / 3) {
gAccess = (gAccess + 1) % points.length;
multiplier += 0.25;
counter++;
console.log(counter);
}
if (counter >= 25) {
gameover = true;
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
drawgameOver();
}
}
function drawNextTarget() {
if (gameOver === true) return;
ctx.beginPath();
ctx.arc(points[gAccess][0], points[gAccess][1], radius / 3, 0, Math.PI * 2);
ctx.fill();
}
function drawgameOver() {
var ctx = canvas.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
grd.addColorStop(0, "black");
grd.addColorStop(1, "gray");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, canvas.width, canvas.height);
var ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.font = "36px Arial";
ctx.fillText("Game Over!", 50, 50);
}
function boundryCheck() {
//up
if (y < radius) {
y = radius;
}
//down
if (y > canvas.height - radius) {
y = canvas.height - radius;
}
//left
if (x < radius) {
x = radius;
}
//right
if (x > canvas.width - radius) {
x = canvas.width - radius;
}
}
function inputs() {
if (upPressed) {
y = y - speed;
}
if (downPressed) {
y = y + speed;
}
if (leftPressed) {
x = x - speed;
}
if (rightPressed) {
x = x + speed;
}
}
function drawGreenBlob() {
ctx.fillStyle = "green";
if (upPressed) {
ctx.fillStyle = "red";
}
if (downPressed) {
ctx.fillStyle = "blue";
}
if (leftPressed) {
ctx.fillStyle = "yellow";
}
if (rightPressed) {
ctx.fillStyle = "purple";
}
ctx.beginPath();
ctx.arc(x, y, radius * multiplier, 0, Math.PI * 2);
ctx.fill();
}
function clearScreen() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
document.body.addEventListener("keydown", keyDown);
document.body.addEventListener("keyup", keyUp);
function keyDown(event) {
//up
if (event.keyCode == 38) {
upPressed = true;
}
//down
if (event.keyCode == 40) {
downPressed = true;
}
//left
if (event.keyCode == 37) {
leftPressed = true;
}
//right
if (event.keyCode == 39) {
rightPressed = true;
}
}
function keyUp(event) {
//up
if (event.keyCode == 38) {
upPressed = false;
}
//down
if (event.keyCode == 40) {
downPressed = false;
}
//left
if (event.keyCode == 37) {
leftPressed = false;
}
//right
if (event.keyCode == 39) {
rightPressed = false;
}
}
drawGame();
<canvas id="gameArea" width=800 height=800></canvas>

One variable is breaking my simple program, why?

I'm following a tutorial and trying to modify some code. As the code currently stands, everything is in working order to have a ball bounce around a square and off a paddle at the bottom and all I want to do is make the ball bigger when it bounces off the paddle. The balls starts at size 15 and I can increment it by 1-4 but at 5 and beyond, there is a bug that causes the ball to stay in location and grow to half the screen and then just stay there. I think as it grows it clips back into the hitbox for the paddle and then activates another growth and repeat. However, I am totally unsure. Can anyone shed some light? I will put a capitalized comment on the variable responsible halfway down the code. Thank you very much for any assistance!
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var x = canvas.width / 2; //starting coordinates
var y = canvas.height - 30;
var dx = 2; //rate of movement for ball
var dy = -2;
var ballRadius = 15;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#ff0000";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
drawPaddle();
x += dx;
y += dy;
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) { //these ifs cause the ball to bounce off walls
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
if (x > paddleX && x < paddleX + paddleWidth) { //detects paddlebox detection
dy = -dy;
ballRadius += 7; //TROUBLESOME VARIABLE! Work with 1-4 but breaks beyond that.
} else {
alert("GAME OVER");
document.location.reload();
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, 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;
}
}
setInterval(draw, 10);
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
<canvas id="myCanvas" width="480" height="320"></canvas>
The issue was that your draw function excecutes every 10ms. So when your ball hits the paddle it actually triggers the ball to grow multiple number of times. My solution was to how a timeout/delay when you increase the size of the ball so that it has time to move away before the next time the draw function fires. Heres the code.
NOTE : Open up the snippet in full screen to view the game better
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var x = canvas.width / 2; //starting coordinates
var y = canvas.height - 30;
var dx = 2; //rate of movement for ball
var dy = -2;
var ballRadius = 15;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#ff0000";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
drawPaddle();
x += dx;
y += dy;
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) { //these ifs cause the ball to bounce off walls
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
if (x > paddleX && x < paddleX + paddleWidth) { //detects paddlebox detection
dy = -dy;
setTimeout(function(){ ballRadius += 7; }, 100);
} else {
alert("GAME OVER");
document.location.reload();
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, 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;
}
}
setInterval(draw, 10);
* {
padding: 0;
margin: 0;
}
canvas {
background: #eee;
display: block;
margin: 0 auto;
}
<canvas id="myCanvas" width="480" height="320"></canvas>

Creating a pong game in Netbeans

I really hope that you might be able to able me. I am a total novice and so I am simply trying to learn. I am trying to create a pong game.
My problem is now that there is no collision between the paddles and balls.
Here is my code. It is messy I must admit.
</head>
<body>
<canvas id="canvas" width="500" height="500" style="border:1px solid #000000;"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var gradientMag = 375;
var gradient = ctx.createLinearGradient(0,0,0, gradientMag);
var ball_x = canvas.width/2;
var ball_y = canvas.height-30;
var dx = -2;
var dy = -2;
var ballRadius = 5;
var p_Height = 100;
var p_Width = 10;
var player1x = (canvas.width-p_Width);
var player1y = canvas.height-p_Height;
var player2y = 0;
var player2x = 0;
var player2Right = false;
var player2Left = false;
var player1Right = false;
var player1Left = false;
var startScreen = true;
var gameRunning = false;
var player1wins = false;
var player2wins = false;
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if(e.keyCode == 40) {
player1Right = true;
} if(e.keyCode == 38) {
player1Left = true;
} if(e.keyCode == 83) {
player2Right = true;
} else if(e.keyCode == 87) {
player2Left = true;
} }
function keyUpHandler(e) {
if(e.keyCode == 40) {
player1Right = false;
} if(e.keyCode == 38) {
player1Left = false;
} if(e.keyCode == 83) {
player2Right = false;
} if(e.keyCode == 87) {
player2Left = false;
}
else if (e.keyCode == 13){
gameRunning = true;
startScreen = false;
player1wins = false;
player2wins = false;
}
}
/*
function loadGame(){
if (startScreen){
var gradient = ctx.createLinearGradient(0,0,0,gradientMag);
gradient.addColorStop(0,blue );
gradient.addColorStop(1,red);
ctx.fillStyle = gradient;
ctx.fillRect(0,0, 500, 500);
ctx.font = "40px Verdana";
ctx.fillstyle = "blue";
ctx.fillText("Press Enter to begin", 150, 110);
}
}
*/
function ball() {
ctx.beginPath();
ctx.arc(ball_x, ball_y, ballRadius, 0, Math.PI*2);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
}
function paddle() {
ctx.beginPath();
ctx.rect(player1x, player1y, p_Width, p_Height);
ctx.fillStyle = "green";
ctx.fill();
ctx.closePath();
}
function player2() {
ctx.beginPath();
ctx.rect(player2x, player2y, p_Width, p_Height);
ctx.fillStyle = "blue";
ctx.fill();
ctx.closePath();
}
function draw() {
if (startScreen){
/*var gradient = ctx.createLinearGradient(0,0,0,gradientMag);
gradient.addColorStop(0,blue );
gradient.addColorStop(1,red);
ctx.fillStyle = gradient;
ctx.fillRect(0,0, 500, 500);
*/
ctx.font = "20px Verdana";
ctx.fillstyle = "blue";
ctx.fillText("Press Enter to begin", 100, 90);
}
if (gameRunning){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ball();
paddle();
player2();
//bounce of the walls
if(ball_y + dy > canvas.width-ballRadius || ball_y+dy < ballRadius){
dy = -dy;
}
//if the ball hits the top
if(ball_x + dx < ballRadius) {
//if the ball hits the paddle of player 2
if(ball_x + dx < player2x + p_Height && ball_y > player2y && ball_y < player2y + p_Width){
console.log("hit the paddle");
dx = -dx;
}
//if the ball hits the top - do this first
else if(ball_x + dx < canvas.height)
{
//alert("Player 1 Wins!");
//document.location.reload();
player1wins = true;
gameRunning = false;
}
}
//if the ball hits the bottom
if(ball_x + dx > canvas.height-ballRadius) {
//the ball hits the paddle
if(ball_x + dx > player1x && ball_y > player1y && ball_y < player1y + p_Width){
dx = -dx;
}
//the ball hits the base
else if(ball_x + dx > canvas.height)
{
//alert("Player 2 Wins!");
//document.location.reload();
player2wins = true;
gameRunning = false;
}
}
if(player1Right && player1y < canvas.width-p_Width) {
player1y += 5;
}else if(player1Left && player1y > 0) {
player1y -= 5;
}
if(player2Right && player2y < canvas.width-p_Width) {
player2y += 5;
}else if(player2Left && player2y > 0) {
player2y -= 5;
}
ball_y += dy;
ball_x += dx;
}
else if (player1wins) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
//background();
ctx.font = "20px Verdana";
ctx.fillstyle = "blue";
ctx.fillText("Well done player 1, you win!", 100, 90);
ctx.fillText("Hit F5 to play again!", 100, 110);
} else if (player2wins) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
//background();
ctx.font = "20px Verdana";
ctx.fillstyle = "blue";
ctx.fillText("Well done player 2, you win!", 100, 90);
ctx.fillText("Hit F5 to play again!", 100, 110);
}
}
setInterval(draw, 10);
//loadGame();
</script>
</body>
</html>
Your choice of y to signify width hurts a bit, however, it seems to me you're only checking collision once the ball has passed the player paddle? (ball_x + dx > player1x)
Shouldn't it be the other way around? ball_x + dx < player1x

How to set a delay in each penalty shot in HTML5 JS Canvas football penalty game

I am trying to make a simple football penalty game using HTML5/JS Canvas. The aim is to make a game where you control the goal keeper and you have three attempts to save the ball.
I have most of the functionality done, I have a score system and collision detection.
Currently I have a delay on the first attempt. I am however finding difficulty in adding a delay before the ball is shot into the goal in the second and third attempt.
I am using the method requestAnimationFrame() to paint my shapes on my canvas. If there is still attempts available, the ball is positioned to its original location but then there is no delay and fires the ball immediately.
Any advice ? Thanks!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Football</title>
<style>
* { padding: 0; margin: 0; }
canvas { background: #a5bd7b; display: block; margin: 0 auto; }
</style>
</head>
<body>
<canvas id="myCanvas" width="300" height="250"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
//Sets the original position of the ball
var x = canvas.width/2;
var y = 50;
// Defines values that will be added to the position of x and y values
// List of possible values for the x position
var x_options = [3.5, 3, 2.5, 2, 1.5, 1, 0.5, 0, -0.5, -1, -1.5, -2, -2.5, -3, -3.5];
// Gets a random value from the x_options array
var dx = x_options[Math.floor(Math.random() * x_options.length)];
var dy = 5;
var ballRadius = 10;
// Defines the height and width of the goal
var goal_height = 40;
var goal_width = 200
// Defines the height, width and position of goalie
var goalieHeight = 20;
var goalieWidth = 40;
var goalieX = (canvas.width-goalieWidth)/2;
var goalieY = (canvas.height - goal_height) - 30;
// Set to false by default
var rightPressed = false;
var leftPressed = false;
var goalkeeper_blocked = 0;
var goalkeeper_missed = 0;
var attempts_left = 3;
var attempt1 = true;
var attempt2 = false;
var attempt3 = false;
var footBall = {
shapes : {
ball: function (){
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2, false);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
},
goal : function (){
ctx.beginPath();
ctx.rect((canvas.width - goal_width) / 2 , canvas.height - goal_height, goal_width, goal_height);
ctx.strokeStyle = "#000000";
ctx.stroke();
ctx.closePath();
},
goalie : function(){
ctx.beginPath();
ctx.rect(goalieX, goalieY, goalieWidth, goalieHeight);
ctx.fillStyle = "#666666";
ctx.fill();
ctx.closePath();
},
score : function(){
ctx.font = "16px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("Score: "+goalkeeper_blocked, 8, 20);
},
missed : function(){
ctx.font = "16px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("Missed: "+goalkeeper_missed, 8, 40);
},
attempts : function(){
ctx.font = "16px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("Attempts left: "+attempts_left, canvas.width-110, 20);
}
},
controls : {
keyDownHandler : function (e){
if(e.keyCode == 39) {
rightPressed = true;
}
else if(e.keyCode == 37) {
leftPressed = true;
}
},
keyUpHandler : function(e){
if(e.keyCode == 39) {
rightPressed = false;
}
else if(e.keyCode == 37) {
leftPressed = false;
}
}
},
calculateScore : function(){
if(goalkeeper_missed > goalkeeper_blocked){
alert("GAME OVER! YOU HAVE LOST!");
document.location.reload();
} else {
alert("GAME OVER! YOU HAVE WON!");
document.location.reload();
}
},
animateBall : function (){
// Sets a delay of 3 second before it shoots
setTimeout(function(){
x += dx;
y += dy;
}, 3000);
},
resetShapePositions : function(){
//Sets the original position of the ball
x = canvas.width/2;
y = 50;
// Sets a new shooting path
dx = x_options[Math.floor(Math.random() * x_options.length)];
dy = 5;
// Resets the goalie to the middle
goalieX = (canvas.width-goalieWidth)/2;
},
draw : function(){
// This ensures that the ball doesn't leave a trail
// Clears the canvas of this shape each frame
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draws shapes on the canvas
footBall.shapes.ball();
footBall.shapes.goal();
footBall.shapes.goalie();
footBall.shapes.score();
footBall.shapes.missed();
footBall.shapes.attempts();
// adds values to the balls x and y position every frame
footBall.animateBall();
// Ball hits the goal
if(y + dy > canvas.height - goal_height) {
attempts_left--;
goalkeeper_missed++;
if (!attempts_left){
footBall.calculateScore();
}
else {
footBall.resetShapePositions();
}
} // Ball saved by goalie
else if (x > goalieX && x < goalieX + goalieWidth && y + dy > goalieY - ballRadius){
attempts_left--;
goalkeeper_blocked++;
if (!attempts_left){
footBall.calculateScore();
}
else {
footBall.resetShapePositions();
}
}
// makes paddle move left and right and only within the canvas
if(rightPressed && goalieX < canvas.width-goalieWidth) {
goalieX += 7;
}
else if(leftPressed && goalieX > 0) {
goalieX -= 7;
}
requestAnimationFrame(footBall.draw);
}
}
footBall.draw();
// Defines what functions are fired when keydown or keyup event triggers
document.addEventListener("keydown", footBall.controls.keyDownHandler, false);
document.addEventListener("keyup", footBall.controls.keyUpHandler, false);
</script>
</body>
</html>
Add some properties to football that control if/when a shot is occuring:
// is a shot in progress?
isShooting:false,
// the time when next shot will start
nextShotTime:0,
// delay between shots
delayUntilNextShot:3000,
Then in the animation loop, use these properties to appropriately delay the next shot:
If isShooting, process the shot,
If not isShooting, see if the required delay has elapsed between shots. If yes, set isShooting=true,
When the goalie blocks or misses the shot, set isShooting=false and set nextShotTime=currentTime+delayUntilNextShot,
Example code and a Demo:
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
//Sets the original position of the ball
var x = canvas.width/2;
var y = 50;
// Defines values that will be added to the position of x and y values
// List of possible values for the x position
var x_options = [3.5, 3, 2.5, 2, 1.5, 1, 0.5, 0, -0.5, -1, -1.5, -2, -2.5, -3, -3.5];
// Gets a random value from the x_options array
var dx = x_options[Math.floor(Math.random() * x_options.length)];
var dy = 5;
var ballRadius = 10;
// Defines the height and width of the goal
var goal_height = 40;
var goal_width = 200
// Defines the height, width and position of goalie
var goalieHeight = 20;
var goalieWidth = 40;
var goalieX = (canvas.width-goalieWidth)/2;
var goalieY = (canvas.height - goal_height) - 30;
// Set to false by default
var rightPressed = false;
var leftPressed = false;
var goalkeeper_blocked = 0;
var goalkeeper_missed = 0;
var attempts_left = 3;
var attempt1 = true;
var attempt2 = false;
var attempt3 = false;
var footBall = {
// is a shot in progress
isShooting:false,
// time when next shot will run
nextShotTime:0,
// delay until next shot will run
delayUntilNextShot:3000,
shapes : {
ball: function (){
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2, false);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
},
goal : function (){
ctx.beginPath();
ctx.rect((canvas.width - goal_width) / 2 , canvas.height - goal_height, goal_width, goal_height);
ctx.strokeStyle = "#000000";
ctx.stroke();
ctx.closePath();
},
goalie : function(){
ctx.beginPath();
ctx.rect(goalieX, goalieY, goalieWidth, goalieHeight);
ctx.fillStyle = "#666666";
ctx.fill();
ctx.closePath();
},
score : function(){
ctx.font = "16px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("Score: "+goalkeeper_blocked, 8, 20);
},
missed : function(){
ctx.font = "16px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("Missed: "+goalkeeper_missed, 8, 40);
},
attempts : function(){
ctx.font = "16px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("Attempts left: "+attempts_left, canvas.width-110, 20);
}
},
controls : {
keyDownHandler : function (e){
if(e.keyCode == 39) {
rightPressed = true;
}
else if(e.keyCode == 37) {
leftPressed = true;
}
},
keyUpHandler : function(e){
if(e.keyCode == 39) {
rightPressed = false;
}
else if(e.keyCode == 37) {
leftPressed = false;
}
}
},
calculateScore : function(){
if(goalkeeper_missed > goalkeeper_blocked){
alert("GAME OVER! YOU HAVE LOST!");
document.location.reload();
} else {
alert("GAME OVER! YOU HAVE WON!");
document.location.reload();
}
},
resetShapePositions : function(){
//Sets the original position of the ball
x = canvas.width/2;
y = 50;
// Sets a new shooting path
dx = x_options[Math.floor(Math.random() * x_options.length)];
dy = 5;
// Resets the goalie to the middle
goalieX = (canvas.width-goalieWidth)/2;
},
drawField: function(){
// This ensures that the ball doesn't leave a trail
// Clears the canvas of this shape each frame
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draws shapes on the canvas
footBall.shapes.ball();
footBall.shapes.goal();
footBall.shapes.goalie();
footBall.shapes.score();
footBall.shapes.missed();
footBall.shapes.attempts();
},
draw : function(currentTime){
// makes paddle move left and right and only within the canvas
if(rightPressed && goalieX < canvas.width-goalieWidth) {
goalieX += 7;
}
else if(leftPressed && goalieX > 0) {
goalieX -= 7;
}
// draw the scene
footBall.drawField();
// delay until next shot time is due
if(!footBall.isShooting){
// time has elapsed, let's shoot again
if(currentTime>footBall.nextShotTime){
footBall.isShooting=true;
}else{
// time has not elapsed, just request another loop
requestAnimationFrame(footBall.draw);
return;
}
}
// adds values to the balls x and y position every frame
x += dx;
y += dy;
// Ball hits the goal
if(y + dy > canvas.height - goal_height) {
// end the shot
footBall.isShooting=false;
// delay the next shot
footBall.nextShotTime=currentTime+footBall.delayUntilNextShot;
attempts_left--;
goalkeeper_missed++;
if (!attempts_left){
footBall.calculateScore();
}
else {
footBall.resetShapePositions();
}
} // Ball saved by goalie
else if (x > goalieX && x < goalieX + goalieWidth && y + dy > goalieY - ballRadius){
// end the shot
footBall.isShooting=false;
// delay the next shot
footBall.nextShotTime=currentTime+footBall.delayUntilNextShot;
attempts_left--;
goalkeeper_blocked++;
if (!attempts_left){
footBall.calculateScore();
}
else {
footBall.resetShapePositions();
}
}
requestAnimationFrame(footBall.draw);
}
}
footBall.drawField();
footBall.nextShotTime=footBall.delayUntilNextShot;
requestAnimationFrame(footBall.draw);
// Defines what functions are fired when keydown or keyup event triggers
document.addEventListener("keydown", footBall.controls.keyDownHandler, false);
document.addEventListener("keyup", footBall.controls.keyUpHandler, false);
* { padding: 0; margin: 0; }
canvas { background: #a5bd7b; display: block; margin: 0 auto; }
<canvas id="myCanvas" width="300" height="250"></canvas>

How do you move a drawing in javascript up down right and left

I was wondering how to move the red ball right and left (I already did, but its not working) and also how to move it up and down.
<canvas id="canvas" width="480" height="320"></canvas>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var ball;
var obstacle;
var x = canvas.width / 2;
var y = canvas.height / 2;
var dx = 2;
var dy = -2;
var redballRadius = 10;
var ballRadius = 20;
var rightpressed = false;
var leftpressed = false;
var ballX = (canvas.width - redballDiameter) / 2;
var redballDiameter = redballRadius * 2;
function startGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ball = new drawBall(30, 30, 'red', 20, 10);
obstacle = new drawObstacle(40, 30, 'blue', 15, 10);
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if (y + dy > canvas.height - ballRadius || y + dy < ballRadius) {
dy = -dy;
}
if(rightpressed && ballX < canvas.width-redballDiameter) {
ballX += 7;
}
else if(leftpressed && ballX > 0) {
ballX -= 7;
}
}
//keyboard controls
document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, 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 drawBall() {
ctx.beginPath();
ctx.arc(30, 30, 15, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
ctx.closePath();
}
function drawObstacle() {
x += dx;
y += dy;
ctx.beginPath();
ctx.arc(x, y, 20, 10, 1 * Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
ctx.closePath();
}
setInterval(startGame, 10);
I am basically wondering how to move it up down right and left with the keys. Thanks
I took a look at your code. In your life cycle, you are calling drawBall, now sure what you are trying to do with the new there. anyways, I updated the function to use the ballX your key handling logic updates.
function drawBall() {
ctx.beginPath();
ctx.arc(ballX, 30, 15, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
ctx.closePath();
}
here is the working code pen. http://codepen.io/poda/pen/aNPPEp
move a ball to up, down, right and left.
it would be better to use object than use global variable of x_pos and y_pos of ball
function drawBall() {
this.ball_x = 30;
this.ball_y = 30;
this.draw = function() {
ctx.beginPath();
ctx.arc(this.ball_x, this.ball_y, 15, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
ctx.closePath();
},
this.move = function() {
if(rightpressed && this.ball_x < canvas.width-redballDiameter) {
this.ball_x += 5;
}
else if(leftpressed && this.ball_x > redballDiameter) {
this.ball_x -= 5;
}
else if(uppressed && this.ball_y > redballDiameter) {
this.ball_y -= 5;
}
else if(downpressed && this.ball_y < canvas.height - redballDiameter) {
this.ball_y += 5;
}
},
this.collision = function() {
//stuff
}
}
Here's a fiddle

Categories

Resources