TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Making Sprite-based Games with Canvas

101 pointsby jlongsterabout 12 years ago

9 comments

Mahnabout 12 years ago
One thing not mentioned in the article: you <i>don't</i> have to render everything on a single canvas, you can use multiple canvases as layers. This is specially useful to separate what is updated often with what changes rarely, for instance the characters layer, the background layer and the HUD layer can potentially have very different update rates, so it makes sense to redraw them at a different pace each. In fact, you can also get creative and combine DOM elements with canvases.<p>These tricks matter because redrawing the entire screen every frame is usually an expensive operation; this is not noticable on small examples but it can become an issue on larger, more complex games.<p>Great article otherwise.
评论 #5402799 未加载
评论 #5404559 未加载
jereabout 12 years ago
Just dealt with some of these issues last week in 7drl.<p>&#62;image-rendering: optimizeSpeed;<p>In some cases, you will want to scale the images drawn to the canvas, but not the canvas itself. This causes a lot of headache because of image smoothing and is not resolved by the above CSS. The answer is to set the image smoothing property of the canvas context to false. For example:<p>ctx.mozImageSmoothingEnabled = false;<p>ctx.webkitImageSmoothingEnabled = false;<p>Worked great on Chrome and Firefox. For some reason, though, this does not appear to work in Safari. I'm still amazed that something so simple is so hard to accomplish across browsers (after all you're asking to <i>turn off</i> extra, slower functionality). A good article on the intricacies: <a href="http://phoboslab.org/log/2012/09/drawing-pixels-is-hard" rel="nofollow">http://phoboslab.org/log/2012/09/drawing-pixels-is-hard</a>
评论 #5402792 未加载
Lercabout 12 years ago
There is a pitfall with the approach of update loop using variable time steps. Depending on the game type this can matter quite a great deal. Essentially it is analogous to an iterated solution of the three body problem. 50 tiny steps produces a different result to 10 big steps.<p>There was a Google contraption editing game(a Google IO demo?) that suffered from this approach quite badly. It was a set-up-and-go game which should perform deterministically, but was influenced by variations in frame-rate.<p>The easiest approach to fixing this is simply quantised time.<p><pre><code> var now = Date.now(); while(gameAge &#60; now) { update(); gameAge+=stepDuration; } render(); //with usual caveats of resyncing if now-gameAge is too large </code></pre> The much harder (but possibly ideal) approach is to not even have such a time step at all and move in variable increments calculated at the point of interaction between entities. An example of this would be a snooker simulation which moves in steps when the balls make contact. Balls slowing, rolling and curving become calculus problems. Produces a very nice result but your brain explodes.
评论 #5408315 未加载
city41about 12 years ago
This is a great article, but if you're really going to make a canvas game then you're much better off using a game engine. I recommend MelonJS[1] or Impact[2] if you don't mind the cost. I also have a side project that compares JavaScript game engines in much the same way TodoMVC compares MV* frameworks: <a href="http://city41.github.com/breakouts" rel="nofollow">http://city41.github.com/breakouts</a><p>[1]<a href="http://www.melonjs.org" rel="nofollow">http://www.melonjs.org</a> [2]<a href="http://www.impactjs.com" rel="nofollow">http://www.impactjs.com</a>
评论 #5405165 未加载
nollidgeabout 12 years ago
Much more useful than the Udacity HTML5 games class, which bizarrely dives into the bookkeeping minutia of looking up sprites in a collection of spritesheets for an entire unit (edit: unit of the class, I mean)
angersockabout 12 years ago
Minor nitpick. The bullet update code is a bit wordy:<p><pre><code> bullets.push({ pos: [x, y], dir: 'forward', sprite: new Sprite('img/sprites.png', [0, 39], [18, 8]) }); </code></pre> and<p><pre><code> var bullet = bullets[i]; switch(bullet.dir) { case 'up': bullet.pos[1] -= bulletSpeed * dt; break; case 'down': bullet.pos[1] += bulletSpeed * dt; break; default: bullet.pos[0] += bulletSpeed * dt; } </code></pre> You could consider simply adding a velocity to the bullet at spawn time like so:<p><pre><code> bullets.push({ pos: [x, y], dir: [0,10], sprite: new Sprite('img/sprites.png', [0, 39], [18, 8]) }); </code></pre> and then in the update code replace the switch stuff with:<p><pre><code> bullet.pos[0] += bullet.dir[0] * dt; bullet.pos[1] += bullet.dir[1] * dt; </code></pre> That should eliminate branching and make the interpreter much happier.<p>Additionally, by making the speed/velocity a member of the bullet instance, you can do things like have bullets that slow down or speed up if they have a think method or something, or that do homing (for this, look up dot-products and cross-products for steering).
lucaspillerabout 12 years ago
Thanks this is a good article. I've been looking at HTML5 for game development recently for 1GAM [1]. One of the things that has really annoyed me is there does not seem to be any kind of standard way of structuring games. Is there anything like MVC for games?<p>[1] <a href="http://www.onegameamonth.com/" rel="nofollow">http://www.onegameamonth.com/</a>
SeanDavabout 12 years ago
I have very little knowledge in this domain, but why do so few of these demos ever have sound? Is there something lacking with canvas and sound/music?
评论 #5402725 未加载
评论 #5402732 未加载
评论 #5402782 未加载
评论 #5402879 未加载
bobwaycottabout 12 years ago
Nicely done, James. Well written for getting beginners comfortable working with canvas.