簡體   English   中英

在HTML 5 Canvas上繪制靜態背景

[英]Drawing static background on HTML 5 Canvas

剛剛編輯了我的問題,使其更清晰,更明顯。

我正在為游戲創建背景,並且我希望背景保持在與我在背景上方繪制的對象(玩家對象除外)相同的相對位置,就像FPS游戲一樣,只是我的游戲是2D。 我很確定這已經完成了1000次,但是我不知道在哪里找到解決方案。

我的游戲旨在始終將角色放在屏幕中心,並在背景的其他部分繪制其他對象。

假設我的背景如下所述9幀一樣大,一幀就是我的瀏覽器屏幕的確切大小。

在此處輸入圖片說明

現在,如果我的角色從第1幀轉到第9幀,我的角色將始終停留在中心位置,即大約(frame.width / 2,frame.height / 2),因為我的角色將具有某種形狀。 因此,屏幕現在將顯示幀“ 9”,而不是幀“ 1”。 在移動過程中,我將能夠看到其他對象從角色“移開”。

我使用Map類繪制背景,其render()方法如下:

var drawBackground = function (callback) {      
  callback(this);
}

image.onload = drawBackground(() => {
  var pattern = this.ctx.createPattern(image, 'repeat');
  this.ctx.fillStyle = pattern;
  this.ctx.fillRect(0, 0, this.paintWidth, this.paintHeight);
  // this.ctx.drawImage(image, 0, 0, 10000, 10000);

});
image.src = require('../media/bg.jpg');

現在我的代碼有問題。 因為我的背景(地圖)圖形總是在角色周圍重新繪制屏幕,​​所以我看到的效果就像背景與角色一起移動,而其他所有東西都位於同一位置。 這看起來不自然。 我希望背景和所有其他對象保持在同一位置。 他們不跟我的角色一起動。 我怎樣才能做到這一點?

我使用animate()函數顯示動畫。

function animate() {

  map.clear(); // clearRect

  ... Some code to track my character...

  map.render();

  character.render();

  requestAnimationFrame(animate);
}

animiate();

編輯:

有人建議我使用兩個畫布。 我實際上正在使用兩個畫布。

這是我在index.html文件中的設置:

<canvas id="background" style="z-index: 1;">You are viewing the Game Background Canvas -- Update your browser!</canvas>
<canvas id="canvas" style="z-index: 2;">...</canvas>

它們具有CSS樣式,如下所示:

#canvas, #background {position: absolute;left: 0px; top: 0px;}

我的背景使用“背景”畫布,我的角色使用“畫布”,但是我的其他對象也使用“背景”畫布,它們沒有隨我的角色移動,只有背景隨我的角色移動,這很奇怪。

要根據需要繪制背景,只需將要繪制的背景放置在-character.x, -character.y ,並假設這是字符位置的存儲位置。 要使用畫布圖案進行此操作,只需將畫布平移到該位置,然后在原點+角色的位置繪制圖案。

之所以需要如此多的擺弄是因為畫布模式的工作方式。 它們就像畫布的漸變; 填充的位置無關緊要,幾乎就像您使用的魔術文字一樣,可以顯示下面的隱藏顏色。 填滿位置100、100或200、200都沒關系; 模式始終從0,0開始。因此我們將0,0更改為負玩家位置,並在正玩家位置繪制。

image.onload = drawBackground(() => {
  var pattern = this.ctx.createPattern(image, 'repeat');
  this.ctx.fillStyle = pattern;
  this.ctx.save();
  this.ctx.translate(-character.x, -character.y);
  this.ctx.fillRect(character.x, character.y, this.paintWidth, this.paintHeight);
  this.ctx.restore();
});

根據OP的要求,我將嘗試更詳細地解釋此“魔術”。

畫布圖案是一種填充樣式,例如純色或畫布漸變。 將諸如fillRect之類的方法想像成是擦窗器,擦拭骯臟的窗戶以露出另一面。 使用畫布圖案時,另一面是重復平鋪的圖案。 現在,想象一下這種圖案構成了透過窗戶可見的牆壁牆紙。 (為簡化起見,假設牆壁快要接觸到窗戶了,所以您只能看到投射在牆壁上的窗戶擦拭部分的形狀。)假設您要擦拭干凈的隨機盒子形狀的窗戶揭示后面的圖案的一部分。 在左上角,您不一定會看到圖案圖塊之一的左上角。 您可能會看到中間。 或任何隨機位。 現在,假設我們希望圖塊的左上角位於從窗口擦除的盒子形狀的左上角。 我們將不得不更改牆紙開始平鋪的位置。 在畫布上,我們僅使用翻譯。 我們將畫布的原點(x = 0,y = 0)轉換為我們需要的原點(目前不相關),然后執行fillRect。 但是,然后fillRect將在該新原點執行。 我們不想要那個。 因此,我們將x和y設置為開始填充,與平移畫布的原點的數量相反。 然后,只需更改轉換畫布原點所依據的數量,就可以查看所需圖案的任何部分。

在本例中,我們將其轉換為字符x和y位置的否定形式。 (負值使背景以其他方式移動到角色。)然后,我們從角色的位置開始繪制圖案,因為-character.x + character.x = 0,並且我們想從左上角開始繪制屏幕的 在那里,您擁有了! 最后,我們只需要使用context.save和context.restore將畫布的原點更改回屏幕的左上角,即可得到最終結果!

使用兩個畫布一個用於角色,另一個用於移動背景,您可以使用絕對定位將它們放置在同一位置。

<div style="position: relative;">
  <canvas id="layer1" width="100" height="100" 
    style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
  <canvas id="layer2" width="100" height="100" 
    style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</div>

暫無
暫無

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

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