簡體   English   中英

HTML5 Canvas-用剪輯擦除新的圈子后重畫

[英]HTML5 Canvas - Redrawing new circles after erasing them with clip

我有一個獨特的問題。

我正在使用HTML5和Canvas創建蛇游戲

我有一個功能,可以在板上隨機生成蘋果,並在設置的一段時間后將其刪除。 為了刪除圓圈,您必須使用clip()函數,然后使用clearRect()

但是,使用裁剪功能后,將無法再繪制新的圓。

我發現的解決方案是使用ctx.save()ctx.restore() 但是,如果您玩游戲,您會發現當圓圈消失而新的圓圈出現時,蛇會發瘋。

我懷疑這與我使用保存和還原功能有關。

這是有問題的特定代碼

var width = canvas.width;
var height = canvas.height;
var applesArray = [];            // Store the coordinates generated randomly

// Generates a random coordinate within the confines of the canvas and pushes it to the apples array
function randCoord() {
    var coord = Math.floor(Math.random() * height);
    applesArray.push(coord);
    return coord;
}

function generateApples() {
    ctx.beginPath();
    ctx.fillStyle = "green";
    ctx.arc(randCoord(),randCoord(),3,0, 2 * Math.PI);
    ctx.fill();
    ctx.save();           // To redraw circles after clip, we must use save
    ctx.clip();           // Allows only the circle region to be erased
    setTimeout(function() {
        ctx.clearRect(0, 0, width, height);
    },3000);
    ctx.restore();       // We must restore the previous state.
}

setInterval(function() {
    generateApples();
},4000);

你可以在這里玩游戲

https://jsfiddle.net/2q1svfod/9/

誰能解釋這種奇怪的行為? 我沒看到它來嗎?

該代碼有多個問題。

繪制蛇的代碼(例如upArrow函數)只是擴展了當前路徑。 這是一個問題,因為繪制蘋果的代碼開始了新的路徑。 請注意,在Apple繪圖代碼中進行保存/恢復無濟於事,因為路徑不是保存/恢復的狀態的一部分。 繪制蛇的代碼將需要開始新的路徑。 例如...

function upArrow() {
    if (direction == "up") {
        goUp = setInterval(function() {
            ctx.beginPath();
            ctx.moveTo(headX, headY);
            ctx.lineTo(headX, headY - 10);
            ctx.stroke();
            headY -= 10;
        }, 400);
    }
}

保存/剪切/還原調用在繪制蘋果的代碼中。 這些方法需要移到超時回調函數中,以清除蘋果。 另外,擦除蘋果的代碼將需要重新創建路徑(因為蛇圖可能已經更改了繪制蘋果與擦除蘋果之間的路徑)。 例如...

function generateApples() {
    var cx = randCoord();
    var cy = randCoord();
    ctx.beginPath();
    ctx.fillStyle = "green";
    ctx.arc(cx, cy,3,0, 2 * Math.PI);
    ctx.fill();
    setTimeout(function() {
        ctx.beginPath();
        ctx.arc(cx,cy,3,0, 2 * Math.PI);
        ctx.save();
        ctx.clip();
            ctx.clearRect(0, 0, width, height);
        ctx.restore();
    },40000);
}

這些更改將使您接近預期的目標。 但是,仍然會有一些小問題。

繪制蘋果時,在蘋果路徑的邊緣會出現一些抗鋸齒現象。 清除操作可能會錯過清除其中一些像素的操作。 清除操作后,您可能會看到蘋果所在位置的半透明輪廓。 您可以通過清除蘋果時使用稍大的圓半徑來解決此問題。

另一個問題是,蘋果可能會被吸引到蛇頂上。 擦掉蘋果也會擦掉蛇。 沒有解決此問題的簡便方法。 您將需要存儲蛇的所有坐標,然后重畫蛇的全部或部分。

從長遠來看,您可能需要考慮注釋中的建議,這些建議涉及重構邏輯以跟蹤所有對象並在每一幀重繪所有內容(或在每次更改后重繪所有內容)。

暫無
暫無

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

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