diff --git a/public/images/wood.jpg b/public/images/wood.jpg new file mode 100644 index 00000000..386f0194 Binary files /dev/null and b/public/images/wood.jpg differ diff --git a/public/index.html b/public/index.html index b60a0381..87ec40ad 100644 --- a/public/index.html +++ b/public/index.html @@ -3,6 +3,9 @@ Ping Pong Game + diff --git a/public/js/app.js b/public/js/app.js index b48d7f64..b7815557 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -6,6 +6,7 @@ var app = { //resizing width : 800, height : 400, + background : new Image(), //nodes nodes : [], @@ -19,6 +20,12 @@ var app = { this.canvas = document.getElementById('canvas'); this.context = this.canvas.getContext('2d'); + /** + * Download from: + * https://pixabay.com/es/photos/madera-piso-fondo-antecedentes-1866667 + */ + this.background.src = "images/wood.jpg"; + this.render(); this.onInit(); }, @@ -35,17 +42,27 @@ var app = { var dt = Date.now() - this.lastUpdate; this.onUpdate(dt); + this.context.drawImage(this.background,0,0); for(var index in this.nodes){ var node = this.nodes[index]; // Create new node for Text if(node.istext) { + this.context.fillStyle = 'black' this.context.font = node.size+'px serif'; this.context.fillText(node.text, node.x, node.y); }else { - this.context.fillStyle = node.color; - this.context.fillRect(node.x, node.y, node.width, node.height); + if(node.isball) { + this.context.fillStyle = node.color; + this.context.beginPath(); + this.context.arc(node.x, node.y, node.r, 0, Math.PI * 2); + this.context.closePath(); + this.context.fill() + }else { + this.context.fillStyle = node.color; + this.context.fillRect(node.x, node.y, node.width, node.height); + } } } diff --git a/public/js/modules/module.js b/public/js/modules/module.js index abc6bef4..fef1bf4d 100644 --- a/public/js/modules/module.js +++ b/public/js/modules/module.js @@ -3,17 +3,17 @@ class Player { constructor(id,app,color,playerNum) { this.initialY = app.height/2 - this.speed = 5 + this.speed = 9 this.move = { up : false, down : false } let x = 0 if(playerNum == 1) { - x = app.width/20 - (app.width/20) // Player One position + x = app.width/20 // Player One position } if(playerNum == 2) { - x = (app.width) - (app.width/20) // Player Two position + x = app.width - (app.width/20*2) // Player Two position } this.initial = { id : id, @@ -28,6 +28,7 @@ class Player { } reset() { + this.speed = 9 this.node.y = this.initialY } @@ -52,21 +53,22 @@ class Player { getNode() { return this.node } } - -// Node ball class -class Ball { - constructor(id,app,color) { +// Node RoundBall class +class RoundBall { + constructor(id,app,color,playerOne,playerTwo) { + this.p1 = playerOne + this.p2 = playerTwo this.ref = app - this.speed = 6 - this.velocityX = 6 - this.velocityY = 6 + this.speed = 10 + this.velocityX = 8 + this.velocityY = 8 this.initial = { id : id, - width : app.width/30, - height : app.height/25, + r : 15, // Ball Radius x : app.width/2, y : app.height/2, - color : color + color : color, + isball: true } app.nodes.push(this.initial) this.node = app.getNode(this.initial.id) @@ -75,6 +77,12 @@ class Ball { one: 0, two: 0 } + + /** + * Download from https://pixabay.com/sound-effects/ + */ + this.bounce = new Sound('sounds/metal-hit-cartoon.mp3', false) + this.scoreSound = new Sound('sounds/8-bit-powerup.mp3', false) } reset(resetGame) { @@ -86,8 +94,16 @@ class Ball { } this.node.x = this.ref.width/2 this.node.y = this.ref.height/2 - this.speed = 6 + this.speed = 10 + this.velocityX = 8 + this.velocityY = 8 this.velocityX = -this.velocityX + this.p1.speed = 9 + this.p2.speed = 9 + } + + playBounce() { + this.bounce.play() } update(deltatime) { @@ -97,15 +113,18 @@ class Ball { } // Change the ball direction when collide with top and botton border - if(this.node.y + (this.node.height/2) > this.ref.height || this.node.y - (this.node.height/2) < 0) { + if(this.node.y + this.node.r > this.ref.height || this.node.y - this.node.r < 0) { + this.playBounce() // Play Ball bounce this.velocityY = -this.velocityY } // Reset Ball when collide with left or right border to set score if(this.node.x < 0) { + this.scoreSound.play() this.score.one ++ this.reset(false) }else if(this.node.x > this.ref.width) { + this.scoreSound.play() this.score.two ++ this.reset(false) } @@ -114,6 +133,7 @@ class Ball { getNode() { return this.node } } + // Node text class class Text { constructor(id,x,y,size,text,app) { @@ -135,4 +155,47 @@ class Text { } getText() { return this.node } // Return text node +} + + +// Node Net class +class Net { + constructor(id,app,color) { + this.initial = { + id : id, + width : 20, + height : app.height, + x : app.width/2 - (10), + y : 0, + color : color + } + app.nodes.push(this.initial) + this.node = app.getNode(this.initial.id) + } +} + +// Sound Class +class Sound { + constructor(src,loop) { + this.sound = document.createElement("audio"); + this.sound.src = src; + this.sound.setAttribute("preload", "auto"); + this.sound.setAttribute("controls", "none"); + if(loop) { + this.sound.setAttribute("loop", loop) + } + this.sound.style.display = "none"; + this.sound.volume = 0.2 + document.body.appendChild(this.sound); + } + + play() { + this.sound.currentTime = 0 + this.sound.play() + } + + pause() { + this.sound.pause() + this.sound.currentTime = 0 + } } \ No newline at end of file diff --git a/public/js/modules/start.js b/public/js/modules/start.js index 2c911417..ec8ca945 100644 --- a/public/js/modules/start.js +++ b/public/js/modules/start.js @@ -9,19 +9,30 @@ app.height = window.innerHeight document.body.scrollTop = 0; // <-- pull the page back up to the top document.body.style.overflow = 'hidden'; // <-- relevant addition +var net = new Net('net',app,'orange') + var PlayerOne = new Player('player-one',app,'blue',1) var PlayerTwo = new Player('player-two',app,'red',2) -var ball = new Ball('ball',app,'black') +var roundBall = new RoundBall('roundball',app,'white',PlayerOne,PlayerTwo) -var player1Score = new Text('score-two',(app.width/4) * 3, app.height / 4,50,"0",app) -var player2Score = new Text('score-one',app.width / 4, app.height / 4,50,"0",app) -var startText = new Text('start',app.width/2, app.height - 50, 50,"Press 'Enter' to Start",app) -var pauseText = new Text('pause',app.width/2, app.height - 50,50,"",app) -var pauseInst = new Text('pauseInst',app.width/2, app.height - 25,25,"",app) +var mainText = 50, secondText = 25; +var player1Score = new Text('score-two',(app.width/4) * 3, app.height / 4, mainText*1.5,"0",app) +var player2Score = new Text('score-one',app.width / 4, app.height / 4, mainText*1.5,"0",app) +var startText = new Text('start',app.width/2 + (mainText/2), app.height - 50, mainText,"Press 'Enter' to Start",app) +var pauseText = new Text('pause',app.width/2 + (mainText/2), app.height - 50, mainText,"",app) +var pauseInst = new Text('pauseInst',app.width/2 + (secondText/2), app.height - 25, secondText,"",app) var state = 'START' +/** + * Add Game Music Level1.wav + * Created by https://juhanijunkala.com/ + */ +var music = new Sound('sounds/level1.wav', true) + + +// Init app.onInit = function(){ document.addEventListener('keydown', (event) => { @@ -51,13 +62,16 @@ app.onInit = function(){ PlayerTwo.moveDown(false) if(keyName == 'Enter'){ - if(state == 'START') + if(state == 'START'){ + music.play() // Start Game Music state = 'GAME' + } } if(keyName == ' '){ - if(state == 'GAME' || state == 'PAUSE') + if(state == 'GAME' || state == 'PAUSE'){ this.pause() + } } if(keyName == 'r'){ @@ -87,11 +101,13 @@ app.onUpdate = function(time){ app.pause = function(){ if(state == 'GAME'){ + music.pause() // Pause Game Music state = 'PAUSE' pauseText.setText("Pause") pauseInst.setText("press 'R' for reset") } else{ + music.play() // Resume Game Music state = 'GAME' pauseText.setText("") pauseInst.setText("") @@ -103,7 +119,7 @@ app.reset = function(){ PlayerTwo.reset() player1Score.setText("0") player2Score.setText("0") - ball.reset(true) + roundBall.reset(true) state = 'START' pauseText.setText("") pauseInst.setText("") @@ -114,15 +130,15 @@ function gameRuning(deltatime) { PlayerOne.update(deltatime) PlayerTwo.update(deltatime) - ball.update(deltatime) - player1Score.setText(ball.score.one) - player2Score.setText(ball.score.two) + roundBall.update(deltatime) + player1Score.setText(roundBall.score.one) + player2Score.setText(roundBall.score.two) - if(collision(ball.getNode(),PlayerOne.getNode())){ - changeDirection(ball,PlayerOne,app) + if(collision(roundBall.getNode(),PlayerOne.getNode())){ + changeDirection(roundBall,PlayerOne,app) } - if(collision(ball.getNode(),PlayerTwo.getNode())){ - changeDirection(ball,PlayerTwo,app) + if(collision(roundBall.getNode(),PlayerTwo.getNode())){ + changeDirection(roundBall,PlayerTwo,app) } } @@ -133,10 +149,10 @@ function collision(ball,player) { let pLeft = player.x let pRight = (player.x) + player.width - let bTop = ball.y - let bBottom = (ball.y) + ball.height - let bLeft = ball.x - let bRight = (ball.x) + ball.width + let bTop = ball.y - ball.r + let bBottom = (ball.y) + ball.r + let bLeft = ball.x - ball.r + let bRight = (ball.x) + ball.r // boolean for collision return bRight > pLeft && bTop < pBottom && bLeft < pRight && bBottom > pTop @@ -144,6 +160,7 @@ function collision(ball,player) { // Change ball direction once it collides with player function changeDirection(ball,player,app) { + ball.playBounce() // Play Ball bounce let collideHit = ball.getNode().y - (player.getNode().y + player.getNode().height / 2) collideHit = collideHit / (player.getNode().height / 2) let angle = (Math.PI/4) * collideHit @@ -155,5 +172,6 @@ function changeDirection(ball,player,app) { ball.velocityX = direction * ball.speed * Math.cos(angle) ball.velocityY = direction * ball.speed * Math.sin(angle) - ball.speed += 0.5 + ball.speed += 1 + player.speed += 1 } \ No newline at end of file diff --git a/public/sounds/8-bit-powerup.mp3 b/public/sounds/8-bit-powerup.mp3 new file mode 100644 index 00000000..0495c3c3 Binary files /dev/null and b/public/sounds/8-bit-powerup.mp3 differ diff --git a/public/sounds/level1.wav b/public/sounds/level1.wav new file mode 100644 index 00000000..01fc7f83 Binary files /dev/null and b/public/sounds/level1.wav differ diff --git a/public/sounds/metal-hit-cartoon.mp3 b/public/sounds/metal-hit-cartoon.mp3 new file mode 100644 index 00000000..152b3fe0 Binary files /dev/null and b/public/sounds/metal-hit-cartoon.mp3 differ