I'm coding a Breakout game with Javascript. I took the MDN tutorial and another tutorial and I'm trying to modify the original with a OOP approach. Until now, everything works fine except for the collision detection with the paddle. Which is not happening. Why is that? Here's my code. Can somebody help? Thanks!
var canvas = document.getElementById('game');
var theLoop;
var paddleSpeed = 4;
//OBJECTS
//Game
function Game() {
this.width = canvas.width;
this.height = canvas.height;
this.ctx = canvas.getContext('2d');
this.ctx.fillStyle = "white";
this.p = new Paddle(0, 130);
this.p.x = (this.width - this.p.width) / 2;
this.keys = new Keylistener();
this.ball = new Ball();
this.ball.x = this.width / 2;
this.ball.y = 125;
this.ball.vy = Math.floor(Math.random() * 12 - 6);
this.ball.vx = 7 - Math.abs(this.ball.vy);
}
Game.prototype.draw = function() {
this.ctx.clearRect(0, 0, this.width, this.height);
this.p.draw(this.ctx);
this.ball.draw(this.ctx);
};
Game.prototype.update = function() {
if (this.paused) return;
this.ball.update();
//Right Paddle's Directions
if (this.keys.isPressed(37)) { // LEFT
this.p.x = Math.max(0, this.p.x - paddleSpeed);
} else if (this.keys.isPressed(39)) { // RIGHT
this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
}
if (this.ball.x < this.ball.ballRadius || this.ball.x > this.width - this.ball.ballRadius) { //LEFT & RIGHT
this.ball.vx = -this.ball.vx;
}
if (this.ball.y < this.ball.ballRadius) { //TOP
this.ball.vy = -this.ball.vy;
} else if (this.ball.y > this.height - this.ball.ballRadius) {
if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
this.ball.vy = -this.ball.vy;
console.log('hit');
} else {
// console.log(this.ball.x);
}
}
};
/////Paddle
function Paddle(x, y) {
this.x = x;
this.y = y;
this.width = 30;
this.height = 5;
this.score = 0;
}
Paddle.prototype.draw = function(p) {
p.fillRect(this.x, this.y, this.width, this.height);
};
///KEY LISTENER
function Keylistener() {
this.pressedKeys = [];
this.keydown = function(e) {
this.pressedKeys[e.keyCode] = true;
};
this.keyup = function(e) {
this.pressedKeys[e.keyCode] = false;
};
document.addEventListener("keydown", this.keydown.bind(this));
document.addEventListener("keyup", this.keyup.bind(this));
}
Keylistener.prototype.isPressed = function(key) {
return this.pressedKeys[key] ? true : false;
};
Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
document.addEventListener("keypress", function(e) {
if (e.keyCode == keyCode) callback(e);
});
};
///BALL
function Ball() {
this.x = 0;
this.y = 0;
this.vx = 0;
this.vy = 0;
this.ballRadius = 5;
}
Ball.prototype.update = function() {
this.x += this.vx;
this.y += this.vy;
};
Ball.prototype.draw = function(p) {
p.beginPath();
p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
p.fill();
p.closePath();
};
//Initialize the game
var game = new Game();
//the Main Engine
function mainLoop() {
theLoop = setInterval(function() {
game.update();
game.draw();
}, 33.3333);
}
//calling the Main Engine
mainLoop();
#game {
width: 800px;
height: 400px;
background-color: #353535;
}
<canvas id="game"></canvas>
var canvas = document.getElementById('game');
var theLoop;
var paddleSpeed = 4;
//OBJECTS
//Game
function Game() {
this.width = canvas.width;
this.height = canvas.height;
this.ctx = canvas.getContext('2d');
this.ctx.fillStyle = "white";
this.p = new Paddle(0, 130);
this.p.x = (this.width - this.p.width) / 2;
this.keys = new Keylistener();
this.ball = new Ball();
this.ball.x = this.width / 2;
this.ball.y = 125;
this.ball.vy = Math.floor(Math.random() * 12 - 6);
this.ball.vx = 7 - Math.abs(this.ball.vy);
}
Game.prototype.draw = function() {
this.ctx.clearRect(0, 0, this.width, this.height);
this.p.draw(this.ctx);
this.ball.draw(this.ctx);
};
Game.prototype.update = function() {
if (this.paused) return;
this.ball.update();
//Right Paddle's Directions
if (this.keys.isPressed(37)) { // LEFT
this.p.x = Math.max(0, this.p.x - paddleSpeed);
} else if (this.keys.isPressed(39)) { // RIGHT
this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
}
if (this.ball.x < this.ball.ballRadius || this.ball.x > this.width - this.ball.ballRadius) { //LEFT & RIGHT
this.ball.vx = -this.ball.vx;
}
if (this.ball.y < this.ball.ballRadius) { //TOP
this.ball.vy = -this.ball.vy;
} else if (this.ball.y > this.p.y - this.ball.ballRadius &&
this.ball.y < this.p.y + this.p.height + this.ball.ballRadius) {
if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
this.ball.vy = -this.ball.vy;
console.log('hit');
} else {
// console.log(this.ball.x);
}
}
};
/////Paddle
function Paddle(x, y) {
this.x = x;
this.y = y;
this.width = 30;
this.height = 5;
this.score = 0;
}
Paddle.prototype.draw = function(p) {
p.fillRect(this.x, this.y, this.width, this.height);
};
///KEY LISTENER
function Keylistener() {
this.pressedKeys = [];
this.keydown = function(e) {
this.pressedKeys[e.keyCode] = true;
};
this.keyup = function(e) {
this.pressedKeys[e.keyCode] = false;
};
document.addEventListener("keydown", this.keydown.bind(this));
document.addEventListener("keyup", this.keyup.bind(this));
}
Keylistener.prototype.isPressed = function(key) {
return this.pressedKeys[key] ? true : false;
};
Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
document.addEventListener("keypress", function(e) {
if (e.keyCode == keyCode) callback(e);
});
};
///BALL
function Ball() {
this.x = 0;
this.y = 0;
this.vx = 0;
this.vy = 0;
this.ballRadius = 5;
}
Ball.prototype.update = function() {
this.x += this.vx;
this.y += this.vy;
};
Ball.prototype.draw = function(p) {
p.beginPath();
p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
p.fill();
p.closePath();
};
//Initialize the game
var game = new Game();
//the Main Engine
function mainLoop() {
theLoop = setInterval(function() {
game.update();
game.draw();
}, 33.3333);
}
//calling the Main Engine
mainLoop();
#game {
width: 800px;
height: 400px;
background-color: #353535;
}
<canvas id="game"></canvas>
Your problem is this section right here.
else if (this.ball.y > this.height - this.ball.ballRadius) {
if (this.ball.x > this.p.x && this.ball.x < this.p.x + this.p.width) {
You aren't trying to register a hit with the paddle unless the ball is at the bottom of the screen. You need to be checking if the ball intersects with the paddle before you hit the bottom of the screen.
var paddleLeft = this.p.x;
var paddleRight = paddleLeft + this.p.width;
var paddleTop = this.p.y;
var ballLeft = this.ball.x;
var ballRight = ballLeft + this.ball.ballRadius;
var ballBottom = this.ball.y + this.ball.ballRadius;
var xCollision = (ballLeft <= paddleRight && ballRight >= paddleLeft);
var yCollision = (ballBottom >= paddleTop);
if (this.ball.y < this.ball.ballRadius) { //TOP
this.ball.vy = -this.ball.vy;
} else if (xCollision && yCollision) {
this.ball.vy = -this.ball.vy;
console.log('hit');
}
Here it is running in your game.
var canvas = document.getElementById('game');
var theLoop;
var paddleSpeed = 4;
//OBJECTS
//Game
function Game() {
this.width = canvas.width;
this.height = canvas.height;
this.ctx = canvas.getContext('2d');
this.ctx.fillStyle = "white";
this.p = new Paddle(0, 220);
this.p.x = (this.width - this.p.width) / 2;
this.keys = new Keylistener();
this.ball = new Ball();
this.ball.x = this.width / 2;
this.ball.y = 125;
this.ball.vy = Math.floor(Math.random() * 12 - 6);
this.ball.vx = 7 - Math.abs(this.ball.vy);
}
Game.prototype.draw = function() {
this.ctx.clearRect(0, 0, this.width, this.height);
this.p.draw(this.ctx);
this.ball.draw(this.ctx);
};
Game.prototype.update = function() {
if (this.paused) return;
this.ball.update();
//Right Paddle's Directions
if (this.keys.isPressed(37)) { // LEFT
this.p.x = Math.max(0, this.p.x - paddleSpeed);
} else if (this.keys.isPressed(39)) { // RIGHT
this.p.x = Math.min(this.p.x + paddleSpeed, this.width - this.p.width);
}
var leftBallCollision = this.ball.x < this.ball.ballRadius;
var rightBallCollision = this.ball.x > this.width - this.ball.ballRadius;
if (leftBallCollision || rightBallCollision) { //LEFT & RIGHT
this.ball.vx = -this.ball.vx;
}
var paddleLeft = this.p.x;
var paddleRight = paddleLeft + this.p.width;
var paddleTop = this.p.y;
var ballLeft = this.ball.x;
var ballRight = ballLeft + this.ball.ballRadius;
var ballBottom = this.ball.y + this.ball.ballRadius;
var xCollision = (ballLeft <= paddleRight && ballRight >= paddleLeft);
var yCollision = (ballBottom >= paddleTop);
if (this.ball.y < this.ball.ballRadius) { //TOP
this.ball.vy = -this.ball.vy;
} else if (xCollision && yCollision) {
this.ball.vy = -this.ball.vy;
console.log('hit');
}
};
/////Paddle
function Paddle(x, y) {
this.x = x;
this.y = y;
this.width = 30;
this.height = 5;
this.score = 0;
}
Paddle.prototype.draw = function(p) {
p.fillRect(this.x, this.y, this.width, this.height);
};
///KEY LISTENER
function Keylistener() {
this.pressedKeys = [];
this.keydown = function(e) {
this.pressedKeys[e.keyCode] = true;
};
this.keyup = function(e) {
this.pressedKeys[e.keyCode] = false;
};
document.addEventListener("keydown", this.keydown.bind(this));
document.addEventListener("keyup", this.keyup.bind(this));
}
Keylistener.prototype.isPressed = function(key) {
return this.pressedKeys[key] ? true : false;
};
Keylistener.prototype.addKeyPressListener = function(keyCode, callback) {
document.addEventListener("keypress", function(e) {
if (e.keyCode == keyCode) callback(e);
});
};
///BALL
function Ball() {
this.x = 0;
this.y = 0;
this.vx = 0;
this.vy = 0;
this.ballRadius = 5;
}
Ball.prototype.update = function() {
this.x += this.vx;
this.y += this.vy;
};
Ball.prototype.draw = function(p) {
p.beginPath();
p.arc(this.x, this.y, this.ballRadius, 0, Math.PI * 2, false);
p.fill();
p.closePath();
};
//Initialize the game
var game = new Game();
//the Main Engine
function mainLoop() {
theLoop = setInterval(function() {
game.update();
game.draw();
}, 33.3333);
}
//calling the Main Engine
mainLoop();
#game {
background-color: #353535;
}
<canvas id="game" width="320" height="240"></canvas>
Related
I need to resize my spritesheet so it fits the correct dimensions of my game object. I have been looking around the internet and I found that this -ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);- is what i think i need to use. however, i do not know how or where to implement this in my code. i know how it works but i dont know where to put it or where in my code to put it. i use almost completely javascript
var myGamePiece;
var myObstacle;
var object1;
var objects;
var box;
function startGame() {
//creation of objects
wall = new component(30, 100, "black", 300, 200);
myGamePiece = new component(30, 30, "red", 240, 135);
myObstacle = new component(100, 100, "green", 200, 100);
object1 = new component(30, 30, "enemy.png", 340, 125, "image");
box = new component(30, 30, "box.png", 177, 145, "image");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
window.addEventListener('keydown', function (e) {
myGameArea.key = e.keyCode;
})
window.addEventListener('keyup', function (e) {
myGameArea.key = false;
})
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
collide : function() {
object1.x += 1;
object1.y += 1;
},
//what to do when pushing box
boxleft : function() {
box.x -= 1;
x -= 1;
}
}
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.sx = x;
this.sy = y;
this.swidth = width;
this.sheight = height;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width,
this.height
);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
//code for gray square
this.crashWith = function(object1) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = object1.x;
var otherright = object1.x + (object1.width);
var othertop = object1.y;
var otherbottom = object1.y + (object1.height);
var crash = true;
if ((mybottom < othertop) ||
(mytop > otherbottom) ||
(myright < otherleft) ||
(myleft > otherright)) {
crash = false;
}
return crash;
}
//code to push box
this.pushboxWith = function(box) {
const myleft = this.x;
const myright = this.x + (this.width);
const mytop = this.y;
const mybottom = this.y + (this.height);
const boxleft = box.x-2;
const boxright = box.x + (box.width)+2;
const boxtop = box.y+2;
const boxbottom = box.y + (box.height)-2;
var pushboxleft = true;
var pushboxright = true;
//test if pushing box
if ((myleft < boxright) && (mybottom >= boxtop) && (mytop <= boxbottom) && (myleft > boxleft)) {
pushboxleft = true;
} else {
pushboxleft = false;
}
return pushboxleft;
}
}
function updateGameArea() {
if (myGamePiece.crashWith(object1)) {
myGameArea.collide();
} else if (myGamePiece.pushboxWith(box)) {
myGameArea.boxleft();
} else {
myGameArea.clear();
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
//keyboard controls. moves everything but the player
if (myGameArea.key && myGameArea.key == 37) {
myObstacle.x += 2;
object1.x += 2;
box.x += 2;
wall.x += 2;
}
if (myGameArea.key && myGameArea.key == 39) {
myObstacle.x += -2;
object1.x += -2;
box.x += -2;
wall.x += -2;
}
if (myGameArea.key && myGameArea.key == 38) {
myObstacle.y += 2;
object1.y += 2;
box.y += 2;
wall.y += 2
}
if (myGameArea.key && myGameArea.key == 40) {
myObstacle.y += -2;
object1.y += -2;
box.y += -2;
wall.y += -2
}
//other square movement. disabled to isolate code.
/*
if (object1.x < myGamePiece.x) {
object1.x += 1;
}
if (object1.x > myGamePiece.x) {
object1.x += -1;
}
if (object1.y < myGamePiece.y) {
object1.y += 1;
}
if (object1.y > myGamePiece.y) {
object1.y += -1;
}
*/
/* object order: the object that is higher on the list
will be on top of objects lower on the list
*/
myObstacle.update();
myGamePiece.newPos();
myGamePiece.update();
wall.update();
object1.update();
box.update();
//end of list
}
}
i do use some html
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
border:1px solid #d3d3d3;
background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">
<script src="main.js"></script>
</body>
</html>
if you need to test my code you can find it here- https://eeeegame-2.octopuscat.repl.co/
I'm working on a javascript game and trying to add some code to the button that toggles the visibility of the games and acts as a pause button so that it will stop running and not keep shoving scoring alerts down your throat if you have it hidden, and all of the code that I've written has failed miserably. Here it is, hope someone can help me fix it.
<div id = 'games'>
<!-- I only put this canvas in a div because there will be more games here soon. -->
<canvas id='my' width = '640' height = '480'></canvas>
</div>
<script>
var canvas = document.getElementById("my");
var ctx = canvas.getContext("2d");
function paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedModifier = 0;
this.hasCollidedWith = function(ball) {
var paddleLeftWall = this.x;
var paddleRightWall = this.x + this.width;
var paddleTopWall = this.y;
var paddleBottomWall = this.y + this.height;
if (ball.x > paddleLeftWall &&
ball.x < paddleRightWall &&
ball.y > paddleTopWall &&
ball.y < paddleBottomWall) {
return true;
}
return false;
};
this.move = function(keyCode) {
var nextY = this.y;
if (keyCode == 40) {
nextY += 5;
this.speedModifer = 1.5;
} else if (keyCode == 38) {
nextY += -5;
this.speedModifier = 1.5;
} else {
this.speedModifier = 0;
}
nextY = nextY < 0 ? 0 : nextY;
nextY = nextY + this.height > 480 ? 480 - this.height : nextY;
this.y = nextY;
};
}
var player = new paddle(5, 200, 25, 100);
var ai = new paddle(610, 200, 25, 100);
var ball = {
x: 320,
y: 240,
radius: 7,
xSpeed: 2,
ySpeed: 0,
playerscore: 0,
aiscore: 0,
reverseX: function() {
this.xSpeed *= -1;
},
reverseY: function() {
this.ySpeed *= -1;
},
reset: function() {
alert('The score is now ' + this.playerscore + ' to ' + this.aiscore);
this.x = 20;
this.y = 24;
this.xSpeed = 2;
this.ySpeed = 0;
},
isBouncing: function() {
return ball.ySpeed != 0;
},
modifyXSpeedBy: function(modification) {
modification = this.xSpeed < 0 ? modification * -1 : modification;
var nextValue = this.xSpeed + modification;
nextValue = Math.abs(nextValue) > 9 ? 9 : nextValue;
this.xSpeed = nextValue;
},
modifyYSpeedBy: function(modification) {
modification = this.ySpeed < 0 ? modification * -1 : modification;
this.ySpeed += modification;
}
};
function tick() {
updateGame();
draw()
window.setTimeout("tick()", 1000 / 60);
}
function updateGame() {
ball.x += ball.xSpeed;
ball.y += ball.ySpeed;
if (ball.x < 0) {
ball.reset();
ball.aiscore = ball.aiscore + 1;
}
if (ball.x > 640) {
ball.reset();
ball.playerscore = ball.playerscore + 1
}
if (ball.y <= 0 || ball.y >= 480) {
ball.reverseY();
}
var collidedWithPlayer = player.hasCollidedWith(ball);
var collidedWithAi = ai.hasCollidedWith(ball);
if (collidedWithPlayer || collidedWithAi) {
ball.reverseX();
ball.modifyXSpeedBy(0.25);
var speedUpValue = collidedWithPlayer ? player.speedModifier : ai.speedModifier;
ball.modifyYSpeedBy(speedUpValue);
}
for (var keyCode in heldDown) {
player.move(keyCode);
}
var aiMiddle = ai.y + (ai.height / 2);
if (aiMiddle < ball.y) {
ai.move(40);
}
if (aiMiddle > ball.y) {
ai.move(38);
}
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 640, 480);
renderPaddle(player);
renderPaddle(ai);
renderBall(ball);
}
function renderPaddle(paddle) {
ctx.fillStyle = "blue";
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
function renderBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "pink";
ctx.fill();
}
var heldDown = {};
window.addEventListener("keydown", function(keyInfo) {
heldDown[event.keyCode] = true;
}, false);
window.addEventListener("keyup", function(keyInfo) {
delete heldDown[event.keyCode];
}, false);
function playPong(){
if (canvas.style.display == 'none'){canvas.style.display = 'block';}
else {canvas.style.display == 'none';}
if (canvas.style.display === 'block')
{
tick()};
}
</script>
<script>
function hide() {
var games = document.getElementById('games')
if (games.style.display === 'block')
games.style.display = 'none';
else{games.style.display = 'block';}
}
function show(){
var canvas = document.getElementById('my')
canvas.style.display = 'block';
}
</script>
<button onclick = 'hide()'> Hide or show the games</button>
<button onclick = 'playPong();show()'> Play pong </button>
I would try not using the visibility of the canvas as the deciding factor in the if statement and instead maybe trying something like this-
<div id='games'>
<canvas id='my' width='640' height='480'></canvas>
</div>
<script>
var paused = false
function PausePlay() {
if (paused === false) {
paused = true;
} else {
paused = false;
}
}
var canvas = document.getElementById("my");
var ctx = canvas.getContext("2d");
function paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedModifier = 0;
this.hasCollidedWith = function(ball) {
var paddleLeftWall = this.x;
var paddleRightWall = this.x + this.width;
var paddleTopWall = this.y;
var paddleBottomWall = this.y + this.height;
if (ball.x > paddleLeftWall &&
ball.x < paddleRightWall &&
ball.y > paddleTopWall &&
ball.y < paddleBottomWall) {
return true;
}
return false;
};
this.move = function(keyCode) {
var nextY = this.y;
if (keyCode == 40) {
nextY += 5;
this.speedModifer = 1.5;
} else if (keyCode == 38) {
nextY += -5;
this.speedModifier = 1.5;
} else {
this.speedModifier = 0;
}
nextY = nextY < 0 ? 0 : nextY;
nextY = nextY + this.height > 480 ? 480 - this.height : nextY;
this.y = nextY;
};
}
var player = new paddle(5, 200, 25, 100);
var ai = new paddle(610, 200, 25, 100);
var ball = {
x: 320,
y: 240,
radius: 7,
xSpeed: 2,
ySpeed: 0,
playerscore: 0,
aiscore: 0,
reverseX: function() {
this.xSpeed *= -1;
},
reverseY: function() {
this.ySpeed *= -1;
},
reset: function() {
alert('The score is now ' + this.playerscore + ' to ' + this.aiscore);
this.x = 20;
this.y = 24;
this.xSpeed = 2;
this.ySpeed = 0;
},
isBouncing: function() {
return ball.ySpeed != 0;
},
modifyXSpeedBy: function(modification) {
modification = this.xSpeed < 0 ? modification * -1 : modification;
var nextValue = this.xSpeed + modification;
nextValue = Math.abs(nextValue) > 9 ? 9 : nextValue;
this.xSpeed = nextValue;
},
modifyYSpeedBy: function(modification) {
modification = this.ySpeed < 0 ? modification * -1 : modification;
this.ySpeed += modification;
}
};
function tick() {
updateGame();
draw()
window.setTimeout("tick()", 1000 / 60);
}
function updateGame() {
if (paused === false) {
ball.x += ball.xSpeed;
ball.y += ball.ySpeed;
if (ball.x < 0) {
ball.reset();
ball.aiscore = ball.aiscore + 1;
}
if (ball.x > 640) {
ball.reset();
ball.playerscore = ball.playerscore + 1
}
if (ball.y <= 0 || ball.y >= 480) {
ball.reverseY();
}
var collidedWithPlayer = player.hasCollidedWith(ball);
var collidedWithAi = ai.hasCollidedWith(ball);
if (collidedWithPlayer || collidedWithAi) {
ball.reverseX();
ball.modifyXSpeedBy(0.25);
var speedUpValue = collidedWithPlayer ? player.speedModifier : ai.speedModifier;
ball.modifyYSpeedBy(speedUpValue);
}
for (var keyCode in heldDown) {
player.move(keyCode);
}
var aiMiddle = ai.y + (ai.height / 2);
if (aiMiddle < ball.y) {
ai.move(40);
}
if (aiMiddle > ball.y) {
ai.move(38);
}
}
}
function draw() {
if (paused === false) {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 640, 480);
renderPaddle(player);
renderPaddle(ai);
renderBall(ball);
}
}
function renderPaddle(paddle) {
ctx.fillStyle = "blue";
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
function renderBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "pink";
ctx.fill();
}
var heldDown = {};
window.addEventListener("keydown", function(keyInfo) {
heldDown[event.keyCode] = true;
}, false);
window.addEventListener("keyup", function(keyInfo) {
delete heldDown[event.keyCode];
}, false);
function playPong() {
tick()
}
</script>
<script>
function getOff() {
alert("you've been on for five minutes now. Time to take a break.");
setTimeout(function() {
alert("it's been 10 minutes now. Get back to work.");
close();
var body = document.getElementById('hide5')
body.style.display = 'none'
}, 300000);
}
setInterval(getOff, 300000)
}
</script>
<script>
function hide() {
var games = document.getElementById('games')
if (games.style.display === 'block')
games.style.display = 'none';
else {
games.style.display = 'block';
}
}
function show() {
var canvas = document.getElementById('my')
canvas.style.display = 'block';
}
</script>
<button onclick='hide()'> Hide or show the games</button>
<button onclick='PausePlay()'> Pause games </button>
<button onclick='playPong()'> Play pong </button>
i have a simple pong game where i can shot the ball and check for colisions at the moment. I had the colisions with X and Y working, but since i added angles to the ball trajectory the colisions at X coordinate sometimes fail, dunno why. So this is what i have at the moment, the colisions checking is handled by the ballMovementHandler function.
var canvas;
var ctx;
var player;
var ball;
var gameStarted;
var flagY;
var flagX;
var angle;
function init() {
canvas = document.getElementById('myCanvas')
if (canvas.getContext) {
ctx = canvas.getContext('2d')
setCanvasSize(ctx)
player = new Player()
ball = new Ball()
attachKeyboardListeners()
reset();
animate();
}
}
function reset() {
flagX = -1;
flagY = -1;
angle = 90;
gameStarted = false
player = new Player();
ball = new Ball();
}
function animate () {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawIce()
player.drawPlayer();
ball.drawBall();
playerMovementeHandler()
if(gameStarted) {
ballMovementHandler();
}
window.requestAnimationFrame(animate);
}
function playerMovementeHandler() {
if(player.left === true) {
if(player.x > 0) {
player.movePlayer(-SPEED);
if(!gameStarted) {
ball.moveBallWithPlayer(-SPEED);
}
}
}
if(player.right === true) {
if(player.x + player.width < ctx.canvas.width) {
player.movePlayer(SPEED);
if(!gameStarted) {
ball.moveBallWithPlayer(SPEED);
}
}
}
}
function ballMovementHandler() {
if(ball.y - ball.radius <= 0) {
flagY = 1;
}
if(ball.y + ball.radius === player.y) {
if(ball.x + ball.radius >= player.x && ball.x < player.x + player.width) {
angle = playerAngleHandler()
flagY = -1;
}
else {
reset();
}
}
if(ball.x - ball.radius <= 0) {
flagX = 1;
}
if(ball.x + ball.radius >= ctx.canvas.width) {
flagX = -1;
}
radians = angle * Math.PI/ 180;
ball.moveBallY(Math.sin(radians) * ball.speed * flagY);
ball.moveBallX(Math.cos(radians) * ball.speed * flagX);
}
function playerAngleHandler() {
var angle = 90;
if(ball.x + ball.radius <= player.x + 25) {
angle = 35;
} else if(ball.x + ball.radius >= player.x + player.width - 25) {
angle = 135;
} else if(ball.x + ball.radius >= player.x + player.width - 50) {
angle = 120
} else if(ball.x + ball.radius <= player.x + 50 ) {
angle = 50;
} else if(ball.x + ball.radius <= player.x + 75) {
angle = 75;
} else if( ball.x + ball.radius >= player.x + player.width - 75 ) {
angle = 100;
}
return angle;
}
function drawIce() {
ctx.fillStyle = 'rgb(134,214,216)'
ctx.fillRect(0,ctx.canvas.height - Y_OFFSET + player.height + 10, ctx.canvas.width, Y_OFFSET)
}
function setCanvasSize() {
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
}
function keyboardEvent(keyCode, keyStatus) {
switch(keyCode) {
case 37:
player.left = keyStatus;
break;
case 39:
player.right = keyStatus;
break;
case 32:
gameStarted = true;
break;
}
}
function attachKeyboardListeners() {
document.addEventListener('keydown', function(e) {
keyboardEvent(e.keyCode, true)
})
document.addEventListener('keyup', function(e) {
keyboardEvent(e.keyCode, false)
})
}
init();
ball.js
// defines player configuration behaviour
const BALL_POSITION_Y = 100;
const RADIUS = 12;
const BALL_SPEED = 10;
function Ball(x = ctx.canvas.width/2, y = ctx.canvas.height - Y_OFFSET - RADIUS, radius = RADIUS, color = 'rgb(100,149,237)', speed = BALL_SPEED) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.speed = speed;
this.drawBall = function() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
ctx.fill();
}
// for inital game started
this.moveBallWithPlayer = function(deltaX) {
this.x += deltaX;
}
this.moveBallY = function(flag) {
this.y = this.y + flag;
}
this.moveBallX = function(flag) {
this.x = this.x + flag;
}
}
player.js
// defines player configuration behaviour
const PLAYER_WIDTH = 200;
const Y_OFFSET = 100;
const PLAYER_HEIGHT = 30;
const SPEED = 6;
function Player(x = ctx.canvas.width/2 - PLAYER_WIDTH/2, y = ctx.canvas.height - Y_OFFSET, width = PLAYER_WIDTH, height = PLAYER_HEIGHT, color = 'rgba(0,0,0)') {
this.left = false;
this.right = false;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.movePlayer = function(deltaX) {
this.x += deltaX;
}
this.drawPlayer = function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
I am trying to make a javascript game, got some codes online and I am trying to refine it to what I want, so I want the interval to be faster after score gets to 1000. I have tried all my possible best to dig into this, please kindly help me to refine my code. The start function takes an interval of 20 miliseconds in the gamearea function. I do a count of scores, then when the scores get to 1000, i want to increase the interval by settiing it in the updateGame function
function startGame() {
myGameArea = new gamearea();
myGamePiece = new component(30, 30, "red", 10, 75);
myscore = new component("15px", "Consolas", "black", 220, 25, "text");
myGameArea.start();
}
function gamearea() {
this.canvas = document.createElement("canvas");
this.canvas.width = 320;
this.canvas.height = 180;
document.getElementById("canvascontainer").appendChild(this.canvas);
this.context = this.canvas.getContext("2d");
this.pause = false;
this.frameNo = 0;
this.start = function() {
this.interval = setInterval(updateGameArea, 20);
}
this.stop = function() {
clearInterval(this.interval);
this.pause = true;
}
this.clear = function(){
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "text") {
this.text = color;
}
this.score = 0; this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (this.type == "text") {
ctx.font = this.width + " " + this.height;
ctx.fillStyle = color;
ctx.fillText(this.text, this.x, this.y);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
crash = false;
}
return crash;
}
}
function updateGameArea() {
var x, y, min, max, height, gap;
for (i = 0; i < myObstacles.length; i += 1) {
if (myGamePiece.crashWith(myObstacles[i])) {
myGameArea.stop();
document.getElementById("myfilter").style.display = "block";
document.getElementById("myrestartbutton").style.display = "block";
return;
}
}
if (myGameArea.pause == false) {
myGameArea.clear();
myGameArea.frameNo += 1;
myscore.score +=1;
if (myGameArea.frameNo == 1 || everyinterval(150)) {
x = myGameArea.canvas.width;
y = myGameArea.canvas.height - 100;
min = 20;
max = 100;
height = Math.floor(Math.random()*(max-min+1)+min);
min = 50;
max = 100;
gap = Math.floor(Math.random()*(max-min+1)+min);
myObstacles.push(new component(10, height, "green", x, 0));
myObstacles.push(new component(10, x - height - gap, "green", x, height + gap));
}
for (i = 0; i < myObstacles.length; i += 1) {
myObstacles[i].x += -1;
myObstacles[i].update();
}
myscore.text="SCORE: " + myscore.score;
if (myscore.score == 1000){
this.start = function() {
this.interval = setInterval(updateGameArea, 10);
}
}
myscore.update();
myGamePiece.x += myGamePiece.speedX;
myGamePiece.y += myGamePiece.speedY;
myGamePiece.update();
}
}
startGame();
You need to explicitly stop the old interval running and start a new one.
if (myscore.score == 1000){
this.stop(); // Stop the old interval
// Start a new interval with the new timing
this.interval = setInterval(updateGameArea, 10);
}
I need to create function sprite() with canvas in javascript
I have 2 codes
this to create a sprite :
var width = 40,
height = 28,
frames = 2,
currentFrame = 0,
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
image = new Image()
image.src = 'http://s28.postimg.org/k90gybbtl/bird_Sprite.png';
var draw = function(){
ctx.clearRect(0, 0, width, height);
ctx.drawImage(image, 0, height * currentFrame, width, height, 0, 0, width, height);
if (currentFrame == frames) {
currentFrame = 0;
} else {
currentFrame++;
}
}
setInterval(draw, 120);
I have another code for simple game :
function startGame() {
myGamePiece = new component(30, 30, "red", 10, 120);
myGamePiece.gravity = 0.05;
myScore = new component("30px", "Consolas", "black", 280, 40, "text");
myUpBtn = new component(canvasWidth, canvasHeight, "rgba(0, 0, 0, 0)", 0, 0);
myGameArea.start();
}
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
this.update = function() {
ctx = myGameArea.context;
if (this.type == "text") {
ctx.font = this.width + " " + this.height;
ctx.fillStyle = color;
ctx.fillText(this.text, this.x, this.y);
} else {
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
}
this.clicked = function() {
var mytop = this.y;
var clicked = true;
if (mytop > myGameArea.y) {
clicked = false;
}
return clicked;
}
this.newPos = function() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY + this.gravitySpeed;
this.hitBottom();
}
this.hitBottom = function() {
var rockbottom = myGameArea.canvas.height - this.height;
if (this.y > rockbottom) {
this.y = rockbottom;
this.gravitySpeed = 0;
}
}
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
crash = false;
}
return crash;
}
} // https://www.w3schools.com/graphics/game_images.asp
etc...
now the problem is ...
I can't make the 2 codes together
can anyone help me?
thank you :)
The following code adds your sprite to the game code from W3 Schools:
var myGamePiece;
var myObstacles = [];
var myScore;
function startGame() {
myGamePiece = new component(40, 28, "red", 10, 120, "sprite");
myGamePiece.gravity = 0.05;
myScore = new component("30px", "Consolas", "black", 280, 40, "text");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(width, height, color, x, y, type) {
this.type = type;
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
if (type === "sprite") {
this.currentFrame = 0;
this.frames = 2;
this.tickCount = 0;
this.ticksPerFrame = 4;
this.image = new Image();
this.image.src = 'http://s28.postimg.org/k90gybbtl/bird_Sprite.png';
}
this.update = function() {
ctx = myGameArea.context;
if (this.type == "text") {
ctx.font = this.width + " " + this.height;
ctx.fillStyle = color;
ctx.fillText(this.text, this.x, this.y);
} else if (this.type == "sprite") {
if (this.tickCount > this.ticksPerFrame) {
ctx.drawImage(this.image, 0, this.height * this.currentFrame, this.width, this.height, this.x, this.y, this.width, this.height);
this.tickCount = 0;
if (this.currentFrame == this.frames) {
this.currentFrame = 0;
} else {
this.currentFrame++;
}
} else {
ctx.drawImage(this.image, 0, this.height * this.currentFrame, this.width, this.height, this.x, this.y, this.width, this.height);
this.tickCount++;
}
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY + this.gravitySpeed;
this.hitBottom();
}
this.hitBottom = function() {
var rockbottom = myGameArea.canvas.height - this.height;
if (this.y > rockbottom) {
this.y = rockbottom;
this.gravitySpeed = 0;
}
}
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
crash = false;
}
return crash;
}
}
function updateGameArea() {
var x, height, gap, minHeight, maxHeight, minGap, maxGap;
for (i = 0; i < myObstacles.length; i += 1) {
if (myGamePiece.crashWith(myObstacles[i])) {
return;
}
}
myGameArea.clear();
myGameArea.frameNo += 1;
if (myGameArea.frameNo == 1 || everyinterval(150)) {
x = myGameArea.canvas.width;
minHeight = 20;
maxHeight = 200;
height = Math.floor(Math.random()*(maxHeight-minHeight+1)+minHeight);
minGap = 50;
maxGap = 200;
gap = Math.floor(Math.random()*(maxGap-minGap+1)+minGap);
myObstacles.push(new component(10, height, "green", x, 0));
myObstacles.push(new component(10, x - height - gap, "green", x, height + gap));
}
for (i = 0; i < myObstacles.length; i += 1) {
myObstacles[i].x += -1;
myObstacles[i].update();
}
myScore.text="SCORE: " + myGameArea.frameNo;
myScore.update();
myGamePiece.newPos();
myGamePiece.update();
}
function everyinterval(n) {
if ((myGameArea.frameNo / n) % 1 == 0) {return true;}
return false;
}
function accelerate(n) {
myGamePiece.gravity = n;
}
canvas {
border:1px solid #d3d3d3;
background-color: #f1f1f1;
}
<body onload="startGame()">
<br>
<button onmousedown="accelerate(-0.2)" onmouseup="accelerate(0.05)">ACCELERATE</button>
<p>Use the ACCELERATE button to stay in the air</p>
<p>How long can you stay alive?</p>
</body>
In summary:
Within the component function we initialise variables to handle the sprite animation if the type parameter is set to sprite
Within the update function we only draw the next frame of the sprite animation every 4th time update is called. This ensures that the sprite animation doesn't play to quickly
We then increment or reset the currentFrame count the same as you did before in your original code
If we're not ready to display the next frame in the sprite animation, we just display the existing frame again.
To take it further you might want to consider refactoring my solution so that the sprite is a separate "class" which inherits it's core functionality from component.