How can i add a Start button to this function? - javascript

I'm trying to figure out how I can add a start button to play a javascript game by replacing the audio in the background. I came across this game, the way it works is as soon as you load the page the music plays in the background and the games already started. When I removed the audio link, the game paused after the players 3 lives are up, if I leave the audio in, then when the 3 lives are up you can see your points and a pop up message, can someone please help me understand this
here is a link to the game so you can look at the code and understand what I'm trying to say : https://jsfiddle.net/74nbrdak/embedded/result/
<div>
<canvas id="canvas" width="1000" height="500"></canvas>
</div>
<audio id="background-music" preload="auto" autoplay loop>
<source
src="https://dl.dropbox.com/s/5r3iu7kjsl0mx81/Wildfire%20Cut%20Loopable.wav" type="audio/wav">
function ShowGamesFinished() {
var message = gamesfinished[Math.floor(Math.random() * gamesfinished.length)];
document.getElementById("background-music").pause();

When I removed the audio link, the game paused after the players 3 lives are up, if I leave the audio in, then when the 3 lives are up you can see your points and a pop up message, can someone please help me understand this
So, In the second scenario when the audio element is on the page, the game works just as the creator intended.
In the first scenario when the audio element isn't on the page, the game works fine until the function that handles the game over is called. What causes the problem in that function is this line document.getElementById("background-music").pause();. Since the audio element doesn't exist, it throws an error and the game over screen isn't drawn. Hope that this helps

If you are using pure javascript Without any external libraries, you can initialize your canvas and on a click of the button you can start animating the canvas and your game starts.
let me know If you don't get my answer.

At first glance, removing the audio tag should not have any effect at all on the javascript. The audio plays upon openeing the page because the audio tag has the autoplay attribute.
All of the javascript code seems to be just within a script tag, so it will also autorun once the page gets opened. What you could try is wrapping the entire code from the fiddle into a function and just bind it to your button.
Something like:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
h1 {
font-family: Architects Daughter;
text-align: center;
font-size: 48pt;
margin-top: 50px;
margin-bottom: 0px;
}
h2 {
font-family: Architects Daughter;
text-align: center;
font-size: 28pt;
margin-top: 0px;
margin-bottom: 50px;
}
span {
display: block;
font-family: Arial;
text-align: center;
margin-bottom: 2px;
}
div {
display: flex;
justify-content: space-around;
}
canvas {
border: 2px solid #CC3333;
}
</style>
</head>
<body>
<div>
<canvas id="canvas" width="640" height="360"></canvas>
</div>
<button id="start_game">Start</button>
<script>
var run_game = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var updateTime = 20; // Milliseconds
var keys = [false, false, false];
var score = 0;
var kills = 0;
// Player Size = 50x18
var playerHealth = 3;
var playerX = WIDTH / 2;
var playerY = HEIGHT - 20;
var playerSpeed = 6;
var lazerSpeed = 16;
var lazerReloadDistance = playerY - 120;
var lazerLoaded = true;
var lazers = [];
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var maxEnemies = 12;
var enemySpeed = 4;
var enemies = [];
function Clear() {
ctx.fillStyle = "#404040";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
}
function DrawHealth(health) {
ctx.fillStyle = "#E52B50";
ctx.shadowColor = "#E52B50";
ctx.shadowBlur = 15;
ctx.font = "18px Arial";
ctx.textAlign = "start";
var hearts = "";
if (health == 3) {
hearts = "<3 <3 <3";
}
else if (health == 2) {
hearts = "<3 <3 X";
}
else if (health == 1) {
hearts = "<3 X X";
}
else {
hearts = "X X X";
}
ctx.fillText(hearts, 10, 25);
}
function DrawScore() {
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.shadowBlur = 15;
ctx.font = "18px Arial";
ctx.textAlign = "end";
ctx.fillText(score, WIDTH - 10, 25);
}
function DrawPlayer(x, y) {
ctx.fillStyle = "#1E90FF";
ctx.shadowColor = "#1E90FF";
ctx.shadowBlur = 15;
ctx.font = "24px Arial";
ctx.textAlign = "center";
ctx.fillText("</^\\>", x, y);
}
function Lazer() {
this.x = playerX;
this.y = playerY - 38;
this.draw = function() {
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.shadowBlur = 15;
this.y -= lazerSpeed;
ctx.fillRect(this.x, this.y, 2, 18);
}
}
function DrawLazers() {
// Check if the last lazer fired is far enough away to fire another
if (lazers.length != 0) {
if (lazers[lazers.length - 1].y <= lazerReloadDistance) {
lazerLoaded = true;
}
}
else {
lazerLoaded = true;
}
for (var i = 0; i < lazers.length; i++) {
var currentLazer = lazers[i];
// Still on screen
if (currentLazer.y > -20) {
currentLazer.draw();
}
else {
lazers.splice(i, 1);
}
}
}
function Enemy(x) {
this.x = x;
this.y = 0;
this.health = Math.ceil(Math.random() * 4);
this.speed = enemySpeed / this.health;
var letterIndex = Math.floor(Math.random() * letters.length);
this.letter = letters.substr(letterIndex, 1);
this.size = 24 + (this.health * 4); // Font size based on health
ctx.font = this.size+"px Arial";
this.width = ctx.measureText(this.letter).width;
this.height = this.size * 0.75; // Approximate height;
this.draw = function() {
ctx.fillStyle = "#FF0040";
ctx.shadowColor = "#FF0040";
ctx.shadowBlur = 15;
ctx.font = this.size+"px Arial";
ctx.textAlign = "center";
this.y += this.speed;
ctx.fillText(this.letter, this.x, this.y);
}
}
function DrawEnemies() {
// Spawn new enemies
if (Math.random() <= 0.05 && enemies.length < maxEnemies) {
var randX = 40 + Math.floor(Math.random() * (WIDTH - 80));
enemies.push(new Enemy(randX));
}
for (var i = 0; i < enemies.length; i++) {
var currentEnemy = enemies[i];
if (currentEnemy.health <= 0) {
enemies.splice(i, 1);
score += 25;
kills++;
continue;
}
// Put enemies that passed the player back at the top
if (currentEnemy.y > HEIGHT + currentEnemy.height) {
currentEnemy.y = 0;
continue;
}
currentEnemy.draw();
}
}
var gameOverMessages = [
"You're in a better place",
"You're Cooked!",
"You gave it your all",
"At least you tried",
"You're Ruined!",
"You're Finished!"
];
function DrawGameOver() {
var message = gameOverMessages[Math.floor(Math.random() * gameOverMessages.length)];
// after deleting the audio element, this doesnt work anymore.
// document.getElementById("background-music").pause();
ctx.fillStyle = "#505050";
ctx.shadowColor = "#505050";
ctx.shadowBlur = 15;
ctx.fillRect(50, (HEIGHT / 2) - 100, WIDTH - 100, 200)
ctx.fillStyle = "#FFFFFF";
ctx.shadowColor = "#FFFFFF";
ctx.shadowBlur = 15;
ctx.textAlign = "center";
ctx.font = "36pt Arial";
ctx.fillText(message, WIDTH / 2, HEIGHT / 2 - 40);
ctx.textAlign = "end";
ctx.font = "18pt Arial";
ctx.fillText("Final Score - ", WIDTH / 2, HEIGHT / 2 + 30);
ctx.textAlign = "start";
ctx.fillStyle = "#FFFF00";
ctx.shadowColor = "#FFFF00";
ctx.fillText(score, WIDTH / 2, HEIGHT / 2 + 30);
ctx.fillStyle = "#FFFFFF";
ctx.shadowColor = "#FFFFFF";
ctx.textAlign = "end";
ctx.font = "18pt Arial";
ctx.fillText("Total Kills - ", WIDTH / 2, HEIGHT / 2 + 60);
ctx.textAlign = "start";
ctx.fillStyle = "#FF0040";
ctx.shadowColor = "#FF0040";
ctx.fillText(kills, WIDTH / 2, HEIGHT / 2 + 60);
}
////////////////////
// Core Functions //
////////////////////
var collidedEnemyIndex = -1;
function CheckCollision() {
for (var i = 0; i < enemies.length; i++) {
var currentEnemy = enemies[i];
// Check if enemy hits player. The 2 is to account for the text width of the player
if (
currentEnemy.x <= playerX - 2 + 25 + (currentEnemy.width / 2) &&
currentEnemy.x >= playerX - 2 - 25 - (currentEnemy.width / 2) &&
currentEnemy.y >= playerY - 18 &&
currentEnemy.y <= playerY + currentEnemy.height &&
collidedEnemyIndex != enemies.indexOf(currentEnemy)
)
{
collidedEnemyIndex = enemies.indexOf(currentEnemy);
playerHealth--;
}
// Reset the index of the enemy colliding with the player
if (collidedEnemyIndex == enemies.indexOf(currentEnemy) && currentEnemy.y < HEIGHT / 2) {
collidedEnemyIndex = -1;
}
for (var j = 0; j < lazers.length; j++) {
var currentLazer = lazers[j];
if (
currentLazer.x <= currentEnemy.x + (currentEnemy.width / 2) &&
currentLazer.x >= currentEnemy.x - (currentEnemy.width / 2) &&
currentLazer.y <= currentEnemy.y
)
{
currentEnemy.health--;
score += 10;
lazers.splice(lazers.indexOf(currentLazer), 1);
}
}
}
}
function HandleInput() {
if (keys[0] == true && keys[1] == false && playerX <= WIDTH - 30) {
playerX += playerSpeed;
}
if (keys[1] == true && keys[0] == false && playerX >= 30) {
playerX -= playerSpeed;
}
if (keys[2]) {
if (lazerLoaded) {
lazers.push(new Lazer());
lazerLoaded = false;
}
}
}
function KeysDown(e) {
e.preventDefault();
// Right
if (e.keyCode == 39) {
keys[0] = true;
}
// Left
else if (e.keyCode == 37) {
keys[1] = true;
}
// Up/Fire
if (e.keyCode == 38) {
keys[2] = true;
}
}
function KeysUp(e) {
// Right
if (e.keyCode == 39) {
keys[0] = false;
}
// Left
else if (e.keyCode == 37) {
keys[1] = false;
}
// Up/Fire
if (e.keyCode == 38) {
keys[2] = false;
}
}
document.addEventListener("keydown", KeysDown, true);
document.addEventListener("keyup", KeysUp, true);
function Update() {
Clear();
HandleInput();
CheckCollision();
DrawEnemies();
DrawLazers();
DrawPlayer(playerX, playerY);
DrawHealth(playerHealth);
DrawScore();
if (playerHealth <= 0) {
clearInterval(gameLoop);
DrawGameOver();
}
}
var gameLoop = setInterval(Update, updateTime);
};
document.querySelector( '#start_game' ).addEventListener( 'click', run_game );
</script>
</body>
</html>

