动画版雪碧

这是从Sprite Animations:Vampire Kitty Lives开始的教程的延续。

那篇文章以承诺我们会有所改进而结束。

requestAnimFrame

setTimeout很好,并且在几乎所有浏览器中都能很好地工作,但是还有一个更好的方法requestAnimFrame。

requestAnimFrame基本上充当setTimeout ,但是浏览器知道您正在渲染帧,因此可以优化绘制周期,以及如何与其余页面重排交互。 它甚至会检测该选项卡是否可见,如果隐藏了该选项卡,则无需费心绘制该选项卡,从而节省了电池电量(是的,以60fps的速度循环播放网络游戏会消耗电池电量)。 在幕后,浏览器还获得了以其他他们没有告诉我们很多其他神秘方式进行优化的机会。 以我在较重的框架负载(尤其是数百个精灵)上的经验来看,性能可能会大大提高。 特别是在最近的浏览器版本中。

我要补充的一点是,在某些情况下, setTimeout性能将优于requestAnimFrame ,尤其是在移动设备上。 进行测试并根据设备配置您的应用。

在不同的浏览器中,使用requestAnimFrame的调用是不同的,因此检测到此问题的标准垫片( 感谢Paul Irish )是:

window.requestAnimFrame = (function(){return  window.requestAnimationFrame       ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame    ||window.oRequestAnimationFrame      ||window.msRequestAnimationFrame     ||function( callback ){window.setTimeout(callback, 1000 / 60);};
})();

如果没有requestAnimFrame支持,则还可以使用内置的旧setTimeout

然后,您需要修改update方法以重复发出请求:

function update() {requestAnimFrame(update);redraw();frame++;if (frame >= 6) frame = 0;
}

在实际执行渲染/更新之前调用requestAnimFrame往往会提供更一致的结果。

附带说明一下,当我第一次开始使用requestAnimFrame我一直在寻找如何计时,但找不到任何东西。 那是因为不是。 没有任何东西可以通过setTimeout来设置MS延迟,这意味着您实际上无法控制帧速率。 只需完成您的工作,然后让浏览器负责其余的工作即可。

需要注意的另一件事是,如果您在自己的闭包内部使用requestAnimFrame ,则需要进行本机包装来调用它,例如:

my.requestAnimFrame = (function () {var func = window.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||window.msRequestAnimationFrame ||function (callback, element){window.setTimeout(callback, 1000 / this.fps);};// apply to our window global to avoid illegal invocations (it's a native) return function (callback, element) {func.apply(window, [callback, element]);};
})();

基于时间的动画

接下来,我们需要解决可怜猫咪跑的速度。 现在,动画帧根据帧速率前进,它将在不同的设备上跳跃。 那很糟; 如果您同时移动角色和设置动画,则在不同的帧频下情况看起来会很奇怪且不一致。 您可以尝试控制帧速率,但最后基于真实定时的动画将提供更好的全面体验。

您还会发现,一般而言,游戏中的计时将适用于您所做的一切:射击速度,转弯速度,加速,跳跃,只要使用适当的计时,它们都会得到更好的处理。

为了以可控的速度推进小猫,我们需要跟踪经过了多少时间,然后根据分配给每个小猫的时间推进框架。 这个的基础是:

  1. 以每秒帧数为单位设置动画速度。 (msPerFrame)
  2. 在您循环游戏时,请计算自上一帧(增量)以来经过了多少时间。
  3. 如果已经过了足够的时间来向前移动动画帧,则前进帧并将累积增量设置为0。
  4. 如果没有足够的时间,请记住(累积)增量时间(acDelta)。

这是我们的代码中的代码:

var frame = 0;
var lastUpdateTime = 0;
var acDelta = 0;
var msPerFrame = 100;function update() {requestAnimFrame(update);var delta = Date.now() - lastUpdateTime;if (acDelta > msPerFrame){acDelta = 0;redraw();frame++;if (frame >= 6) frame = 0;} else{acDelta += delta;}lastUpdateTime = Date.now();
}

如果您将其加载起来,我们的小猫咪就会平静下来,以更快的速度运转。

缩放和旋转

您还可以使用2D画布在渲染图像时对图像执行各种操作,例如旋转和缩放。

例如,让我们通过将图像缩小一半来制作一些小猫。 您可以通过在绘制调用中添加ctx.scale(0.5, 0.5)来实现:

