簡體   English   中英

透明色HTML5畫布

[英]Transparent Color HTML5 Canvas

我有一個簡單的Pong游戲,用一些Javascript和Canvas標簽制作。

我將canvas標簽的背景顏色設置為透明,因此div標簽的背景圖像可以顯示在畫布下。

問題是,當我將它設置為透明時,它不會正確地繪制球和撥片,就像我將背景設置為正常的十六進制顏色一樣。 它繪制了槳葉和球的路徑,屏幕最終改變了球的顏色。

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

我試過簡單地刪除BG var,但它只是做了同樣的事情。

更新:我也嘗試過使用和不使用ctx.closePath但沒有成功。

這是因為您不會在每個幀的開頭清除畫布。 有了純色背景這沒關系,但透明你必須這樣做:

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

你需要在每次抽獎時清除畫布。 Canvas保留已繪制的內容。

無論如何,擁有透明畫布並不是一個好主意。 透明度使事情變得更慢,因為每次向畫布繪制任何內容時都必須重新計算。 嘗試使用圖像繪制功能將圖像繪制到其中。 您可能會發現它可以使用GPU來執行圖像合成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM