Practical SVG Manipulation for use in Games

I tried to do a demo of some of the SVG stuff I’ve been play­ing with recently at BrisJS, but due to a com­edy of errors I was unable to do much more than talk about it. So I figured I’d write up some of my find­ings here.

SVG in Canvas

Basically what I’ve been doing recently is exper­i­ment­ing with SVG sprites for use in HTML5 Canvas games.

SVG is an XML-based vec­tor image format that’s often used in graphs and inter­act­ive fea­tures, but it’s actu­ally really good as a graph­ics inter­change format for use in games because it can be manip­u­lated really eas­ily with Javascript.

Here’s a SVG image so you can check it out. You can inspect it in the DOM inspector which will show you the ele­ments and attrib­utes we can manip­u­late with JS.

I drew it in Inkscape, but because it’s all XML-based we can adjust the col­ours and styles of the image dynam­ic­ally in the browser.

A Quick Demo

I’ve put together a quick demo of the tech­nique which shows a basic col­our­ising of col­our mapped images such as the one above.

Changing the col­our of SVG images is a pretty simple fea­ture which people use all the time in reg­u­lar SVG oper­a­tions. Generally this might be used to cre­ate a rollover effect or adjust the col­our of a bar in a dough­nut graph, but with this demo you can choose two col­ours and use them to col­our­ise the entire SVG image.

Check it out at assets.kyd.com.au/svg-recolour/demo/demo.html

How it works

I’ve used the col­or­box lib­rary to per­form col­our modi­fic­a­tion oper­a­tions on the input col­ours to gen­er­ate high­lights and shades, which cor­res­pond with the vari­ous key col­ours in the source image.

I’ve then per­formed a basic string search and replace on the tar­geted col­ours to make the changes to the image so it uses the col­ours you’ve chosen rather than the ori­ginal col­ourmap. This some­thing that could very nicely be done with jQuery select­ors for instance, but isn’t some­thing I’ve had time to do yet.

  • 1-or8

The demo also has a game time fea­ture, which per­forms fur­ther col­our modi­fic­a­tions based on the in-game “hour” of the day. So for instance at mid­night the col­ours you ori­gin­ally chose would be heav­ily desat­ur­ated and tin­ted with a blue col­our to sim­u­late night time. In the even­ing, sun­set adjusts the col­ours to add oranges and reds before fad­ing into night.

The final fea­ture of the demo is a little logic which flicks lights on and off once it gets dark, and altern­ates neon signs on and off at intervals.

And then?

SVG tends to be a little slow in select browsers, and espe­cially so with com­plex images which you can prob­ably see in the demo. While this might be okay when you’re just dis­play­ing a static image, it becomes totally unac­cept­able in high-performance situ­ations where you need to draw it sixty times per second.

We can get around this issue by pre-drawing the SVG images to another Canvas object (not pic­tured). This off-screen Canvas holds a bit­map rep­res­ent­a­tion of the image and con­sequently renders to our game can­vas much faster because the heavy lift­ing has already been done.

We can take this a step fur­ther and render all the vari­ations of a par­tic­u­lar image if we have enough memory, res­ult­ing in a long ini­tial load but a fast game once it’s done.

As a side note, using this method trig­gers addi­tional secur­ity pre­cau­tions in the browser which may pre­vent you from per­form­ing some game-related tasks.

Where from here?

Ultimately I’d like to imple­ment this in my game engine and pro­ced­ur­ally gen­er­ate com­plex game worlds, but for now this is just a concept.

I’ve also been play­ing with trans­form­ing tex­tures and apply­ing them to objects within the SVG envir­on­ment as a sort of 2D tex­ture map­ping, but I’m not espe­cially happy with the res­ults so I think I’m going to stick with vec­tor graph­ics for now.

warehouse-toy

Anyway, if you like the idea you should totally have a play and see what you can come up with. You can also check out my code on GitHub if you’d like to see exactly what I’ve done.

Leave a Reply