Related

How to add Start Game and Play Again to canvas game?

I created game using Javascript following YouTube video game tutorial. Game works just fine, but I would like to add ability to enter nickname at the beginning of the game. After entering nickname and hitting play button the game would begin and nickname would display on the middle upper side of the screen. Then after loosing the game, window with score and play-again button should pop up. After clicking play-again button another game starts.
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const collisionCanvas = document.getElementById('collisionCanvas');
const collisionCtx = collisionCanvas.getContext('2d');
collisionCanvas.width = window.innerWidth;
collisionCanvas.height = window.innerHeight;
//obsluga gry
let gameOver = false;
let score = 0;
ctx.font = '50px Impact';
let lives = 3;
let hit = false;
let clicked = false;
//setup spawnow
let timeToNextZombie = 0;
let zombieInterval = 400;
let lastTime = 0;
let zombies =[];
//myszka
let innerCursor = document.querySelector('.inner-cursor');
let outerCursor = document.querySelector('.outer-cursor');
document.addEventListener('mousemove', moveCursor)
function moveCursor(e){
let x = e.clientX;
let y = e.clientY;
innerCursor.style.left = `${x}px`;
innerCursor.style.top = `${y}px`;
outerCursor.style.left = `${x}px`;
outerCursor.style.top = `${y}px`;
}
class Zombie{
constructor(){
this.spriteWidth = 200; //szerkosc klatki zombie
this.spriteHeight = 312; //wyskosc klatki zombie
this.sizeModifier = Math.random()* 0.8 + 0.6; //mnożnik wielkości zombiaka
this.width = this.spriteWidth * this.sizeModifier;
this.height = this.spriteHeight * this.sizeModifier;
this.x = canvas.width;
this.y =Math.random() * (canvas.height -this.height); //spawn zombie od dolu do gory ekranu
this.directionX = Math.random() * 4 + 1; //predkosc zombiakow
if(Math.floor(Math.random() * 20) == 0) this.directionX = 10; //5% szans na szybkiego lopeza
this.markedForDeletion = false; //oznaczenie czy mozna usunac obiekt
this.image = new Image();
this.image.src = 'walkingdead.png';
this.frame = 0;
this.maxFrame = 8;
this.timeSinceFlap = 0;
this.flapInterval = Math.random()*50+50; //flipowanie kazdego inne
this.randomColors = [Math.floor(Math.random()*255), Math.floor(Math.random()*255), Math.floor(Math.random()*255)];
this.color = 'rgb(' + this.randomColors[0] + ',' + this.randomColors[1] + ',' + this.randomColors[2] + ')';
}
update(deltatime){
this.x -= this.directionX;
this.timeSinceFlap +=deltatime;
if (this.x < 0-this.width){
this.markedForDeletion = true;
} //zombiak jest poza zasiegiem
if (this.timeSinceFlap > this.flapInterval){
if (this.frame > this.maxFrame) this.frame = 0;
else this.frame++;
this.timeSinceFlap = 0;
}
if (this.x < 0 -this.width){
lives-=1;
if(lives == 0){
gameOver = true;
}
}
}
//rysowanie zombiaka
draw(){
collisionCtx.fillStyle = this.color;
collisionCtx.fillRect(this.x, this.y, this.width, this.height);
ctx.drawImage(this.image, this.frame * this.spriteWidth, 0, this.spriteWidth, this.spriteHeight, this.x, this.y, this.width, this.height);
}
}
function drawScore(){
//kordy scora
if(lives == 0){
ctx.font = '200px Impact';
ctx.fillText('☠️', 0, 170);
return;
}
ctx.fillStyle = 'white';
ctx.fillText('Score: ' + score, 55, 80);
if(lives == 3) ctx.fillText('❤ ❤ ❤', 55, 130);
if(lives == 2) ctx.fillText('❤ ❤', 55, 130);
if(lives == 1) ctx.fillText('❤', 55, 130);
}
function drawGameOver(){
drawScore();
ctx.font = "bold 100px serif";
ctx.textAlign = 'center';
ctx.fillStyle = 'red';
ctx.fillText("GAME OVER!", canvas.width/2, canvas.height/2)
ctx.fillText("Your score is " + score, canvas.width/2, 100 + canvas.height/2)
}
window.addEventListener('click', function(e){
const detectPixelColor = collisionCtx.getImageData(e.x, e.y, 1, 1);
const pc = detectPixelColor.data; //popieranie info o hitboxie zombie
zombies.forEach(object =>{
if(object.randomColors[0] === pc[0] && object.randomColors[1] === pc[1] && object.randomColors[2] === pc[2]){
object.markedForDeletion = true; //usunąć gościa z mapy
hit = true;
}
clicked = true;
})
});
//obsluga klatki
function animate(timestamp) {
if(clicked){
if(hit) score+=12
else score-=6;
clicked = false;
hit = false;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
collisionCtx.clearRect(0, 0, canvas.width, canvas.height);
let deltatime = timestamp - lastTime;
lastTime = timestamp;
timeToNextZombie += deltatime;
if (timeToNextZombie > zombieInterval){
zombies.push(new Zombie()); //tworzenie nowego zombiaka
timeToNextZombie = 0;
zombies.sort(function(a, b){
return a.width - b.width; //sort zeby mniejsze zombiaki byly za wiekszymi
})
};
drawScore();
//dla kazdego zombiaka przesuwamy zombiaka, object to pojedynczy (obiekt) zombiaka
[...zombies].forEach(object => object.update(deltatime));
[...zombies].forEach(object => object.draw());
zombies = zombies.filter(object => !object.markedForDeletion); //usuwanie zombiakow poza screenem
if(!gameOver) requestAnimationFrame(animate);
else{
drawScore();
drawGameOver();
}
}
animate(0);
*{
cursor: none;
}
canvas{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('board-bg.jpg');
}
#collisionCanvas{
opacity: 0;
}
.inner-cursor{
position: fixed;
width: 15px;
height: 15px;
transform: translate(-50%, -50%);
background-color: white !important;
mix-blend-mode: difference;
border-radius: 50%;
pointer-events: none;
}
.outer-cursor{
position: fixed;
width: 70px;
height: 70px;
transform: translate(-50%, -50%);
border: 5px solid white;
mix-blend-mode: difference;
border-radius: 50%;
pointer-events: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zadanie 12</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas2"></canvas>
<canvas id="collisionCanvas"></canvas>
<canvas id="canvas1"></canvas>
<div class="inner-cursor"></div>
<div class="outer-cursor"></div>
<script src="script.js"></script>
</body>
</html>
You have everything you need in that code...
let gameOver = false;
let zombies = [];
all we need is to change a bit your code to take advantage of those.
I'm not going to implement your "window with score and play-again button pop up" instead I'm going for a much simpler timeout to demonstrate how to restart your game.
The key point in your game that sets the "end" is the one below:
if (lives == 0) {
zombies = []
gameOver = true;
gameEnded = Date.now()
setTimeout(() => {
gameOver = false
lives = 3
}, 5000)
}
before you just had the gameOver now I'm doing a few more things, like that setTimeout that will restart the game in 5 seconds, restarting the game is just to set the gameOver back to false and give the user some lives.
Your function animate is where the drawing loop happens, I changed that a bit, now we no longer stop the loop but draw something else and we can add many conditions there:
function animate(timestamp) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (gameOver) {
drawGameOver();
} else if (abc < 20) {
drawABC();
} else if (def == "start_message") {
drawDEF();
} else {
...
}
requestAnimationFrame(animate)
}
Below is your simplified code with my additions
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = canvas.height = 700;
let gameEnded = Date.now()
let gameOver = false;
let score = 0;
ctx.font = '50px Impact';
let lives = 3;
let hit = false;
let clicked = false;
let timeToNextZombie = 0;
let zombieInterval = 400;
let lastTime = 0;
let zombies = [];
class Zombie {
constructor() {
this.spriteWidth = 200; //szerkosc klatki zombie
this.spriteHeight = 312; //wyskosc klatki zombie
this.sizeModifier = Math.random() * 0.8 + 0.6; //mnożnik wielkości zombiaka
this.width = this.spriteWidth * this.sizeModifier;
this.height = this.spriteHeight * this.sizeModifier;
this.x = canvas.width;
this.y = Math.random() * (canvas.height - this.height); //spawn zombie od dolu do gory ekranu
this.directionX = Math.random() * 4 + 1; //predkosc zombiakow
if (Math.floor(Math.random() * 20) == 0) this.directionX = 10; //5% szans na szybkiego lopeza
this.markedForDeletion = false; //oznaczenie czy mozna usunac obiekt
//this.image = new Image();
//this.image.src = 'walkingdead.png';
this.frame = 0;
this.maxFrame = 8;
this.timeSinceFlap = 0;
this.flapInterval = Math.random() * 50 + 50; //flipowanie kazdego inne
}
update(deltatime) {
this.x -= this.directionX;
this.timeSinceFlap += deltatime;
if (this.x < 0 - this.width) {
this.markedForDeletion = true;
} //zombiak jest poza zasiegiem
if (this.timeSinceFlap > this.flapInterval) {
if (this.frame > this.maxFrame) this.frame = 0;
else this.frame++;
this.timeSinceFlap = 0;
}
if (this.x < 0 - this.width) {
lives -= 1;
if (lives == 0) {
zombies = []
gameOver = true;
gameEnded = Date.now()
setTimeout(() => {
gameOver = false
lives = 3
}, 5000)
}
}
}
draw() {
ctx.beginPath()
ctx.arc(this.x, this.y, 15, 0, 2 * Math.PI);
ctx.stroke()
}
}
function drawGameOver() {
ctx.beginPath()
ctx.font = "bold 100px serif";
ctx.textAlign = 'center';
ctx.fillStyle = 'red';
ctx.fillText("GAME OVER!", canvas.width / 2, canvas.height / 2)
ctx.fillText("Your score is " + score, canvas.width / 2, 100 + canvas.height / 2)
ctx.beginPath()
ctx.font = "bold 30px serif";
ctx.fillText("Game will restart in 5 seconds... " + String(Date.now()- gameEnded), canvas.width / 2, 100)
}
function animate(timestamp) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (gameOver) {
drawGameOver();
} else {
let deltatime = timestamp - lastTime;
lastTime = timestamp;
timeToNextZombie += deltatime;
if (timeToNextZombie > zombieInterval) {
zombies.push(new Zombie()); //tworzenie nowego zombiaka
timeToNextZombie = 0;
zombies.sort(function(a, b) {
return a.width - b.width; //sort zeby mniejsze zombiaki byly za wiekszymi
})
};
[...zombies].forEach(object => object.update(deltatime));
[...zombies].forEach(object => object.draw());
zombies = zombies.filter(object => !object.markedForDeletion);
}
requestAnimationFrame(animate)
}
animate(0);
<canvas id="canvas1"></canvas>

How do i make an object in canvas move based on it's x and y coordinates with a keyboard inputs?

this is my first time asking a question on StackOverflow. I was wondering on to make an object move based on its x and y coordinates with keyboard inputs. I am making a grid based movement for my game. I apologize for any bad code or formatting. I am making a web game for a school project. Do comment if u need my html code. Here's my code below:
$(function(){
var health = 800;
var fuel = 100;
var tankX = 25;
var tankY = 530;
var c = document.getElementById("gameCanvas");
var ctx = c.getContext('2d');
ctx.beginPath();
ctx.fillStyle = "grey";
ctx.fillRect(0,600,1110,100);
ctx.stroke();
for (i = 100; i < 600; i += 100)
{
ctx.moveTo(0, i);
ctx.lineTo(c.width, i);
ctx.stroke();
}
for (i = 100; i < 1110; i += 100)
{
ctx.moveTo(i, 0);
ctx.lineTo(i,600);
ctx.stroke();
}
ctx.fillStyle ="black";
ctx.font = "20px Lucida Sans Typewriter ";
ctx.fillText("Health:",500,630);
ctx.fillText("Fuel:", 100,630);
ctx.fillStyle = "green";
ctx.fillRect(500,640,(health/800)*250,40);
function fuelGauge(){
ctx.fillStyle="yellow";
ctx.fillRect(100,640,(fuel/100)*250,40);
console.log(fuel);
}
function drawTank(){
ctx.fillStyle = "#283618"
ctx.fillRect(tankX,tankY,50,50);
ctx.moveTo(tankX,tankY);
}
drawTank();
fuelGauge();
});
I don't do a lot of jquery, but since nobody answered, here's an example. It uses the keydown event to listen for the arrow keys. I'm sure there's lots of room for improvement, but it should get you started.
var c = document.getElementById("gameCanvas");
var ctx = c.getContext('2d');
var tankX = 25;
var tankY = 530;
var health = 800;
var fuel = 100;
$('html').keydown(function(e){
eraseTank();
if (e.key == "ArrowUp") {
if (tankY > 15) tankY -= 102;
}
else if (e.key == "ArrowDown") {
if (tankY < 530) tankY += 102;
}
else if (e.key == "ArrowLeft") {
if (tankX > 25) tankX -= 100;
}
else if (e.key == "ArrowRight") {
if (tankX < 525) tankX += 100;
}
drawTank();
});
function fuelGauge(){
ctx.fillStyle="yellow";
ctx.fillRect(100,640,(fuel/100)*250,40);
console.log(fuel);
}
function drawTank(){
ctx.fillStyle = "#283618"
ctx.fillRect(tankX,tankY,50,50);
ctx.moveTo(tankX,tankY);
}
function eraseTank(){
ctx.fillStyle = "white"
ctx.fillRect(tankX,tankY,50,50);
ctx.moveTo(tankX,tankY);
}
function drawGame()
{
ctx.beginPath();
ctx.fillStyle = "grey";
ctx.fillRect(0,600,1110,100);
ctx.stroke();
for (i = 100; i < 600; i += 100)
{
ctx.moveTo(0, i);
ctx.lineTo(c.width, i);
ctx.stroke();
}
for (i = 100; i < 1110; i += 100)
{
ctx.moveTo(i, 0);
ctx.lineTo(i,600);
ctx.stroke();
}
ctx.fillStyle ="black";
ctx.font = "20px Lucida Sans Typewriter ";
ctx.fillText("Health:",500,630);
ctx.fillText("Fuel:", 100,630);
ctx.fillStyle = "green";
ctx.fillRect(500,640,(health/800)*250,40);
}
$(function(){
drawGame();
fuelGauge();
drawTank();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="gameCanvas" width="600" height="1100"></canvas>
When you run the snippet, make sure you click on the game board first.

Javascript Canvas Game - How to know when object crosses its own path?

I am new to Javascript. I am trying to make a canvas game similar to Snake, but without the fruits.
The game is over if the player crosses his own path. The following is my code. Do you know how can I determine when the red rectangle crosses its own path and use the game over function?
Thank you!
var player;
var touch = 0;
function startGame() {
myGameArea.start();
player = new component(30, 30, "red", 270, 270);
}
var myGameArea = {
canvas: document.createElement("canvas"),
start: function() {
this.canvas.width = 600;
this.canvas.height = 600;
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;
})
},
clear: function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(width, height, color, x, y) {
this.gamearea = myGameArea;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}
function updateGameArea() {
/*myGameArea.clear();*/
player.speedX = 0;
player.speedY = 0;
if (myGameArea.key == 37) {
player.speedX = -10;
}
if (myGameArea.key == 39) {
player.speedX = 10;
}
if (myGameArea.key == 38) {
player.speedY = -10;
}
if (myGameArea.key == 40) {
player.speedY = 10;
}
if (player.x <= 0 || player.x >= 570 || player.y <= 0 || player.y >= 570) { //When the player goes out of the canvas
gameOver();
}
player.newPos();
player.update();
}
function gameOver() {
var r = confirm("GAME OVER. Restart?");
if (r == true) {
window.location.reload();
} else {
window.open("https://www.google.ca");
}
}
canvas {
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
background-color: #000;
}
<body onload="startGame()">
</body>
Array as a Queue.
The way this game is traditionally done is using a special array type called a queue. Like a real queue you have items added at one end and removed at the other, or first in first out.
Javascript does not have a special array type for a queue but it has all the functions needed to implement a queue.
Push and shift
Array.push(item); // pushes an item onto the top of the array
Array.shift(); // removes an item from the start of the queue
So for the snake game imagine the head as the end of the queue. Every time it moves one forward you place another item on the queue. At the other end you remove an item if the length of the array is longer than the snake length;
var snake = [];
var snakeLength = 10;
function snakeMove(x,y){ // position to move head
checkForHit(x,y); // see below
snake.push({x:x,y:y}); // put another headpiece on the queue
if(snake.length > snakeLength){ // is the length longer than it should be
snake.shift(); // remove a tail item
}
}
To draw the snake you just iterate each part drawing it at the X,y position
To test if the snake has run its self over use the following function
function checkForHit(x,y){
for(var i = 0; i < snake.length; i++){
if(snake[i].x === x && snake[i].y === y){
// Snake has hit its self
}
}
}
When the snake eats something it traditionally grows in length. this is easily done by simply increasing the length variable. snakeLength += 1 makes the queue longer.
And a demo as i have not played the game in so long why not.
"use strict";
var score = 0;
var canvas = document.createElement("canvas");
var scoreE = document.createElement("div");
scoreE.style.color = "white";
scoreE.style.font = "16px arial";
scoreE.style.position = "absolute";
scoreE.style.top = "10px";
scoreE.style.left = "10px";
scoreE.style.width = "600px";
scoreE.style.textAlign = "center";
scoreE.textContent = "Click canvas area to get focus";
canvas.width = 600;
canvas.height = 200;
var ctx = this.canvas.getContext("2d");
document.body.appendChild(canvas);
document.body.appendChild(scoreE);
var lastKeyDown = 0;
window.addEventListener('keydown', function(e) {
lastKeyDown = e.keyCode;
e.preventDefault()
})
var snakePartSize = 8;
var playWidth = canvas.width /snakePartSize;
var playHeight = canvas.height /snakePartSize;
var snake = [];
var snakeLength = 10;
var snakePosX = 0;
var snakePosY = 0;
var snakeDirX = 0;
var snakeDirY = 0;
var snakeSpeed = 16; // number of frame between moves
var gameOver = true;
var instDrawn = false;
var food = [];
var foodFreq = 60;
var yum = 0;
var yumCol = ["red","orange","yellow"];
function startSnake(){
ctx.fillStyle = "black";
ctx.fillRect(0,0,canvas.width,canvas.height);
snakePosX = Math.floor(playWidth / 2);
snakePosY = Math.floor(playHeight / 2);
snakeDirX = 0;
snakeDirY = 0;
snakeLength = 10;
snake = [];
snakeSpeed = 16;
move(snakePosX,snakePosY); // set first pos
food = [];
score = 0;
}
function testHit(x,y){
if(x < 0 || y < 0 || y >= playHeight || x >= playWidth ){
return true;
}
for(var i = 0; i < snake.length; i ++){
if(snake[i].x === x && snake[i].y === y){
return true;
}
}
}
function testFood(x,y){
for(var i = 0; i < food.length; i ++){
if(food[i].x === x && food[i].y === y){
food.splice(i,1);
i --;
yum = 4;
score += 100;
snakeLength += 1;
if(snakeLength % 4 === 0){
snakeSpeed -= snakeSpeed > 1 ? 1:0;
}
}
}
}
function addFood(){
var x = Math.floor(Math.random() * playWidth );
var y = Math.floor(Math.random() * playHeight );
if(!testHit(x,y)){
food.push({x:x,y:y});
drawFood();
}
}
function move(x,y){
if(testHit(x,y)){
gameOver = true;
return;
}
testFood(x,y);
snake.push({x : x, y : y});
drawSnakeHead();
if(snake.length > snakeLength){
drawSnakeTail();
snake.shift();
}
}
function drawYum(){
for(var i = 0; i < snake.length; i ++){
ctx.fillStyle = yumCol[yum];
ctx.fillRect(snake[i].x*snakePartSize, snake[i].y*snakePartSize, snakePartSize, snakePartSize);
}
}
function drawFood(){
var f = food[food.length-1];
ctx.fillStyle = "green";
ctx.fillRect(f.x*snakePartSize, f.y*snakePartSize, snakePartSize, snakePartSize);
}
function drawSnakeHead(){
var head = snake[snake.length-1];
ctx.fillStyle = "red";
ctx.fillRect(head.x*snakePartSize, head.y*snakePartSize, snakePartSize, snakePartSize);
}
function drawSnakeTail(){
var head = snake[0];
ctx.fillStyle = "black";
ctx.fillRect(head.x*snakePartSize, head.y*snakePartSize, snakePartSize, snakePartSize);
}
var counter = 0;
function update(){
counter += 1;
if(!gameOver){
if(snakeDirX === 0){
if(lastKeyDown === 37){ // left
snakeDirX = -1;
snakeDirY = 0;
}
if(lastKeyDown === 39){ // right
snakeDirX = 1;
snakeDirY = 0;
}
}
if(snakeDirY === 0){
if(lastKeyDown === 38){ // up
snakeDirY = -1;
snakeDirX = 0;
}
if(lastKeyDown === 40){ // down
snakeDirY = 1;
snakeDirX = 0;
}
}
lastKeyDown = 0;
if(counter % foodFreq ===0){
addFood();
}
if(counter % snakeSpeed === 0){
snakePosX += snakeDirX;
snakePosY += snakeDirY;
score += 1;
move(snakePosX ,snakePosY);
}
if((counter % 2 === 0) && yum > 0){
yum -= 1;
drawYum();
}
scoreE.textContent = "Score : "+ score;
}
if(gameOver){
if(!instDrawn){
instDrawn = true;
ctx.fillStyle = "white";
ctx.font = "32px arial";
ctx.textAlign = "center";
ctx.fillText("GAME OVER",canvas.width /2, canvas.height /2);
ctx.font = "16px arial";
ctx.fillText("Press a direction key to start.",canvas.width /2, canvas.height /2+32);
}
if(lastKeyDown >= 37 && lastKeyDown <= 40){
gameOver = false;
instDrawn = false;
counter = -1;
startSnake();
}
}
requestAnimationFrame(update);
}
requestAnimationFrame(update);
startSnake();

Can't figure out where to draw image in Javascript code

I am having issues trying to place an image as an object for an "asteroid avoidance" game. I was able to get the game itself to work based on what was written in my book "Foundation: HTML5 Canvas for Games and Entertainment". I want to go one step beyond what was written in the book. I want to replace the triangle shaped ship with that of an image. However, I am unable to figure out where to put the code for this.draw. My professor showed us a way to do it. When I try to implement it into my code it doesn't want to work properly. May I ask for some advice on how to place the image as the ship?
Here is my working code from the book, before I made any this.draw edits:(http://jsbin.com/tukejopofo/1/)
$(document).ready(function() {
var canvas = $("#gameCanvas");
var context = canvas.get(0).getContext("2d");
//canvas dimensions
var canvasWidth = canvas.width();
var canvasHeight = canvas.height();
var playGame;
var asteroids;
var numAsteroids;
var player;
var score;
var scoreTimeout;
var arrowUp = 38;
var arrowRight = 39;
var arrowDown = 40;
var arrowLeft = 37;
//game UI
var ui = $("#gameUI");
var uiIntro = $("#gameIntro");
var uiStats = $("#gameStats");
var uiComplete = $("#gameComplete");
var uiPlay = $("#gamePlay");
var uiReset = $(".gameReset");
var uiScore = $(".gameScore");
var soundBackground = $("#gameSoundBackground").get(0);
var soundThrust = $("#gameSoundThrust").get(0);
var soundDeath = $("#gameSoundDeath").get(0);
var Asteroid = function(x, y, radius, vX) {
this.x = x;
this.y = y;
this.radius = radius;
this.vX = vX;
};
var Player = function(x, y) {
this.x = x;
this.y = y;
this.width = 24;
this.height = 24;
this.halfWidth = this.width / 2;
this.halfHeight = this.height / 2;
this.flameLength1 = 20;
this.flameLength2 = 20;
this.vX = 0;
this.vY = 0;
this.moveRight = false;
this.moveUp = false;
this.moveDown = false;
this.moveLeft = false;
};
//Reset and start the game
function startGame() {
//Reset game stats
uiScore.html("0");
uiStats.show();
//set up initial game settings
playGame = false;
asteroids = new Array();
numAsteroids = 10;
score = 0;
player = new Player(150, canvasHeight / 2, 50, 50);
for (var i = 0; i < numAsteroids; i++) {
var radius = 5 + (Math.random() * 10);
var x = canvasWidth + radius + Math.floor(Math.random() * canvasWidth);
var y = Math.floor(Math.random() * canvasHeight);
var vX = -5 - (Math.random() * 5);
asteroids.push(new Asteroid(x, y, radius, vX));
};
$(window).keydown(function(e) {
var keyCode = e.keyCode;
if (!playGame) {
playGame = true;
soundBackground.currentTime = 0;
soundBackground.play();
animate();
timer();
};
if (keyCode == arrowRight) {
player.moveRight = true;
if (soundThrust.paused) {
soundThrust.currentTime = 0;
soundThrust.play();
}
} else if (keyCode == arrowLeft) {
player.moveLeft = true;
} else if (keyCode == arrowUp) {
player.moveUp = true;
} else if (keyCode == arrowDown) {
player.moveDown = true;
}
});
$(window).keyup(function(e) {
var keyCode = e.keyCode;
if (!playGame) {
playGame = true;
animate();
};
if (keyCode == arrowRight) {
player.moveRight = false;
if (keyCode == arrowRight) {
player.moveRight = false;
soundThrust.pause();
}
} else if (keyCode == arrowUp) {
player.moveUp = false;
} else if (keyCode == arrowDown) {
player.moveDown = false;
} else if (keyCode == arrowLeft) {
player.moveLeft = false;
}
});
//start the animation loop
animate();
};
//initialize the game environment
function init() {
uiStats.hide();
uiComplete.hide();
uiPlay.click(function(e) {
e.preventDefault();
uiIntro.hide();
startGame();
});
uiReset.click(function(e) {
e.preventDefault();
uiComplete.hide();
$(window).unbind("keyup");
$(window).unbind("keydown");
soundThrust.pause();
soundBackground.pause();
clearTimeout(scoreTimeout);
startGame();
});
};
function timer() {
if (playGame) {
scoreTimeout = setTimeout(function() {
uiScore.html(++score);
if (score % 5 == 0) {
numAsteroids += 5;
}
timer();
}, 1000);
};
};
//Animation loop that does all the fun stuff
function animate() {
//Clear
context.clearRect(0, 0, canvasWidth, canvasHeight);
var asteroidsLength = asteroids.length;
for (var i = 0; i < asteroidsLength; i++) {
var tmpAsteroid = asteroids[i];
tmpAsteroid.x += tmpAsteroid.vX;
if (tmpAsteroid.x + tmpAsteroid.radius < 0) { //creates bounderies to prevent player from leaving the canvas
tmpAsteroid.radius = 5 + (Math.random() * 10);
tmpAsteroid.x = canvasWidth + tmpAsteroid.radius;
tmpAsteroid.y = Math.floor(Math.random() * canvasHeight);
tmpAsteroid.vX = -5 - (Math.random() * 5);
}
var dX = player.x - tmpAsteroid.x;
var dY = player.y - tmpAsteroid.y;
var distance = Math.sqrt((dX * dX) + (dY * dY));
if (distance < player.halfWidth + tmpAsteroid.radius) { //checks for collision
soundThrust.pause()
soundDeath.currentTime = 0;
soundDeath.play();
//Game over
playGame = false;
clearTimeout(scoreTimeout);
uiStats.hide();
uiComplete.show();
soundBackground.pause();
$(window).unbind("keyup"); //unbinds keys to stop player movement at the end of the game
$(window).unbind("keydown");
};
context.fillStyle = "rgb(255, 255, 255)";
context.beginPath();
context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI * 2, true);
context.fill();
};
player.vX = 0;
player.vY = 0;
if (player.moveRight) {
player.vX = 3;
};
if (player.moveLeft) {
player.vX = -3;
};
if (player.moveUp) {
player.vY = -3;
};
if (player.moveDown) {
player.vY = 3;
};
player.x += player.vX;
player.y += player.vY;
if (player.x - player.halfWidth < 20) {
player.x = 20 + player.halfWidth;
} else if (player.x + player.halfWidth > canvasWidth - 20) {
player.x = canvasWidth - 20 - player.halfWidth;
}
if (player.y - player.halfHeight < 20) {
player.y = 20 + player.halfHeight;
} else if (player.y + player.halfHeight > canvasHeight - 20) {
player.y = canvasHeight - 20 - player.halfHeight;
}
if (player.moveRight) {
context.save();
context.translate(player.x - player.halfWidth, player.y);
if (player.flameLength1 == 20) {
player.flameLength1 = 15;
(player.flameLength2 == 20)
player.flameLength2 = 15;
} else {
player.flameLength1 = 20;
player.flameLength2 = 20;
};
context.fillStyle = "orange";
context.beginPath();
context.moveTo(0, -12);
context.lineTo(-player.flameLength1, -7);
context.lineTo(0, -5);
context.closePath();
context.fill();
context.fillStyle = "orange";
context.beginPath();
context.moveTo(0, 12);
context.lineTo(-player.flameLength2, 7);
context.lineTo(0, 5);
context.closePath();
context.fill();
context.restore();
};
//draw ship
context.fillStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(player.x + player.halfWidth, player.y);
context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
context.closePath();
context.fill();
while (asteroids.length < numAsteroids) { //adds asteroids as the difficulty increases
var radius = 5 + (Math.random() * 10)
var x = Math.floor(Math.random() * canvasWidth) + canvasWidth + radius;
var y = Math.floor(Math.random() * canvasHeight);
var vX = -5 - (Math.random() * 5);
asteroids.push(new Asteroid(x, y, radius, vX));
}
if (playGame) {
//run the animation loop again in 33 milliseconds
setTimeout(animate, 24);
};
};
init();
});
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
width: 100%;
}
canvas {
display: block;
}
body {
background: #000;
color: #fff;
font-family: Verdana, Arial, sans-serif;
font-size: 18px;
}
h1 {
font-size: 30px;
}
h6 {
font-size: 15px;
}
p {
margin: 0 20px;
}
a {
color: #fff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a.button {
background: #185da8;
border-radius: 5px;
display: block;
font-size: 30px;
margin: 40px 0 0 350px;
padding: 10px;
width: 200px;
text-align: center;
}
a.button:hover {
background: #2488f5;
color: #fff;
text-decoration: none;
}
#game {
height: 600px;
left: 50%;
margin: -250px 0 0 -500px;
position: relative;
top: 50%;
width: 980px;
}
#gameCanvas {
background: #001022;
border: 5px solid green;
background-image: url(../images/space.jpg);
background-position: center top;
background-repeat: no-repeat;
background-size: cover;
}
#gameUI {
height: 600px;
position: absolute;
width: 980px;
}
#gameIntro,
#gameComplete {
background: rgba(0, 0, 0, 0.5);
margin: 100px 0 0 10px;
padding: 40px 0;
text-align: center;
}
#gameStats {
font-size: 14px;
margin: 20px 0;
}
#gameStats .gameReset {
margin: 20px 20px 0 0;
position: absolute;
right: 0;
top: 0;
}
<body>
<div id="game">
<div id="gameUI">
<div id="gameIntro">
<h1>Debris Fields of Spiral Galaxy</h1>
<h6>A <i>Galaxy Smuggler's Run</i> Game</h6>
<hr>
<p>You are Captain Amadaeus delivering goods to a dependent planet on the other side of a debris field</p>
<p>Click <i>"Play"</i> and then press any key to start.</p>
<p><a id="gamePlay" class="button" href="">Play!</a>
</p>
</div>
<div id="gameStats">
<p><b>Time: </b><span class="gameScore"></span> seconds</p>
<p><a class="gameReset" href="">Reset</a>
</p>
</div>
<div id="gameComplete">
<h1>Game Over!</h1>
<p>You survived for <span class="gameScore"></span> seconds.</p>
<p>Would you like to give it another go?</p>
<p><a class="gameReset button" href="">Play Again?</a>
</p>
</div>
</div>
<canvas id="gameCanvas" width="980" height="600">
</canvas>
<audio id="gameSoundBackground" loop>
<source src="sounds/background.ogg">
<source src="sounds/background.mp3">
</audio>
<audio id="gameSoundThrust" loop>
<source src="sounds/thrust.ogg">
<source src="sounds/thrust.mp3">
</audio>
<audio id="gameSoundDeath">
<source src="sounds/death.ogg">
<source src="sounds/death.mp3">
</audio>
</div>
</body>
and here is my Professor's code for drawing an image:(http://jsbin.com/rapayufafe/1/)
// JS file for the ship
function Ship() {
this.x = 100;
this.y = 100;
this.color = "yellow";
this.fillStyle = "white";
this.vx = 0;
this.vy = 0;
this.ax = 1;
this.ay = 1;
//function "move" that will add velocity to the position of the ship
this.move = function() {
this.x += this.vx;
this.y += this.vy;
}//end move function
//draw the ship
this.draw=function () {
//ship var
var imageObj = new Image();
imageObj.src = "images/ship.png";
//save the current state of the canvas
context.save();
//moving the point of origin (0,0) to the ships x and y coordinates
context.translate(this.x,this.y);
context.lineStyle = this.color;
context.fillStyle = this.fillStyle;
/*context.beginPath();
context.moveTo(25,0);
context.lineTo(-25,25)
context.lineTo(-25,-25)*/
//draw ship
context.drawImage(imageObj,-25,-25,50,50);
context.closePath();
context.stroke();
context.fill();
context.restore();
}//end of draw ship
}//end ship function
/*var asteroidsLength = asteroids.length;
for (var i = 0; i < asteroidsLength; i++) {
var tmpAsteroid = asteroids[i];
context.fillStyle = "gray";
context.beginPath();
context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI*2, true);
context.closePath();
context.fill();
};*/
As you can see in your starting code, you have a section looking like this:
//draw ship
context.fillStyle = "rgb(255, 0, 0)";
context.beginPath();
context.moveTo(player.x + player.halfWidth, player.y);
context.lineTo(player.x - player.halfWidth, player.y - player.halfHeight);
context.lineTo(player.x - player.halfWidth, player.y + player.halfHeight);
context.closePath();
context.fill();
Just replace that code with the code for drawing an image.
var imageObj = new Image();
imageObj.src = "images/ship.png";
context.drawImage(imageObj,player.x,player.y);
Although, I'd recommend declaring the imageObj and setting the source at the top of your code where you declare the rest of your variables so that you don't load the image every time you want to draw the ship.

Why does the drawDashedLine function mess up my game?

I found a pong game online and wanted to change it around a bit. I want to put a dashed line in the middle of the screen.
if I take out the dashed line the game works. It will work in Chrome but locks up on the Firefox OS simulator.
****Question: Why would this be the case?"****
Code:
function drawDashedLine() {
ctx.beginPath();
ctx.fillStyle = '#eee';
ctx.setLineDash([1,2]);
ctx.moveTo(0,H/2);
ctx.lineTo(320,H/2);
ctx.closePath();
ctx.stroke();
}
HTML:
<html>
<head>
<title>Firefox OS</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
// RequestAnimFrame: a browser API for getting smooth animations
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
return window.setTimeout(callback, 1000 / 60);
};
})();
window.cancelRequestAnimFrame = ( function() {
return window.cancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
clearTimeout
} )();
//all global variables
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d"); // Create canvas context
//W = window.innerWidth, // Window's width
//H = window.innerHeight, // Window's height
var W = 310;
var H = 440;
var particles = []; // Array containing particles
var ball = {}; // Ball object
var paddles = [2]; // Array containing two paddles
var mouse = {}; // Mouse object to store it's current position
var points = 0; // Varialbe to store points
var fps = 60; // Max FPS (frames per second)
var flag = 0; // Flag variable which is changed on collision
var particlePos = {}; // Object to contain the position of collision
var multipler = 1; // Varialbe to control the direction of sparks
var startBtn = {}; // Start button object
var restartBtn = {}; // Restart button object
var over = 0; // flag varialbe, cahnged when the game is over
var init; // variable to initialize animation
var paddleHit;
// Add mousemove and mousedown events to the canvas
canvas.addEventListener("mousemove", trackPosition, true);
canvas.addEventListener("mousedown", btnClick, true);
// Set the canvas's height and width to full screen
canvas.width = W;
canvas.height = H;
// Ball object
ball = {
x: 50,
y: 50,
r: 5,
c: "red",
vx: 3,
vy: 7,
// Function for drawing ball on canvas
draw: function() {
ctx.beginPath();
ctx.fillStyle = this.c;
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2, false);
ctx.fill();
}
};
// Start Button object
startBtn = {
w: 100,
h: 50,
x: W/2 - 50,
y: H/2 - 25,
draw: function() {
ctx.strokeStyle = "white";
ctx.lineWidth = "2";
ctx.strokeRect(this.x, this.y, this.w, this.h);
ctx.font = "18px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStlye = "white";
ctx.fillText("Start", W/2, H/2 );
}
};
// Restart Button object
restartBtn = {
w: 100,
h: 50,
x: W/2 - 50,
y: H/2 - 50,
draw: function() {
ctx.strokeStyle = "white";
ctx.font = "18px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Tap Center Screen To Play Again!", W/2, H/2 - 25 );
}
};
// Function to paint canvas
function paintCanvas() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 310, 440);
}
// Function for creating paddles
function Paddle(pos) {
// Height and width
this.h = 8;
this.w = 55;
// Paddle's position
this.x = W/2 - this.w/2;
this.y = (pos == "top") ? 0 : H - this.h;
}
function draw() {
paintCanvas();
for(var i = 0; i < paddles.length; i++) {
p = paddles[i];
ctx.fillStyle = "white";
ctx.fillRect(p.x, p.y, p.w, p.h);
}
ball.draw();
update();
}
function increaseSpd() {
if(points % 2 == 33) {
if(Math.abs(ball.vx) < 15) {
ball.vx += (ball.vx < 0) ? -1 : 1;
ball.vy += (ball.vy < 0) ? -2 : 2;
}
}
}
function trackPosition(e) {
mouse.x = e.pageX;
mouse.y = e.pageY;
}
function movePaddles() {
if(mouse.x && mouse.y) {
for(var i = 1; i < paddles.length; i++) {
p = paddles[i];
p.x = mouse.x - p.w/2;
}
}
}
function collisions() {
if(collides(ball, p1)) {
collideAction(ball, p1);
}
else if(collides(ball, p2)) {
collideAction(ball, p2);
} else {
// Collide with walls, If the ball hits the top/bottom,
// walls, run gameOver() function
if(ball.y + ball.r > H) {
ball.y = H - ball.r;
gameOver(); //the game is over
} else if(ball.y < 0) {
ball.y = ball.r;
gameOver(); //the game is over
}
if(ball.x + ball.r > W) {
ball.vx = -ball.vx;
ball.x = W - ball.r;
} else if(ball.x -ball.r < 0) {
ball.vx = -ball.vx;
ball.x = ball.r;
}
}
}
function drawDashedLine() {
ctx.beginPath();
ctx.fillStyle = '#eee';
ctx.setLineDash([1,2]);
ctx.moveTo(0,H/2);
ctx.lineTo(320,H/2);
ctx.closePath();
ctx.stroke();
}
function update() {
updateScore();
movePaddles();
drawDashedLine()
ball.x += ball.vx;
ball.y += ball.vy;
p1 = paddles[1];
p2 = paddles[2];
collisions();
flag = 0;
}
function collides(b, p) {
if(b.x + ball.r >= p.x &&
b.x - ball.r <=p.x + p.w) {
if(b.y >= (p.y - p.h) && p.y > 0){
paddleHit = 1;
return true;
} else if(b.y <= p.h && p.y == 0) {
paddleHit = 2;
return true;
} else {
return false;
}
}
}
function collideAction(ball, p) {
ball.vy = -ball.vy;
if(paddleHit == 1) {
ball.y = p.y - p.h;
particlePos.y = ball.y + ball.r;
multiplier = -1;
} else if(paddleHit == 2) {
ball.y = p.h + ball.r;
particlePos.y = ball.y - ball.r;
multiplier = 1;
}
points++;
if(collision) {
if(points > 0) {
collision.pause();
}
collision.currentTime = 0;
collision.play();
}
particlePos.x = ball.x;
flag = 1;
}
// Function for updating score
function updateScore() {
ctx.fillStlye = "green";
ctx.font = "20px Arial, sans-serif";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText(points, 20, 20 );
}
// Function to run when the game overs
function gameOver() {
ctx.fillStlye = "white";
ctx.font = "20px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Game Over! ("+points+")", W/2, H/2 + 25 );
cancelRequestAnimFrame(init); //stops the animation frame
over = 1;
restartBtn.draw(); //This will allow the user to restart the game
}
// Function for running the whole animation
function animloop() {
init = requestAnimFrame(animloop);
draw();
}
// Function to execute at startup
function startScreen() {
draw();
startBtn.draw();
}
// On button click (Restart and start)
function btnClick(e) {
var mx = e.pageX;
var my = e.pageY;
if(mx >= startBtn.x && mx <= startBtn.x + startBtn.w) {
animloop();
startBtn = {};
}
// If the game is over, and the restart button is clicked
if(over == 1) {
if(mx >= restartBtn.x && mx <= restartBtn.x + restartBtn.w) {
ball.x = 20;
ball.y = 20;
points = 0;
ball.vx = 4;
ball.vy = 8;
animloop();
over = 0;
}
}
}
paddles.push(new Paddle("bottom"));
paddles.push(new Paddle("top"));
startScreen();
</script>
</body>
</html>

Categories