简体   繁体   English

透明色HTML5画布

[英]Transparent Color HTML5 Canvas

I have a simple Pong game made with some Javascript and a Canvas tag. 我有一个简单的Pong游戏,用一些Javascript和Canvas标签制作。

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. 我将canvas标签的背景颜色设置为透明,因此div标签的背景图像可以显示在画布下。

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: 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();

I tried simply removing the BG var but it just did the same thing. 我试过简单地删除BG var,但它只是做了同样的事情。

Update: I also tried with and without ctx.closePath with no success. 更新:我也尝试过使用和不使用ctx.closePath但没有成功。

This 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. Canvas保留已绘制的内容。

Having a transparent canvas isn't a good idea anyway. 无论如何,拥有透明画布并不是一个好主意。 Transparency makes things slower as it has to be recomputed 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 composition. 您可能会发现它可以使用GPU来执行图像合成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM