Reputation:
I'm trying to make a pong-game in Canvas. I figured I would start by making the ball move across the street. The problem is when I loop the draw-function it turns into a line, instead of a ball at each new position. (See screenshot below.)
I thought clearing the canvas and then re-drawing everything would solve the problem, but apparently not.
Here is my code:
HTML:
<!doctype html>
<html lang="sv">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css">
<title>Super Pong!</title>
<script type="text/javascript" src="superPong.js"></script>
</head>
<body>
<nav>
<ul id="navlist">
<li><a href="#">Button 1</a></li>
<li><a href="#">Button 2</a></li>
<li><a href="#">Button 3</a></li>
<li><a href="#">Button 4</a></li>
</ul>
</nav>
<div id="content">
<canvas width="1000" height="600">Your browser does not support HTML5 Canvas</canvas>
</div>
</body>
</html>
CSS:
body {
background-color: #E93D19;
color: #341711;
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 2vw;
}
#content {
text-align: center;
padding-top: 3%;
}
canvas {
background-color: white;
}
nav {
height: 100px;
width: 100%;
text-align: center;
font-size: 3vw;
}
#navlist {
background-color: #FD851D;
list-style-type: none;
margin: 0;
overflow: hidden;
padding: 0;
transform: translateY(10%);
}
#navlist li {
display: inline;
}
#navlist a {
color: #C91D09;
text-decoration: none;
}
#navlist a:hover {
background-color: #C91D09;
color: #FD851D;
}
JavaScript:
window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded(){
var canvas=document.querySelector("canvas");
var ctx=canvas.getContext("2d");
var canWidth=canvas.width;
var canHeight=canvas.height;
var pi=Math.PI;
var timer=null;
var ms=16;
var gameBall={
size:30,
positionX:0,
positionY:0,
color:"#FFF",
set setSize(newSize){
this.size=newSize;
},
set setPosX(posX){
this.positionX=posX;
},
set setPosY(posY){
this.positionY=posY;
},
set setColor(newColor){
this.color=newColor;
},
get getSize(){
return this.size;
},
get getPosX(){
return this.positionX;
},
get getPosY(){
return this.positionY;
},
get getColor(){
return this.color;
}
}
function clearCanvas(){
ctx.clearRect(0,0,canWidth,canHeight);
}
function drawBackground(){
ctx.fillStyle="#000";
ctx.fillRect(0,0,canWidth,canHeight);
}
function drawBall(){
ctx.save();
var posX=gameBall.getPosX;
var posY=gameBall.getPosY;
var size=gameBall.getSize;
ctx.fillStyle=gameBall.getColor;
ctx.arc(posX,posY,size,0,2*pi,true);
ctx.fill();
ctx.restore();
}
function updateBall(){
//clearCanvas();
//drawBackground();
gameBall.setPosX=gameBall.getPosX+3;
gameBall.setPosY=gameBall.getPosY+3;
drawBall();
}
gameBall.setPosX=100;
gameBall.setPosY=100;
drawBackground();
timer=setInterval(updateBall, ms);
}
Upvotes: 3
Views: 1891
Reputation: 63802
You need to clear the canvas every time you redraw a frame.
When drawing paths, you need to make sure that you are creating a new path each frame, and not adding on to the current path. This is usually done by calling ctx.beginPath()
to clear out the context's current path.
Upvotes: 0
Reputation: 105015
Below is a working version of your Fiddle. It's refactored for these 2 issues:
Your prior balls are remaining because Canvas does not allow repositioning of existing ball drawings. The .save & .restore commands just save & restore the context properties -- they do not save & restore drawings on the canvas. Instead, you must erase the canvas and redraw the ball in its new position. So (1) drawBackground, (2) update & (3) drawBall in updateBall is a proper way of "moving" on canvas.
You must call context.beginPath
each time you draw your context.arc
(ball). If not, all previous version of the .arc command will be redrawn.
function eventWindowLoaded(){
var canvas=document.querySelector("canvas");
var ctx=canvas.getContext("2d");
var canWidth=canvas.width;
var canHeight=canvas.height;
var pi=Math.PI;
var timer=null;
var ms=1000/60*1;
var gameBall={
size:30,
positionX:0,
positionY:0,
color:"#FFF",
set setSize(newSize){
this.size=newSize;
},
set setPosX(posX){
this.positionX=posX;
},
set setPosY(posY){
this.positionY=posY;
},
set setColor(newColor){
this.color=newColor;
},
get getSize(){
return this.size;
},
get getPosX(){
return this.positionX;
},
get getPosY(){
return this.positionY;
},
get getColor(){
return this.color;
}
}
function clearCanvas(){
ctx.clearRect(0,0,canWidth,canHeight);
}
function drawBall(){
ctx.save();
var posX=gameBall.getPosX;
var posY=gameBall.getPosY;
var size=gameBall.getSize;
ctx.fillStyle=gameBall.getColor;
ctx.beginPath();
ctx.arc(posX,posY,size,0,2*pi,true);
ctx.fill();
ctx.restore();
}
function updateBall(){
//clearCanvas();
gameBall.setPosX=gameBall.getPosX+3;
gameBall.setPosY=gameBall.getPosY+3;
ctx.fillStyle='black';
ctx.fillRect(0,0,canvas.width,canvas.height);
drawBall();
}
gameBall.setPosX=35;
gameBall.setPosY=35;
timer=setInterval(updateBall, ms);
}
eventWindowLoaded();
body {
background-color: #E93D19;
color: #341711;
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 2vw;
}
#content {
text-align: center;
padding-top: 3%;
}
canvas {
background-color: black;
}
nav {
height: 100px;
width: 100%;
text-align: center;
font-size: 3vw;
}
#navlist {
background-color: #FD851D;
list-style-type: none;
margin: 0;
overflow: hidden;
padding: 0;
transform: translateY(10%);
}
#navlist li {
display: inline;
}
#navlist a {
color: #C91D09;
text-decoration: none;
}
#navlist a:hover {
background-color: #C91D09;
color: #FD851D;
}
<body>
<nav>
<ul id="navlist">
<li><a href="#">Button 1</a></li>
<li><a href="#">Button 2</a></li>
<li><a href="#">Button 3</a></li>
<li><a href="#">Button 4</a></li>
</ul>
</nav>
<div id="content">
<canvas width="600" height="400">Your browser does not support HTML5 Canvas</canvas>
</div>
</body>
Upvotes: 1