javascript - Javascript canvas animate sprite walking
问题描述
I am trying to get a sprite to walk over a background image with canvas. Ideally, I would do this all on one canvas, but using two seems to be more efficient and easier.
What I have so far:
and
Code from fiddle 1, working on the simplest form of the animation:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var spritePosition = 0;
var spriteWidth = 50;
var spriteHeight = 225;
var spriteCount = 17;
var spritePlayCount = 0;
var maxSpritePlays = 3;
var sheet = new Image();
sheet.onload = function () {
animate();
}
sheet.src = "https://s33.postimg.cc/dapcxzmvj/sprite_walk.png";
var fps = 15;
function animate() {
setTimeout(function () {
if (spritePlayCount < maxSpritePlays) {
requestAnimationFrame(animate);
}
// Drawing code goes here
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(sheet,
spritePosition * spriteWidth, 0, spriteWidth, spriteHeight,
0, 0, spriteWidth, spriteHeight);
spritePosition++;
if (spritePosition > spriteCount - 1) {
spritePosition = 0;
spritePlayCount++;
}
}, 1000 / fps);
}
I want to be able to get this to walk correctly, and understand how it works. I see both use something along the lines of sprite.width
and sprite.height
, which I figured would be width/columns
and height/rows
but those dont seem to work properly.
解决方案
你的坐标全错了。您的spriteWidth和 spriteHeight 值与 spritesheet 的所有值都不匹配。
此外,您的逻辑仅更新 x 轴,而您的精灵表设置在多行上。
您需要更新此逻辑,以便更新 x 和 y 源位置。
最后,不要像这样混合 setTimeout 和 requestAnimationFrame 。他们永远不会相处融洽。要达到 15FPS,您可以很容易地运行 requestAnimationFrame 循环,该循环将以 60FPS 触发,并且只需每四帧绘制一次(60FPS / 4 => 15FPS)。
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var xIndex = 0;
var yIndex = 0;
var cols = 5;
var rows = 4;
var spriteWidth = 265;
var spriteHeight = 200;
var sheet = new Image();
sheet.onload = function() {
animate();
}
sheet.src = "https://i.stack.imgur.com/eL5yV.png";
var frame = 0;
function animate() {
requestAnimationFrame(animate);
// 60FPS / 4 => 15FPS
if ((++frame) % 4 > 0) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
// update the current column
xIndex = (xIndex + 1) % cols;
// update the current row if x is 0
yIndex = xIndex === 0 ? (yIndex + 1) % rows : yIndex;
// three cells are empty on the last row...
if (yIndex === (rows - 1) && xIndex === 2)
xIndex = yIndex = 0;
// update both sourceX and sourceY
ctx.drawImage(sheet,
xIndex * spriteWidth, yIndex * spriteHeight, spriteWidth, spriteHeight,
0, 0, spriteWidth, spriteHeight);
}
<canvas id="canvas" width=350 height=350></canvas>
推荐阅读
- data-structures - 查找在树中定位数字的可能路线
- excel - VBA刷新受保护页面上的查询数据,单步执行时工作,自动运行失败
- http-post - “Promise”类型上不存在属性“id”
' - amazon-web-services - 如何从 serverless.yml 中的多个 yml 文件中加入或合并 provider.patterns 数组,以及如何在预定事件上设置启用标志
- python - python - 如何通过python aiogram中的机器人在同步函数中发送消息?
- azure-functions - 设置设置 SCM_DO_BUILD_DURING_DEPLOYMENT=true 后,我得到 write failed No space left on device (28) 错误
- quantization - Lloyd max 算法的零概率条件对连续情况有何意义?
- python - 合并熊猫数据框,合并非关键的同一列
- php - 目标类控制器在本地主机中不存在 Laravel 8 一切正常但不在线
- linux - 过去的网络连接是否存储在某处?