Wednesday, December 4, 2013

Cage Match! CSS vs Canvas vs SVG (Game Programming)

As promised, here are my opinions on which graphics technologies to use for Firefox OS game programming. Of course, with any technology, you can make anything do almost anything if you work at it long enough. But each of the three are great and have their places. But they might seem to be fighting for your attention and against each other.


On the left is CSS, in the middle is Canvas, and over there on the right is SVG. For this comparison, I'll list specific categories of game programming and how each seems to be pro or con. Your mileage may vary and please let me know if I've missed something.


Performance
All three run pretty fast in today's browsers. If you compare the bouncing ball examples (CSS, Canvas, and SVG), they are all pretty fast. When I first started working on these, I was surprised at how fast they all are, but I shouldn't have been, because all the major browsers (even IE) are now tuning graphics for high performance.

CSS: browsers have been doing CSS forever, so they know how to do it and a lot of CSS is heavily optimized because everybody is using it (though not for animation). There are some new animation techniques that fit under the name of CSS3, but I'm not looking at newer things, only stuff that has been around a long time. If you ask CSS to move something, it does it instantly.

Canvas: slow at first, all browsers now try to add hardware acceleration to Canvas drawing and you'll find that most HTML5 games use Canvas because it works. Redrawing the screen using requestAnimationFrame really speeds up one of the big problems of Canvas, which is moving and erasing where you were (cleaning up after yourself). Still, some operations can be slow if you're doing a lot of pixel manipulation.

SVG: fast if you use the SVG object model directly and bypass the HTML DOM. You're working directly with the SVG engine and all browsers (thanks, IE) are now tuning SVG as it catches on. I think some parts of webkit are still running behind, but I'm sure they are trying. SVG also just seems fast, because you just make a tweak and the objects respond.

Ease of Programming
None of these are easy. Life is short and animation is hard. In terms of ease of programming, I chose the order of these three when I started this blog based on CSS being easy, Canvas taking more skill, and SVG requiring the most skill. In terms of computer languages, I'd rate it this way:

     CSS is similar to BASIC
     Canvas is similar to JavaScript and C#
     SVG is more like C/C++

CSS: the easiest is to use because you just slap bitmaps around. If you're a web monkey, you know what CSS is all about and by using simple JavaScript, you can move things easily enough. You can get something working and know it will work in just about any browser that's still around. Maybe even IE 6. Not particularly well documented as a game programming technique, but it can be used. It would make a nice beginning programming tool for web designers.

Canvas: there are tons of books and articles on HTML5 game programming with Canvas. It works and requires specific techniques. You can't go wrong with this. It reminds me of programming 8-bit computers long ago, where you have to clean up after yourself and be very aware of where every pixel goes. The biggest limitation is that once you spray those pixels on the canvas, you're done. You can't easily move them or keep track of them. Very similar to artistic canvases, in that once you lay down your paint, you can only try to cover it up with more paint and hope for the best.

SVG: This isn't well documented anywhere. Mozilla Developer Network has good documentation on the basic object model but doesn't have many (or any?) examples. There are a few. And it makes it more confusing that there are three different ways to program SVG in a web page now that HTML5 supports the joining of SVG to HTML5 at the hip. But if you learn some simple rules and look up things in the SVG specification, you can figure your way around it. But it has real advantages in terms of keeping track of all your objects, collision detection, etc. You can do more with SVG than the other two, and all of it is fast.

Ease of Art Resources
You have to create the art yourself, one way or the other. Each of the three uses art in different ways.

CSS: uses plain old pixel art. Make a drawing in Photoshop, export it as a PNG, and you're done. There are a zillion different pixel art programs. And there are a zillion artists out there that are really good. Check out deviant art!

Canvas: is an alien/human hybrid. It can use pixel art straight out of Photoshop (or a zillion others) and that's all most people will ever do. However, the alien part is that it can draw shapes on command. Want a box? It can draw it. Want a circle? You can, if you know a circle is just a complete arc. You can design all the twists and turns of the shapes yourself on graph paper, but you can also draw shapes in Adobe Illustrator and with a plug-in, convert it to Canvas commands. Read about it here: http://blog.mikeswanson.com/post/29634279264/ai2canvas.  This gives you the most options for art creation.

SVG: is an alien. It only uses shapes and lines and colors to do its work, so you can't use bitmaps directly. You'll need to create your art by working out the details yourself on graph paper, or use Inkscape or Illustrator to do the heavy lifting for you. I prefer Inkscape because they use SVG all the way down to the core (Illustrator is based on some other technologies and they've added SVG to it along the way). If you want to see a ton of cool SVG art, go to the Open Clipart site. One important fact to point out is that when you create pixel art, you can't do much with it. If you stretch it too much, it looks weird. But SVG is scalable and you can change the size and shape of any SVG art with no loss at all (no loss at all!!!).

Collision
Not all games are about collision, but most action games are, and a phone is a good place for a little quick action! I've written about collision specifically already (CSS, Canvas, SVG) but I'll summarize.

CSS: no collision detection at all. You have to have JavaScript keep track of what is where and when it might collide. That's fine and JavaScript does a great job of keeping track of things. It does have the ability to track a mouse event, so you can tell what object you clicked and process it.

Canvas: has no collision detection either. You need to track where the objects are on your canvas and canvas has no memory of anything except the pixels on it. So JavaScript again saves the day. Unfortunately a canvas has no understanding of where a mouse event lands on the canvas. You can track it by figuring out the coordinates, but the canvas only tells you it was clicked somewhere. It doesn't know. Maybe some day someone will invent something called SmartCanvas. But at least, as I showed in the sample, you can detect what is on the canvas at one spot and make a decision based on that pixel's RBGA color value. Useful if you are tracking a lot of objects with the same color.

SVG: keeps track of everything all the time. It knows every property of every object. You want to know where something is? Ask it. It will tell you its x and y values and its favorite color. In the SVG example of collision, if you look at the code (and you did, right?), you'll see that the mouse click was just a click. It didn't matter where you touched the screen, all that happens is that the red ball jumps. It knows where it is, so it can jump 50 pixels higher. You can do a lot of relative motion, and by using getBBox, you can even track objects as they change size and location. Collision detection is built in.

Special Effects
There's nothing like some special effects to brighten up a game. CSS has the fewest (if you don't count CSS3), Canvas has some very interesting effects if you work at it, but SVG has tons of special effects built in. Tons!

CSS: there are a few CSS effects you can do, but not much that is unusual. You can read about some of them on MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/filter. However, you'll notice quickly that there's a lot of SVG talk on that page, because SVG and CSS are also joined at the hip. A lot of SVG stuff uses CSS! (Everybody knows its a secret.) But I'm not sure how well they work in CSS. (The page on MDN says experimental.)

Canvas: you can do some cool effects with Canvas, but you have to do it pixel by pixel. Tedious and close to assembly language. For some complicated ugly code, check out How to Create Canvas Special Effects.

SVG: it has a lot. If you look at the specification, there are miles of effects just in the Filter Effect section (with lots of cool pictures showing the changes). Plus you can dramatically change size, shape, color, position, etc., with one line of JavaScript for any object. And more. I'm working on some cool glow effects that I'll explain soon (I just love glow effects).

Wrapping Up
There's really no winners and losers. Depending on what you want to do and your skill level and the skill of the artists you work with (or who are you), you can do lots of cool things. Here's my quick summary:

CSS: simple, easy, only uses simple pixel art. And works in every browser. A winner if you are just starting out. But not well known for games (look for CSS sprites if you want to know more). It is the BASIC of the graphics world.

Canvas: very popular. Lots of books. Browsers are really good now about accelerating the canvas so it draws fast and erases fast. Uses pixel art and some shapes. But sometimes seems a little dumb. I'm waiting for Canvas 2.0. Is there even an effort to make it better? Yes, this does resemble C# and JavaScript in that it gets the job done, but has limitations.

SVG: the strange dark animal lurking on the edges. SVG can do all kinds of stuff, but you have to understand what you're doing (or copy code from those who do). But it offers a lot more. SVG is very smart (Smart Vector Graphics) and has a lot of options that are hidden inside every major browser, but which are still partially hidden. Yes, it is like C/C++ in that it provides great performance and endless possibilities, but can be difficult to program. But fun.

So there you have it. As I move forward with more game programming stuff and creating actual games that can go in the Marketplace, I'll be focusing on SVG, but may do some things in Canvas or CSS for fun.

Stay tuned, but not iTuned.

PS: if you feel I've missed anything about any of this, let me know. These are my findings, but you may have found something else.