function redraw()
{ctx.fillStyle = '#000000';ctx.fillRect(0, 0, canvas.width, canvas.height);if (imageReady){ctx.save();ctx.scale(0.5,0.5);ctx.drawImage(img, frame*96, 0, 96, 54,canvas.width/2 - 48, canvas.height/2 - 48, 96, 54);ctx.restore();}
}

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

免费获得这本书

由于缩放比例在变化,因此您会注意到在缩放调用之前还添加了一个ctx.save() ,最后添加了一个ctx.restore()。 没有这个,规模化的呼声就会累积起来,可怜的小猫会很快萎靡不振(尝试一下,这很有趣)。

缩放也可以使用负值来反转图像。 如果将比例值从(0.5,0.5)更改为(-1,1),则猫图像将水平翻转,因此它将以相反的方向运行。 请注意,平移用于翻转起始X位置以抵消图像的反转。

function redraw() {ctx.fillStyle = '#000000';ctx.fillRect(0, 0, canvas.width, canvas.height);if (imageReady) {ctx.save();ctx.translate(img.width, 0);ctx.scale(-1, 1);ctx.drawImage(img, frame*96, 0, 96, 54,canvas.width/2 - 48, canvas.height/2 - 48, 96, 54);ctx.restore();}
}

您可以使用旋转进行(duh)旋转。 这是爬墙的小猫:

ctx.rotate( 270*Math.PI/180 );ctx.drawImage(img, frame*96, 0, 96, 54,-(canvas.width/2 - 48), (canvas.height/2 - 48), 96, 54);

在这种情况下,通过旋转上下文,坐标也将旋转,而不仅仅是图像,因此为此drawImage调用偏移量,方法是反转将绘制小猫的x位置。

这么有才华的小猫(虽然吸血鬼应该能够爬墙,对吗?)

缩放和旋转很酷。 伙计,我什么都可以做! 好吧,不是真的。 很棒,但是它也很慢,并且会对渲染性能产生巨大的影响。 在生产游戏中,还有另一个技巧可以解决此问题,以及您可能会遇到的许多其他渲染性能问题:预渲染。

预渲染

预渲染只是获取您在常规绘制周期中将要渲染的图像,然后进行组装或手动操作。 您只需执行一次昂贵的渲染操作,然后在常规绘制周期中绘制预渲染的结果。

在HTML5中,您需要在单独的不可见画布上绘制,然后代替绘制图像,而是在其位置绘制另一个画布。

这是一个将小猫预呈现为反转图像的函数示例。

var reverseCanvas = null;function prerender() {reverseCanvas = document.createElement('canvas');reverseCanvas.width = img.width;reverseCanvas.height = img.height;var rctx = reverseCanvas.getContext("2d");rctx.save();rctx.translate(img.width, 0);rctx.scale(-1, 1);rctx.drawImage(img, 0, 0);rctx.restore();
}

请注意,画布对象已创建,但未添加到DOM,因此不会显示。 将高度和宽度设置为原始的spritesheet,然后使用渲染缓冲区的2D上下文绘制原始图像。

要设置预渲染,您可以从已加载的函数中调用它。

function loaded() {imageReady = true;prerender();requestAnimFrame(update);
}

然后,当您进行常规重绘调用时,请使用reverseCanvas而不是原始的:

function redraw() {ctx.fillStyle = '#000000';ctx.fillRect(0, 0, canvas.width, canvas.height);if (imageReady) {ctx.save();ctx.drawImage(reverseCanvas, frame*96, 0, 96, 96, (canvas.width/2 - 48), (canvas.height/2 - 48), 96, 96);ctx.restore();}
}

不幸的是,当我们反转图像时,动画现在也向后播放,因此您还需要反转动画序列:

function update() {requestAnimFrame(update);var delta = Date.now() - lastUpdateTime;if (acDelta > msPerFrame) {acDelta = 0;redraw();frame--;if (frame < 0) frame = 5;} else {acDelta += delta;}lastUpdateTime = Date.now();
}

如果需要,可以通过将画布的来源设置为使用包含已编码图像数据的数据URL来将画布转换为图像。 Canvas有一种方法可以做到这一点,所以很简单:

newImage = new Image();newImage.src = reverseCanvas.toDataURL("image/png");

