I have written a simple pong game in Javascript. But I am having two problems with it.
I don't know why the ball doesn't deflect off of the computer's paddle which is the "playerB" according to the code.
How can I create some randomness when the ball deflects from the paddles? Currently the game seems very repetitive.
How can I fix these two problems?
Link to Jsfiddle
<!DOCTYPE html>
<html>
<head>
<title>Pong game</title>
<script type="text/javascript" src="jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="js/pong.js"></script>
<link rel="stylesheet" href="css/pong.css">
</head>
<body>
<header>
<p>
Computer:<span id="scoreB"></span> Human:<span id="scoreA"></span>
</p>
</header>
<div id="playground">
<div id="ball"></div>
<div id="playerA" class="paddle right"></div>
<div id="playerB" class="paddle left"></div>
</div>
</body>
</html>
html,body{
margin: 0 atuo;
height:100%;
}
#playground{
position: relative;
width:700px;
height:400px;
border: 1px solid grey;
overflow:hidden;
}
#ball{
position: absolute;
background: #fbb;
width:20px;
height:20px;
left:200px;
top:100px;
border-radius:10px;
}
.paddle{
position: absolute;
border:1px solid grey;
width:10px;
height:80px;
}
.left.paddle{
left:0px;
background-color: green;
}
.right.paddle{
right:0px;
background-color: blue;
}
$(document).ready(function(){
var values = {
ball:{
speed:5,
x:50,
y:50,
directionX: 1,
directionY: 1,
radius: 10
},
playground:{
width: parseInt($("#playground").width()),
height: parseInt($("#playground").height())
},
playerA:{
y:0,
top: $("#playerA").offset().top,
height: $("#playerA").height(),
width: $("#playerA").width(),
score:0
},
playerB:{
y:0,
top: $("#playerB").offset().top,
height: $("#playerB").height(),
width: $("#playerB").width(),
score:0
}
};
//collision detection
function hitsTopBottom(){
var y = values.ball.y;
return y>values.playground.height-20 || y < 0;
}
function hitsRight(){
return values.ball.x > values.playground.width-20;
}
function hitsLeft(){
return values.ball.x < 0;
}
//ball hits playerA's paddle. Works properly but open to improvement
function hitsPlayerA(){
var ballX = values.ball.x;
var ballY = values.ball.y;
var playerAY = values.playerA.y;
return ballY<=playerAY+values.playerA.height && ballY>playerAY && ballX>=700-values.playerA.width-values.ball.radius;
}
//ball hits playerB's paddle. Doesn't work at all
function hitsPlayerB(){
var ballX = values.ball.x;
var ballY = values.ball.y;
var playerBY = values.playerB.y;
return ballY<=playerBY+values.playerB.height && ballY>=playerBY && ballX<=values.playerB.width-values.ball.radius;
}
//rendering the position of the ball
function renderball(){
$("#ball").css("left",values.ball.x);
$("#ball").css("top",values.ball.y);
$("#scoreB").text(values.playerB.score);
$("#scoreA").text(values.playerA.score);
}
//moving ball
function moveball(){
if(hitsTopBottom()){
values.ball.directionY *= -1;
}
if(hitsPlayerA()){
values.ball.directionX *= -1;
}
if(hitsPlayerB()){
values.ball.directionX = 1;
}
if(hitsRight()){
values.ball.x = 200;
values.ball.y = 200;
values.playerB.score += 1;
}
if(hitsLeft()){
values.ball.x = 200;
values.ball.y = 200;
values.playerA.score += 1;
}
values.ball.x += values.ball.speed*values.ball.directionX;
values.ball.y += values.ball.speed*values.ball.directionY;
renderball();
var playerB_pos = values.ball.y - values.playerB.height/2;
$("#playerB").css("top",playerB_pos);
}
//player movements
$("#playground").mousemove(function(e){
values.playerA.y = e.pageY-values.playerA.top-parseInt($("#playerA").height()/2);
$("#playerA").css("top",values.playerA.y);
});
setInterval(moveball,1000/30);
});
The ball was not deflecting off the computer paddle because its position was not being stored. By setting values.playerB.y = playerB_pos
in the loop it will correctly bounce off now. However since it is the same as the y position of the ball the computer will never lose. To correct for this and add some randomness I used jQuery's animate function to tween the computer paddle between points and fake momentum:
if(!isAnimating) {
isAnimating = true;
$("#playerB").animate({"top": playerB_pos}, {
duration: (values.ball.speed*16),
easing: "linear",
step: function( now, fx ) {
values.playerB.y = parseInt($("#playerB").offset().top - parseInt($("#playerA").height()));
},
complete: function() {
isAnimating = false;
}
});
}
You can see it in action here: http://jsfiddle.net/yb290ow9/5/
You forgot to edit the actual playerB.y value (you just changed the css):
var playerB_pos = values.ball.y - values.playerB.height/2;
values.playerB.y = playerB_pos; // Forgot this!
$("#playerB").css("top",playerB_pos);
Working JSFiddle: http://jsfiddle.net/yb290ow9/6/
About the randomness: you could make the paddle "bouncy": change the speed of the ball, not just the direction
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With