将场景分成几块画布还是继续重绘一张?
打算用 javascript 创建一个基于画布的游戏,我面临一个选择:
我是否应该在性能方面将屏幕上发生的所有内容保留在一个画布中(所有移动的角色、精灵)并以恒定的速率重新绘制它,例如, 60 FPS 还是我应该将场景分成几个较小的画布,从而消除场景的冗余重绘?我什至可以为角色的四肢创建单独的画布元素,然后通过简单地操作给定画布元素的 CSS(旋转、定位、不透明度)来完成大部分动画。
对我来说,后者听起来更合理、更容易实现,但它也更快吗?另外,我是否应该使用 SVG,将字符和精灵保留为其中的元素并直接操作它们的 XML 和 CSS 属性?
那么,对于具有多个精灵和角色的场景,您认为最合适的解决方案是什么:
- 以 FPS 速率手动(且浪费地)重绘一个画布对象
- 多个画布元素,以更合理的方式手动重绘
- 结构化矢量图形文档,如 SVG / VML通过 DOM 操作
我主要关心性能差异,但背后逻辑代码的易读性也很有趣(我之前已经使用过画布,例如,我相当确定整个画布的重绘函数将是一个难以维护的脚本野兽)。
Intent on creating a canvas-based game in javascript I stand before a choice:
Should I performance-wise keep all the stuff happening in the screen in one canvas (all the moving characters, sprites) and redraw it at constant rate of, say, 60 FPS or should I break the scene into several smaller canvases thus removing the need of redundant redrawing of the scene? I could even create separate canvas elements for the characters' limbs and then do most of the animation by simply manipulating the CSS of the given canvas element (rotation, positioning, opacity).
To me the latter sounds way more plausible and easier to implement, but is it also faster? Also, shouldn't I perhaps use SVG, keep the characters and sprites as elements inside of it and manipulate their XML and CSS properties directly?
So what do you think is the most fitting solution to a scene with severals sprites and characters:
- One canvas object redrawn manually (and wastefully) at FPS rate
- Several canvas elements, redrawn manually in a more reasonable fashion
- Structured vector graphics document like SVG / VML manipulated via DOM
I am mainly concerned about the performance differences, but the legibility of the logical code behind is also of interest (I, having already worked with canvas before, am for example fairly sure that the redrawing function for the entire canvas would be one hard-to-maintain beast of a script).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
与 GPU 加速的画布操作相比,DOM 操作速度较慢,因此我会远离 SVG 和 VML。
就构建画布代码而言,由于玩家移动或执行了某个操作而清除并重新绘制整个画布当然没有意义(特别是出于性能原因)。根据您的描述,我猜测您的游戏将是 2D 的。这些类型的游戏非常适合分层,除非您正在做一些相当复杂的游戏,例如《纸片马里奥》。您应该从面向对象的角度看待问题,并适当地将绘图过程和对象封装在一起。
例如,创建一个玩家对象,该对象维护一个代表角色的小画布。维持角色状态所需的所有逻辑都保存在对象内,对其所做的任何更改都无需担心游戏视觉表示的其他组件。同样,对背景、用户界面以及任何其他可以抽象到层中的内容(在合理范围内)执行相同的操作。例如,如果您正在制作视差游戏,则可能有
前景
、背景
、角色
和用户界面< /代码>层。
最终,您需要单独维护游戏中不同组件的状态。玩家动画、背景云朵移动、树木摇曳等都将由适当的对象来管理。由于您已经拥有这种类型的代码结构设置,因此只需在单独的画布元素上维护主要组件并根据需要将它们组合在一起以获得更好的性能是有意义的。如果角色在具有静态背景的场景的左下角移动,则无需重新绘制右上角(或场景的 95%)。如果您正在考虑全屏功能,这绝对是一个性能问题。
DOM manipulations are slow in comparison to GPU-accelerated canvas operations, so I would stay away from SVG and VML.
As far as structuring your canvas code goes, it certainly doesn't make sense (especially for performance reasons) to clear and re-draw the entire canvas because the player moved or performed an action. Based on your description here, I'm guessing that your game will be 2D. These types of games lend themselves extremely well to layering unless you're doing something rather complex like Paper Mario. You should be looking at the issue from an object-oriented viewpoint and encapsulating your drawing procedures and objects together as appropriate.
For instance, create a player object that maintains a small canvas representing the character. All the logic needed to maintain the character's state is kept within the object and any changes made to it need not worry about other components of the game's visual representation. Likewise, do the same for the background, user interface, and anything else you can abstract into a layer (within reason). For example, if you're doing a parallax game, you might have a
foreground
,background
,character
, anduser interface
layer.Ultimately you will need to maintain the state of the different components in your game individually. Player animations, background clouds moving, trees swaying, etc. will all be managed by appropriate objects. Since you will already have that type of code structure setup, it makes sense to just maintain major components on separate canvas elements and composite them together as needed for better performance. If the character moves in the bottom left corner of a scene with a static background, you don't need to re-draw the top right corner (or 95% of the scene, for that matter). If you're considering full-screen capabilities, this is definitely a performance concern.
编程中有一条规则,在遇到速度问题之前,永远不要尝试优化某些东西。你会花更多的时间试图弄清楚如何以最好的方式编码,而不是实际编码,而且永远不会完成任何事情。
以固定的速率将它们全部绘制在画布上。就是这样完成的。如果您开始为每个肢体和元素创建画布并使用 CSS 操作它们,那么您就是在浪费画布的潜力。不妨只使用图像。在画布出现之前他们就是这样做的。这就是画布旨在解决的问题。
如果您遇到速度问题,那么您可以开始解决它们。 查看这些幻灯片了解一些提示 (相关视频)。 这个人的博客也有一些关于画布性能的实用技巧。
There's a rule in programming, that you should never try and optimize something before you have a speed problem with it. You'll spend more time trying to figure out how to code something in the best way than to actually code, and will never finish anything.
Draw them all on your canvas at a fixed rate. That's how it's done. If you start creating a canvas for each limb and element and manipulate them using CSS, you're wasting the potential of canvas. Might as well just use images. That's how they did it before canvas. That's the problem canvas was made to solve.
If you ever encounter speed issues, then you can start hammering at them. Check out these slides for some tips (related video). This guy's blog also has some handy tips on canvas performance.