Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 透明彩色HTML5画布_Javascript_Html_Canvas - Fatal编程技术网

Javascript 透明彩色HTML5画布

Javascript 透明彩色HTML5画布,javascript,html,canvas,Javascript,Html,Canvas,我有一个简单的乒乓球游戏,用一些Javascript和一个画布标签制作 我将canvas标记的背景色设置为透明,以便div标记的背景图像可以显示在canvas下 问题是,当我将其设置为透明时,它不能正确地绘制球和划桨,就像我将背景设置为正常的十六进制颜色一样。它会绘制球拍和球的路径,屏幕最终会改变球的颜色 Javascript代码是: //canvas var Width = 988; var Height = 310; var canvas = document.getElementById(

我有一个简单的乒乓球游戏,用一些Javascript和一个画布标签制作

我将canvas标记的背景色设置为透明,以便div标记的背景图像可以显示在canvas下

问题是,当我将其设置为透明时,它不能正确地绘制球和划桨,就像我将背景设置为正常的十六进制颜色一样。它会绘制球拍和球的路径,屏幕最终会改变球的颜色

Javascript代码是:

//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();
//画布
var宽度=988;
var高度=310;
var canvas=document.getElementById(“Pong”);
画布宽度=宽度;
canvas.height=高度;
canvas.setAttribute('tabindex',1);
var ctx=canvas.getContext(“2d”);
var FPS=1000/60;
变量BG={
颜色:'透明',
绘制:函数(){
ctx.fillStyle=this.Color;
ctx.fillRect(0,0,宽度,高度);
}
};
//变量鼠标={X:0,Y:0};
变量球={
半径:6,
颜色:“#ffffff”,
X:0,,
Y:0,
VelX:0,
结果:0,,
绘制:函数(){
ctx.beginPath();
ctx.fillStyle=this.Color;
ctx.arc(this.X,this.Y,this.Radius,0,Math.PI*2,false);
ctx.fill();
这个.Update();
},
更新:函数(){
this.X+=this.VelX;
this.Y+=this.Y;
},
重置:函数(){
这.X=宽度/2;
这.Y=高度/2;
this.VelX=(!!Math.round(Math.random()*1)?1.5:-1.5);
this.VelY=(!!Math.round(Math.random()*1)?1.5:-1.5);
}
};
功能挡板(位置){
this.Color='#ffffff';
这个。宽度=15;
这个。高度=60;
这个.X=0;
this.Y=高度/2-this.Height/2;
这个分数=0;
如果(位置==“左”)
这个X=50;
否则,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=“标准10磅口径”;
如果(位置==“左”){
ctx.textAlign=“左”;
ctx.fillText(“分数:+Player.score,10,10);
}否则{
ctx.textAlign=“右”;
ctx.fillText(“分数:+计算机分数,宽度-10,10);
}
};
this.IsCollision=函数(){
if(Ball.X-Ball.Radius>this.Width+this.X | | this.X>Ball.Radius*2+Ball.X-Ball.Radius)
返回false;
if(Ball.Y-Ball.Radius>this.Height+this.Y | | this.Y>Ball.Radius*2+Ball.Y-Ball.Radius)
返回false;
返回true;
};
};
window.requestAnimFrame=(函数(){
return window.requestAnimationFrame
||window.webkitRequestAnimationFrame
||window.mozRequestAnimationFrame
||window.oRequestAnimationFrame
||window.msRequestAnimationFrame
||函数(回调){return window.setTimeout(回调,FPS);};}
)();
window.cancelRequestAnimFrame=(函数(){
return window.cancelAnimationFrame
||window.webkitCancelRequestAnimationFrame
||window.mozCancelRequestAnimationFrame
||window.oCancelRequestAnimationFrame
||window.msCancelRequestAnimationFrame
||clearTimeout}
)();
//游戏
var Computer=新桨();
var Player=新桨(“左”);
//事件侦听器
函数MouseMove(e){
Player.Y=e.pageY-Player.Height/2;
}
//武官活动
addEventListener(“mousemove”,mousemove,true);
函数绘制(){
ctx.beginPath();
BG.Paint();
Computer.Paint();
Player.Paint();
Ball.Paint();
}
函数循环(){
init=requestAnimFrame(循环);
油漆();
if(Player.IsCollision()| | Computer.IsCollision()){
Ball.VelX=Ball.VelX*-1;
Ball.VelX+=(Ball.VelX>0?0.5:-0.5);
if(数学绝对值(球体高度)>球体半径*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>高度)
Ball.VelY=Ball.VelY*-1;
if(球X-球半径宽度){
Player.Score++;
Ball.Reset();
}
如果(计算机分数===10)
GameOver(假);
否则如果(Player.Score==10)
GameOver(真);
Computer.Y=(Computer.Y+Computer.Height/2
我试图简单地删除BG变量,但它只是做了同样的事情


更新:我还尝试了使用和不使用ctx.closePath,但都没有成功。

这是因为您没有在每帧的开头清除画布。对于纯色背景,这并不重要,但对于透明背景,您必须做到:

ctx.clearRect(0,0,canvas.width,canvas.height);

你需要在每次画图时清除画布。画布保留在其上绘制的内容


无论如何,拥有一块透明的画布不是一个好主意。透明度使事情变得更慢,因为每次在画布上绘制任何东西时都必须重新计算透明度。尝试使用图像绘制功能将图像绘制到其中。您可能会发现它可以使用GPU进行图像合成。

您似乎从未调用过
ctx.closePath
,这可能会导致问题。@david感谢您的评论。我只是尝试了一下,但没有成功。那没关系,除非你尝试划过路径。对于
填充
,它会自动关闭。我知道这很简单。。。谢谢,我觉得有点傻。