javascript - Html5画布动画留下痕迹
问题描述
我正在尝试制作一个小游戏来玩画布。我决定选择Flappy Bird,因为网上有很多例子。我的目标是让游戏对所有设备都“响应”。如果您在手机或任何屏幕中打开它,您应该可以正常播放它。
为此,我在画布中绘制了一个背景图像,它将使高度适应屏幕的高度,并通过 x 轴重复它。
我遇到的问题是,当我为这只鸟设置动画时,它会在它身后留下一条痕迹。
就像这样:
如本文所述,一个简单的解决方法是清除画布:
但这是不可能的,因为我画背景的方式(我画了一次,如果调整大小就重新画)。
问题
如何避免这种带有静态背景的图像轨迹?是否有可能拥有不需要重新绘制的虚假静态背景?
我显然想在画布上做,而不需要在 html 中有图像。
这是具有主要功能的代码,您可以看一下:
const cvs = document.getElementById("canvas");
const ctx = cvs.getContext("2d");
cvs.style.height = "100vh";
cvs.style.width = "100vw";
var bird = new Image();
var bg = new Image();
bird.src = "https://lh3.googleusercontent.com/prntPuix7QxlhKXx6IBtTxv7PrdEJtmzFJ4mopScNS1_klze86BVNy3PqHbQn2UQ4JyJdix3XQ=w128-h128-e365";
bg.src = "https://opengameart.org/sites/default/files/bg_5.png";
let gravity = 1;
birdPositionY = 10;
birdPositionX = 50;
const draw = () => {
ctx.drawImage(bird, birdPositionX, birdPositionY);
birdPositionY += gravity;
birdPositionX += 3;
requestAnimationFrame(draw);
};
const resizeCanvas = () => {
const {
width,
height
} = cvs.getBoundingClientRect();
cvs.height = height;
cvs.width = width;
let x = 0,
y = 0;
while (x < cvs.width && y < cvs.height) {
ctx.drawImage(bg, x, y, 360, cvs.height);
x += bg.width;
}
};
bg.onload = () => {
resizeCanvas();
};
window.addEventListener("resize", resizeCanvas, false);
draw();
<!DOCTYPE html>
<html>
<head>
<title>Flappy Bird</title>
<meta name="viewport" content="width=device-width, user-scalable=no" />
<style>
html {
overflow: hidden;
}
body {
margin: 0;
}
canvas {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="index.js"></script>
</body>
</html>
希望它确实有意义!
提前致谢!
解决方案
在您将保持在屏幕外的画布上绘制背景,然后在绘制移动部件之前在可见帧上绘制每一帧。
const cvs = document.getElementById("canvas");
const ctx = cvs.getContext("2d");
// our backround canvas that we won't append in the doc ("off-screen")
const background = cvs.cloneNode();
const bg_ctx = background.getContext('2d');
cvs.style.height = "100vh";
cvs.style.width = "100vw";
var bird = new Image();
var bg = new Image();
bird.src = "https://lh3.googleusercontent.com/prntPuix7QxlhKXx6IBtTxv7PrdEJtmzFJ4mopScNS1_klze86BVNy3PqHbQn2UQ4JyJdix3XQ=w128-h128-e365";
bg.src = "https://opengameart.org/sites/default/files/bg_5.png";
let gravity = 1;
birdPositionY = 10;
birdPositionX = 50;
const draw = () => {
// first draw the background canvas
ctx.drawImage(background, 0,0);
// then your persona
ctx.drawImage(bird, birdPositionX, birdPositionY);
birdPositionY += gravity;
birdPositionX += 3;
requestAnimationFrame(draw);
};
const resizeCanvas = () => {
const {
width,
height
} = cvs.getBoundingClientRect();
// resize both canvases
cvs.height = background.height = height;
cvs.width = background.width = width;
let x = 0,
y = 0;
while (x < cvs.width && y < cvs.height) {
// draw on the off-screen canvas
bg_ctx.drawImage(bg, x, y, 360, cvs.height);
x += bg.width;
}
};
bg.onload = () => {
resizeCanvas();
draw();
};
window.addEventListener("resize", resizeCanvas, false);
<!DOCTYPE html>
<html>
<head>
<title>Flappy Bird</title>
<meta name="viewport" content="width=device-width, user-scalable=no" />
<style>
html {
overflow: hidden;
}
body {
margin: 0;
}
canvas {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="index.js"></script>
</body>
</html>
推荐阅读
- python-3.x - 占位符的自动格式化
- php - 插入到 mysql 数据库准备状态
- java - Java:尝试获取 HTML 元素的值
- c# - 通过索引号 wpf mvvm 在 listview itemsource 中搜索值
- angular - 尝试安装 @ngx-progressbar/core 时未满足的依赖项
- php - 基于 Wordpress 中活动类别的当前帖子的 PHP 滑块
- javascript - 计算 Qualtrics 中的 TAB 击键
- javascript - HTML 表单提交按钮刷新页面
- java - Java void 作为带参数的 Runnable
- swift - swift - 字符串的通知标题