繁体   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