[英]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.