另一个不错的图像处理方法是使用实​​际的像素数据。 HTML5 canvas元素将图像数据公开为RGBA格式的像素数组。 您可以使用以下方法从上下文访问数据数组:

var imageData = ctx.getImageData(0, 0, width, height);

这将返回一个ImageData结构,其中包含宽度,高度和数据成员。 数据元素是我们需要的像素数组。

数据阵列由所有像素组成,每个像素由4个条目表示,红色,绿色,蓝色和alpha级别,范围从0到255。因此,图像宽512宽512高一个数组,其中包含1048576个元素– 512×512等于262,144像素,乘以每个像素4个条目。

使用此数据数组,这里有一个示例,其中增加了图像的特定红色分量,同时减少了红色和蓝色分量,从而创建了我们的2级怪物,hell-spawn-demon-kitty。

function prerender() {reverseCanvas = document.createElement('canvas');reverseCanvas.width = img.width;reverseCanvas.height = img.height;var rctx = reverseCanvas.getContext("2d");rctx.save();rctx.translate(img.width, 0);rctx.scale(-1, 1);rctx.drawImage(img, 0, 0);// modify the colorsvar imageData = rctx.getImageData(0, 0, reverseCanvas.width, reverseCanvas.height);for (var i=0, il = imageData.data.length; i < il; i+=4) {if (imageData.data[i] != 0) imageData.data[i] = imageData.data[i] + 100;    // redif (imageData.data[i+1] != 0) imageData.data[i+1] = imageData.data[i+1] - 50; // greenif (imageData.data[i+1] != 0) imageData.data[i+2] = imageData.data[i+2] - 50; // blue}rctx.putImageData(imageData, 0, 0);rctx.restore();
}

for循环以四步为单位遍历数据数组,每次修改三种原色。 第四个通道alpha保持不变,但是如果您愿意,可以使用它来更改某些像素的透明度。 (注意:在下面的JSFiddle示例中,我们对图像数据使用dataURL,特别是为了避免直接像素操作引起的跨域问题。您无需在自己的服务器上进行操作。)

这是我们的2级老板小猫:

由于使用像素阵列处理图像需要遍历所有元素(对于地狱猫来说,这是一百万次以上),因此您应该使事情保持最佳状态:尽可能进行预计算,不要创建变量/对象并跳过像素。

结论

画布绘制,缩放,旋转,平移和像素处理的结合,以及使用预渲染的性能选项,赋予了制作炫酷,动态游戏的多种能力。

例如,我最近在Playcraft的一款演示游戏中使用了这些技术,即2D 4向滚动空间射击游戏。 艺术家仅对每艘船(玩家和敌方战斗机)制作了一个框架,然后我将根据我们希望这些船旋转多少度(因此又有多光滑)来旋转和渲染。 我可以根据运行时的船只类型来调整角度的数量-默认情况下,玩家的船只渲染有36个转弯角度(非常平滑),而敌方和对手的船只仅以16个角度(波动)进行渲染。 我还添加了一个选项,使功能更强大的计算机上的玩家可以选择将平滑度角度全面提高到72(超级平滑)。 此外,我会根据您所在的团队为船上的标志和标记(机翼上凉爽的大条纹)动态重新着色。 这再次节省了渲染和资源,但是还允许根据用户选择的团队颜色动态调整船的颜色。

有关您可以使用画布做什么的更多信息,请查看Canvas Element API 。

本文最初出现在BuildNewGames.com上 ,该网站是Bocoup和Internet Explorer团队的合作。

翻译自: https://www.sitepoint.com/sprite-animations-boss-kitty/

动画版雪碧

