I have a simple Pong game made with some Javascript and a Canvas tag.
I set the background color of the canvas tag to be transparent so the background image of the div tag can be displayed under the canvas.
The problem is that when I have it set to transparent it doesn't draw the ball and paddles correctly as if I set the background to a normal hex color. It draws the path of the paddles and the ball and the screen eventually turns the color of the ball.
The Javascript code is:
//canvas
var Width = 988;
var Height = 310;
var canvas = document.getElementById("Pong");
canvas.width = Width;
canvas.height = Height;
canvas.setAttribute('tabindex', 1);
var ctx = canvas.getContext("2d");
var FPS = 1000 / 60;
var BG = {
Color: 'transparent',
Paint: function(){
ctx.fillStyle = this.Color;
ctx.fillRect(0, 0, Width, Height);
}
};
//var Mouse = {X: 0, Y: 0};
var Ball = {
Radius: 6,
Color: '#ffffff',
X: 0,
Y: 0,
VelX: 0,
VelY: 0,
Paint: function(){
ctx.beginPath();
ctx.fillStyle = this.Color;
ctx.arc(this.X, this.Y, this.Radius, 0, Math.PI * 2, false);
ctx.fill();
this.Update();
},
Update: function(){
this.X += this.VelX;
this.Y += this.VelY;
},
Reset: function(){
this.X = Width/2;
this.Y = Height/2;
this.VelX = (!!Math.round(Math.random() * 1) ? 1.5 : -1.5);
this.VelY = (!!Math.round(Math.random() * 1) ? 1.5 : -1.5);
}
};
function Paddle(position){
this.Color = '#ffffff';
this.Width = 15;
this.Height = 60;
this.X = 0;
this.Y = Height/2 - this.Height/2;
this.Score = 0;
if(position == 'left')
this.X = 50;
else this.X = 938;
this.Paint = function(){
ctx.fillStyle = this.Color;
ctx.fillRect(this.X, this.Y, this.Width, this.Height);
ctx.fillStyle = this.Color;
ctx.font = "normal 10pt Calibri";
if(position == 'left'){
ctx.textAlign = "left";
ctx.fillText("score: " + Player.Score, 10, 10);
}else{
ctx.textAlign = "right";
ctx.fillText("score: " + Computer.Score, Width - 10, 10);
}
};
this.IsCollision = function () {
if (Ball.X - Ball.Radius > this.Width + this.X || this.X > Ball.Radius * 2 + Ball.X - Ball.Radius)
return false;
if (Ball.Y - Ball.Radius > this.Height + this.Y || this.Y > Ball.Radius * 2 + Ball.Y - Ball.Radius)
return false;
return true;
};
};
window.requestAnimFrame = (function(){
return window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function( callback ){ return window.setTimeout(callback, FPS); }; }
)();
window.cancelRequestAnimFrame = (function() {
return window.cancelAnimationFrame
|| window.webkitCancelRequestAnimationFrame
|| window.mozCancelRequestAnimationFrame
|| window.oCancelRequestAnimationFrame
|| window.msCancelRequestAnimationFrame
|| clearTimeout }
)();
//game
var Computer = new Paddle();
var Player = new Paddle('left');
//event listener
function MouseMove(e){
Player.Y = e.pageY - Player.Height/2;
}
//attache event
canvas.addEventListener("mousemove", MouseMove, true);
function Paint(){
ctx.beginPath();
BG.Paint();
Computer.Paint();
Player.Paint();
Ball.Paint();
}
function Loop(){
init = requestAnimFrame(Loop);
Paint();
if(Player.IsCollision() || Computer.IsCollision()){
Ball.VelX = Ball.VelX * -1;
Ball.VelX += (Ball.VelX > 0 ? 0.5 : -0.5 );
if(Math.abs(Ball.VelX) > Ball.Radius * 1.5)
Ball.VelX = (Ball.VelX > 0 ? Ball.Radius * 1.5 : Ball.Radius * -1.5);
}
if(Ball.Y - Ball.Radius < 0 || Ball.Y + Ball.Radius > Height)
Ball.VelY = Ball.VelY * -1;
if(Ball.X - Ball.Radius <= 0){
Computer.Score++;
Ball.Reset();
}else if(Ball.X + Ball.Radius > Width){
Player.Score++;
Ball.Reset();
}
if(Computer.Score === 10)
GameOver(false);
else if(Player.Score === 10)
GameOver(true);
Computer.Y = (Computer.Y + Computer.Height/2 < Ball.Y ? Computer.Y + Computer.Vel : Computer.Y - Computer.Vel);
};
function GameOver(win){
cancelRequestAnimFrame(init);
BG.Paint();
ctx.fillStyle = "#ffffff";
ctx.font = "bold 40px Calibri";
ctx.textAlign = "center";
ctx.fillText((win ? "A WINNER IS YOU" : "GAME OVER"), Width/2, Height/2);
ctx.font = "normal 16px Calibri";
ctx.fillText("refresh to reply", Width/2, Height/2 + 20);
}
function NewGame(){
Ball.Reset();
Player.Score = 0;
Computer.Score = 0;
Computer.Vel = 1.25;
Loop();
}
NewGame();
I tried simply removing the BG var but it just did the same thing.
Update: I also tried with and without ctx.closePath with no success.
I have a simple Pong game made with some Javascript and a Canvas tag.
I set the background color of the canvas tag to be transparent so the background image of the div tag can be displayed under the canvas.
The problem is that when I have it set to transparent it doesn't draw the ball and paddles correctly as if I set the background to a normal hex color. It draws the path of the paddles and the ball and the screen eventually turns the color of the ball.
The Javascript code is:
//canvas
var Width = 988;
var Height = 310;
var canvas = document.getElementById("Pong");
canvas.width = Width;
canvas.height = Height;
canvas.setAttribute('tabindex', 1);
var ctx = canvas.getContext("2d");
var FPS = 1000 / 60;
var BG = {
Color: 'transparent',
Paint: function(){
ctx.fillStyle = this.Color;
ctx.fillRect(0, 0, Width, Height);
}
};
//var Mouse = {X: 0, Y: 0};
var Ball = {
Radius: 6,
Color: '#ffffff',
X: 0,
Y: 0,
VelX: 0,
VelY: 0,
Paint: function(){
ctx.beginPath();
ctx.fillStyle = this.Color;
ctx.arc(this.X, this.Y, this.Radius, 0, Math.PI * 2, false);
ctx.fill();
this.Update();
},
Update: function(){
this.X += this.VelX;
this.Y += this.VelY;
},
Reset: function(){
this.X = Width/2;
this.Y = Height/2;
this.VelX = (!!Math.round(Math.random() * 1) ? 1.5 : -1.5);
this.VelY = (!!Math.round(Math.random() * 1) ? 1.5 : -1.5);
}
};
function Paddle(position){
this.Color = '#ffffff';
this.Width = 15;
this.Height = 60;
this.X = 0;
this.Y = Height/2 - this.Height/2;
this.Score = 0;
if(position == 'left')
this.X = 50;
else this.X = 938;
this.Paint = function(){
ctx.fillStyle = this.Color;
ctx.fillRect(this.X, this.Y, this.Width, this.Height);
ctx.fillStyle = this.Color;
ctx.font = "normal 10pt Calibri";
if(position == 'left'){
ctx.textAlign = "left";
ctx.fillText("score: " + Player.Score, 10, 10);
}else{
ctx.textAlign = "right";
ctx.fillText("score: " + Computer.Score, Width - 10, 10);
}
};
this.IsCollision = function () {
if (Ball.X - Ball.Radius > this.Width + this.X || this.X > Ball.Radius * 2 + Ball.X - Ball.Radius)
return false;
if (Ball.Y - Ball.Radius > this.Height + this.Y || this.Y > Ball.Radius * 2 + Ball.Y - Ball.Radius)
return false;
return true;
};
};
window.requestAnimFrame = (function(){
return window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function( callback ){ return window.setTimeout(callback, FPS); }; }
)();
window.cancelRequestAnimFrame = (function() {
return window.cancelAnimationFrame
|| window.webkitCancelRequestAnimationFrame
|| window.mozCancelRequestAnimationFrame
|| window.oCancelRequestAnimationFrame
|| window.msCancelRequestAnimationFrame
|| clearTimeout }
)();
//game
var Computer = new Paddle();
var Player = new Paddle('left');
//event listener
function MouseMove(e){
Player.Y = e.pageY - Player.Height/2;
}
//attache event
canvas.addEventListener("mousemove", MouseMove, true);
function Paint(){
ctx.beginPath();
BG.Paint();
Computer.Paint();
Player.Paint();
Ball.Paint();
}
function Loop(){
init = requestAnimFrame(Loop);
Paint();
if(Player.IsCollision() || Computer.IsCollision()){
Ball.VelX = Ball.VelX * -1;
Ball.VelX += (Ball.VelX > 0 ? 0.5 : -0.5 );
if(Math.abs(Ball.VelX) > Ball.Radius * 1.5)
Ball.VelX = (Ball.VelX > 0 ? Ball.Radius * 1.5 : Ball.Radius * -1.5);
}
if(Ball.Y - Ball.Radius < 0 || Ball.Y + Ball.Radius > Height)
Ball.VelY = Ball.VelY * -1;
if(Ball.X - Ball.Radius <= 0){
Computer.Score++;
Ball.Reset();
}else if(Ball.X + Ball.Radius > Width){
Player.Score++;
Ball.Reset();
}
if(Computer.Score === 10)
GameOver(false);
else if(Player.Score === 10)
GameOver(true);
Computer.Y = (Computer.Y + Computer.Height/2 < Ball.Y ? Computer.Y + Computer.Vel : Computer.Y - Computer.Vel);
};
function GameOver(win){
cancelRequestAnimFrame(init);
BG.Paint();
ctx.fillStyle = "#ffffff";
ctx.font = "bold 40px Calibri";
ctx.textAlign = "center";
ctx.fillText((win ? "A WINNER IS YOU" : "GAME OVER"), Width/2, Height/2);
ctx.font = "normal 16px Calibri";
ctx.fillText("refresh to reply", Width/2, Height/2 + 20);
}
function NewGame(){
Ball.Reset();
Player.Score = 0;
Computer.Score = 0;
Computer.Vel = 1.25;
Loop();
}
NewGame();
I tried simply removing the BG var but it just did the same thing.
Update: I also tried with and without ctx.closePath with no success.
Share Improve this question edited Oct 24, 2013 at 23:39 Carl asked Oct 24, 2013 at 23:21 CarlCarl 2453 gold badges4 silver badges15 bronze badges 3-
You never seem to call
ctx.closePath
which will probably cause issues. – david Commented Oct 24, 2013 at 23:30 - @david Thanks for the ment. I just tried that with no success. – Carl Commented Oct 24, 2013 at 23:38
-
1
That doesn't matter, unless you try to
stroke
the path. Forfill
, it auto-closes. – Niet the Dark Absol Commented Oct 24, 2013 at 23:42
2 Answers
Reset to default 6This is because you don't clear the canvas at the start of each frame. With a solid-colour background this doesn't matter, but with transparent you must do this:
ctx.clearRect(0,0,canvas.width,canvas.height);
You need to clear the canvas on every draw. Canvas keeps the content that has been drawn on it.
Having a transparent canvas isn't a good idea anyway. Transparency makes things slower as it has to be reputed every time you draw anything to the canvas. Try drawing an image into it using the image draw functions. You might find that it can use the GPU to do the image position.