动画版雪碧_雪碧动画:老板凯蒂相关推荐

  1. 动画版雪碧_雪碧动画:吸血鬼凯蒂的生活

    动画版雪碧 我一直很喜欢网页游戏: 它们只是制作有趣,易于编码(大多数情况下),并且当用户只需要单击一个链接即可开始玩游戏时,游戏的可访问性就非常不错. Ajax和移动的dom元素带来了一些乐趣,但是 ...

  2. gif透明背景动画_火柴人动画制作软件下载_火柴人动画制作软件最新电脑版下载...

          火柴人动画制作软件官方版(Pivot Stickfigures Animator)是一款完全免费的火柴人动画制作软件.如果您不具备Flash等专业动画软件制作技能,那么可使用火柴人动画制作 ...

  3. 画火柴人动画的手机软件_火柴人动画制作软件(Pivot Stickfigure Animator)2.25 中文版附教程...

    火柴人游戏一直深受广大玩家喜爱,有没有人想过火柴人动画是怎么制作出来的呢?今天小编就为大家带来一款火柴人动画制作软件Pivot Stickfigures Animator,它可以帮你快速而简单的制作出 ...

  4. 动画版《三体》启动制作,2021 年真能上映么?

    By 超神经 场景描述:近日,<三体>动画版的正式预告在 B 站放出,并宣布最终成片将于 2021 年推出,短短 3 分钟的视频吸引了数百万人的目光.这一次,我们要等多久能看到<三体 ...

  5. wpsppt页面卷曲在哪里_2013版ppt怎么制作页面卷曲动画效果_博客

    2013 版 ppt 怎么制作页面卷曲动画效果 _ 博客 2013 版 ppt 怎么制作页面卷曲动画效果 在制作幻灯片的时候会用到不少切换动画效果, 但是怎么才能实现 ? 对于不常用 ppt 的朋友或 ...

  6. 打印杨辉三角形知识点_高中数学知识点:杨辉三角问题解法(动画版)

    高中数学知识点:杨辉三角问题解法 ( 动画版 ) 在高中数学知识点中,杨辉三角,又称贾宪三角形,帕斯卡三角形, 是二项式系数在三角形中的一种几何排列.在欧洲,这个表叫做帕斯卡三角 形.下面让我们更深入 ...

  7. h5可以获取本机手机号码么_三体动画版要来了!看完新版H5,我是真坐不住了!...

    这是H5资讯站的第:930篇更新-最近,我在朋友圈看到了不少人转发关于<三体>的新内容.打开一看,原来是<三体>要出动画了,这个消息还真挺让人兴奋的. B站也为此,也专门做了H ...

  8. html5动画怎么做成gif,一种网页版的调用html5视频录制动画GIF图像的方法与流程...

    本发明涉及WEB开发与应用技术领域,特别涉及一种网页版的调用html5视频录制动画GIF图像的方法. 背景技术: GIF 格式指的是图像交换格式(Graphics Interchange Format ...

  9. gif动画修改_如何更改动画GIF速度

    gif动画修改 Comedians would tell you that timing is the most important part of any joke. The same could ...

最新文章

  1. 北大博士整理B站实战项目!yyds!
  2. 让UpdatePanel支持文件上传(2):服务器端组件
  3. ecshop数据表结构说明
  4. 怎么能打开AOPR的日志文件
  5. RabbitMQ -- Hello world
  6. 从linux内核启动,学习Linux内核启动过程:从start_kernel到init
  7. (转) PowerDesigner中Table视图同时显示Code和Name
  8. flex布局 - justify-content: space-evenly
  9. 阿里健康上线新冠核酸检测服务:本周覆盖北京武汉等38城
  10. 云存储之对象存储性价比小谈
  11. mysq;多表查询 总结
  12. endnote导入参考文献及国标(Chinese standard)
  13. IT界的悲哀--做互联网,就要跳出互联网
  14. html5音乐播放器格式midi,html5音频标签是否非正式地包含.mid(MIDI)?
  15. win7 计算机 局域网共享,win7局域网一键共享工具(教程)
  16. linux下安装mysql5.7.11全纪录_记一次linux下安装mysql5.7
  17. fastq质量值_fastq碱基质量值转化
  18. 联通家庭宽带光猫DDNS设置
  19. 超详细解决 Tomcat环境变量没问题还是闪退问题
  20. QCon北京2019大会定制书单(内有赠书福利)

热门文章

  1. 苹果最新系统ios7_手机资讯:你绝对不知道的iOS7隐藏功能
  2. c#桌面程序在DataGridview中增加日期类型的列的方法。
  3. 小强与小明的故事-正在疯传的伟大故事
  4. 0基础编程学python_编程零基础应当如何开始学习 Python?
  5. 8.31前端 jQuery
  6. Blender下载安装
  7. linux sysctl机制,Linux操作系统sysctl机制的思想与实现
  8. 秒级加速质变,Apache Doris与360数科的“化学反应”
  9. 正能量系列 女性程序员篇
  10. 数据库课程设计--人事管理系统代码