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
  • 3-or8
  • 5-or8
  • 7-or8
  • 10-or8
  • 11-or8
  • 10-or8
  • 7-or8
  • 5-or8
  • 3-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.

A private key for specified extension already exists

So your Chrome app is ready to go? Awesome! You’re pack­ing it up to test on all your devices when sud­denly… A private key for specified extension already exists. Reuse that key or delete it first.

Pack Extension Error

The Pack Extension Error is actu­ally a pretty simple one to get around. It’s caused because the exten­sion has already been packed in the past, and Chrome auto­mat­ic­ally cre­ated a private key for the package.

The auto­mat­ic­ally cre­ated key has the same file­name as the folder you selec­ted, and is in the same par­ent folder as your exten­sion, You can choose to either delete it (and another will be cre­ated next build) or select the key from the dialog.

Chrome CRX Keys

Each Chrome app is signed with a key, and if you don’t spe­cify one it’s auto­mat­ic­ally cre­ated for you.

You can see from the com­mand line below that the pack-extension com­mand cre­ates both a crx (exten­sion) and a pem (key) file.

$ ls
build-chrome  build-chrome.sh  chrome.zip  libs
$ google-chrome --pack-extension=build-chrome/
Created the following files:
Extension: build-chrome.crx
Key File: build-chrome.pem
Keep your key file in a safe place. You will need it
to create new versions of your extension.
$ ls
build-chrome      build-chrome.pem  chrome.zip
build-chrome.crx  build-chrome.sh   libs

The next time we run the pack-extension com­mand above it will fail because we also need to spe­cify the --pack-extension-key para­meter like so:

$ google-chrome --pack-extension=build-chrome/ --pack-extension-key=build-chrome.pem

None of this is par­tic­u­larly obvi­ous from within Chrome itself, which just gives you the unhelp­ful Pack Extension Error dia­log box. It’s a fairly easy fix though, just hit “Browse…” and the pem file should be right there.

Chrome SecurityError: DOM Exception 18

Of the more cryptic and frus­trat­ing Chrome errors are the SecurityErrors. These bad boys show up at inop­por­tune times and ruin your day with an “Uncaught Error” and a big red excep­tion killing your code in its tracks.

So you’re play­ing around with HTML5 Canvas when all of a sud­den you’re get­ting a Uncaught Error: SecurityError: DOM Exception 18 in the con­sole. What’s it mean?

DOM Exception 18

This excep­tion is thrown when your code is try­ing to access some­thing it shouldn’t, includ­ing cross-domain resources or stuff on your local filesystem.

Once you hit this one you will either need to loosen your browser secur­ity set­tings which is never optimal, or find out how to work around it.

HTML5 Canvas & Exception 18

Which brings us to the case of the com­plain­ing can­vas. Loading images into your can­vas from another domain will “taint” your can­vas, mean­ing any attempts to read the can­vas back again will fail with this error.

This is because your Javascript adheres to a same-origin policy to increase secur­ity. It’s essen­tially done as a con­tain­ment meas­ure so that a rogue script can’t use your browser to access resources you’re authen­tic­ated against.

Hypothetical Canvas Attack

For instance, if I hypo­thet­ic­ally wanted to access your email and your browser didn’t pre­vent cross-site-scripting, I could per­form a $.ajax('http://gmail.com'). This would pull down your logged-in gmail page, and then I could send all your email mes­sages back to my server.

The same applies for images.

This fea­ture pre­vents a rogue site pulling down your Facebook pho­tos, for instance (which again could hypo­thet­ic­ally be done), ren­der­ing them to a can­vas in order to get a hold of the bin­ary image data then send­ing it back to the attack server.

So the second you draw a third party image to your can­vas, you can no longer read back the res­ult­ing image.

The easy solu­tion is to host all your images loc­ally or if that’s not pos­sible you could use a script to pull down and serve the images on your behalf.

SVG Image & Canvas SecurityError

If you’re play­ing around with draw­ing SVG to Canvas in Chrome, you may also run into this secur­ity error, but for a dif­fer­ent reason.

Chrome bombs out printing a SVG

This appears to be a Chrome-specific fea­ture (per­haps a bug?) whereby the SVG doc­u­ment is con­sidered to be of dif­fer­ent ori­gin to the can­vas. This goes a step fur­ther than simply check­ing the ori­gin of the url, it out­right black­lists all SVG images regard­less of ori­gin, includ­ing images encoded in data: uris.

This means that whenever you paint a SVG to your can­vas you’re taint­ing your can­vas and won’t be able to pull inform­a­tion back out of it. This severely hinders efforts to use SVG images as dynamic game sprites, and can be frus­trat­ing to debug because it isn’t imme­di­ately obvi­ous what’s happening.

Working around the same-origin policy

It’s actu­ally pos­sible to spe­cify a cus­tom policy to over­ride the default same-origin beha­viour. This is done via cus­tom HTTP head­ers, which means you’ll need access to your web server to make these changes.

I haven’t yet exper­i­mented with this tech­nique myself, but you can read about it on HTML5 Rocks. I’ll be play­ing with this in the fol­low­ing days, but if you’ve had luck with this tech­nique, do let me know in the comments.

SVG images on a HTML5 Canvas

I wrote a while back about using SVG sprites in a HTML5 Canvas game, but there’s actu­ally a bet­ter way of doing it that doesn’t involve an external JavaScript lib­rary like canvg.

Rendering SVG to a HTML5 Canvas

It’s trivi­ally easy to load up a SVG image as a JavaScript Image ele­ment and draw that to the can­vas. There’s a few ways you can do this, with the easi­est being:

var source = new Image();
source.src = 'http://example.org/myfile.svg';
source.width = '100';
source.height = '100';

This example loads the source file into a new Image ele­ment, ready to be applied to a Canvas the same as any other image.

This takes the hassle and unpre­dict­ab­il­ity out of using a third party lib­rary because it uses the nat­ive browser’s SVG cap­ab­il­it­ies, and will prob­ably be faster to boot.

There are still a few quirks when it comes to load­ing SVG images this way, in par­tic­u­lar the browser may not get the width and height right. In the example above we’ve hard-coded the dimensions.

Actually Rendering to a Canvas

To actu­ally draw a SVG image to a can­vas, it’s the same as any other Image object.

// Set up our canvas on the page before doing anything.
var myCanvas = document.createElement('canvas');
myCanvas.width = 640;
myCanvas.height = 480;
document.getElementsByTagName('body') [0].appendChild(myCanvas);
// Get drawing context for the Canvas
var myCanvasContext = myCanvas.getContext('2d');
// Load up our image.
var source = new Image();
source.src = 'http://example.org/myfile.svg';
source.width = '100';
source.height = '100';
// Render our SVG image to the canvas once it loads.
source.onload = function(){
	myCanvasContext.drawImage(source,0,0);
}

This code loads the SVG image, cre­ates an image in the <body> and renders the SVG to the Canvas ele­ment. The onload is import­ant because it makes sure the image has com­pletely loaded before try­ing to draw it.

Rendering Dynamically Created SVG

If you’re going to be dynam­ic­ally cre­at­ing or modi­fy­ing your SVGs, this tech­nique won’t work.

Any SVG ele­ments loaded as Images no longer have a DOM access­ible for you to manip­u­late, so you will need to pre-load the SVG file and manip­u­late it prior to load­ing it in an Image. You can use any num­ber of tech­niques here such as XHR which I won’t go into.

The dif­fi­cult bit is load­ing the mod­i­fied SVG string back into an Image in order to plop it down onto a can­vas. The solu­tion to this is base64 encod­ing the image and cre­at­ing a Data URI.

The fol­low­ing code will cre­ate a data URI by base64 encod­ing the SVG string:

// My SVG file as s string.
var mySVG = '<svg […]';
// Create a Data URI.
var mySrc = 'data:image/svg+xml;base64,'+window.btoa(mySVG);
// Load up our image.
var source = new Image();
source.src = mySrc;

The btoa func­tion is a nat­ive func­tion to encode a string to base64, but is not offi­cially stand­ard­ised yet. It is a part of the WHATWG liv­ing stand­ard and is sup­por­ted in all SVG/Canvas-capable browsers with the excep­tion of IE9. If you require back­wards com­pat­ib­il­ity or IE9 sup­port there are count­less base64 lib­rar­ies out there you can use instead.

Some Caveats to using SVG on a Canvas

This tech­nique is great provid­ing you don’t require sup­port for IE8, in which case you’re out of luck and should look into using a third party ren­der­ing lib­rary in con­junc­tion with a Canvas shim.

If you’re only look­ing at tar­get­ing mod­ern browsers like Android 3+ and IE9+ this tech­nique will work per­fectly and give you the power and speed of the browser’s nat­ive SVG implementation.

Learn Chrome Dev Tools

Have you always wanted to learn how to use the developer tools in your web browser? Or do you want to learn the ins and outs of debug­ging your sites?

CodeSchool have released a fant­astic range of tutorial videos and inter­act­ive quizzes designed to teach you how to use and make the most of the Chrome dev tools inter­act­ively by modi­fy­ing the tutorial code your­self. It’s really quite clever.

Discover Devtools

The Devtools course fea­tures sev­eral chapters, each tak­ing you through a series of videos and quizzes which teach you to use a skill then assess your know­ledge from within the browser.

  • Check out these Chrome Devtools tutorials.
  • Each tutorial comes with a video and a quiz.
  • The tutorials are HTML based and work with the live developer tools.

The early quizzes work straight up, but more advanced ones such as the source edit­ing, pro­fil­ing and debug­ging require a Chrome plu­gin to track your progress.

If you’re work­ing on Javascript game devel­op­ment, you should def­in­itely check this out for the chapters on per­form­ance and pro­fil­ing. Even if you’re a vet­eran developer, you may still learn a thing or two, so check it out.

CodeSchool

CodeSchool is an ini­ti­at­ive to teach you web devel­op­ment lan­guages and tech­niques from the com­fort of your own browser. It fea­tures a num­ber of classes from web design to pro­gram­ming and is a great way to learn new skills by exper­i­ence.

Can I Use

When you’re devel­op­ing a site, there’s a bunch of neat HTML5 stuff you can use, but a lot of the time it’s not sup­por­ted prop­erly or at all in vari­ous browsers.

Enter stage left: Can I Use dot com.

Caniuse.com is an awe­some com­pat­ib­il­ity ref­er­ence for CSS and HTML5 fea­tures on the web. It lists cur­rent and pre­vi­ous ver­sions of browsers that sup­port vari­ous fea­tures and has a super-fast search to find the tech you’re look­ing for.

Can I Use shows compatibility tables in an easy-to-understand way.

It’s a great way to determ­ine whether you should use a par­tic­u­lar fea­ture for your tar­get audi­ence, and also makes it easier to work out whether you should use a shim to bring older browsers up to speed or use another method entirely to achieve your goals.

Even bet­ter, the source data is on GitHub, so you can fork it for your own nefar­i­ous pur­poses or con­trib­ute back in areas that might not be complete.

If you haven’t already, check out Can I Use before you start work on your next web pro­ject, you may be sur­prised by what you can do.

Chrome Web Store Feedback

If you’re pub­lish­ing a Chrome web app, one thing you may have noticed is that the Chrome Web Store doesn’t have a great feed­back mech­an­ism built into the review system.

If you’re find­ing you’re get­ting a lot of unhelp­ful one star reviews, there’s a chance some­thing is wrong with your app and users might not be able to com­mu­nic­ate this on their own. This is where the “User Feedback” sys­tem comes in.

Some reviews just aren't helpful. Use the User Feedback system to turn unhelpful reviews into solvable problems.

The User Feedback feature

The User Feedback sys­tem is essen­tially an issue track­ing sys­tem built in to the Chrome Web Store. It lets users post com­ments, report issues and oth­er­wise send feed­back for your app which you can reply to and use to solve problems.

The User Feedback sys­tem lets other users see the issues that have been repor­ted, so they can see whether a prob­lem has already been repor­ted as well as what the solu­tion to the prob­lem might have been. This can be help­ful in resolv­ing issues and also in pre­vent­ing bad reviews.

Letting people report issues is a great way to get happy users.

Enable User Feedback

You can enable user feed­back from the Chrome Web Store Developer Dashboard, avail­able from the gear icon at the top-right of the web store.

From the Dashboard you can enable the fea­ture from the options at the bot­tom of the screen.

Once you have enabled the User Feedback fea­ture, users will see a “Send Feedback” but­ton with a gear icon on the details tab of your app page.

You can find the Send Feedback button on the Details tab of your app page.

Dealing with feedback

You can see user feedback from the developer dashboard or via the Web Store. You can view feed­back through the Developer Dashboard by click­ing “User Feedback” next to your app, or you can go through the web store and click “send feed­back” on your app.

The User Feedback sys­tem doesn’t email you when someone cre­ates a ticket, so you need to check back every few hours, days, weeks depend­ing on your project.

Unfortunately the developer dash­board is a some­what rudi­ment­ary inter­face, but you can still use it to reply, request more inform­a­tion, adjust the status of tick­ets and keep track of issues that users are report­ing for your app.

Making the most of User Feedback

While the user feed­back option is great on its own, there are a few ways you can encour­age people to leave qual­ity feed­back you can work with.

The simplest method is to place a line in the descrip­tion text of your app page, dir­ect­ing people to the fea­ture if they have any prob­lems. This can be help­ful espe­cially if your app is new, because people love being able to report issues and help out.

Let users leave feedback from your app, and they'll be far less likely to seek out a negative review.One of the more suc­cess­ful meth­ods is to place a dir­ect link to the User Feedback page from within your app.

The feed­back link doesn’t have to be a prom­in­ent item, just enough for people to know it’s there. This way if some­thing goes wrong, it encour­ages people to air their griev­ances on the feed­back form rather than on the review page where you can’t do any­thing to help them.

Issue Tracking for Chrome Apps

The User Feedback mod­ule is a great addi­tion to the web store, and means you don’t have to set up your own help­desk infra­struc­ture to deal with prob­lems arising in your apps.

Of course it’s an entirely optional ser­vice but it’s use­ful to get feed­back from users in a famil­iar, non-confrontational way. This helps make your app bet­ter, and leaves happy users and developer alike.

Publishing HTML5 Web Apps

Once you have your HTML5 game or app up and run­ning, where do you go to pub­lish it?

You could buy the .com, chuck it online and pub­li­cise it fero­ciously, but have you ever con­sidered sub­mit­ting it to the vari­ous web app stores that are pop­ping up around the ‘net?

There are a num­ber to choose from and each have bene­fits and draw­backs. Here’s a few you might be inter­ested in.

Facebook

The big F, the Facebook App Center is one of the biggest pub­lish­ers you can choose. It’s nowhere near as slick as other app stores and tends to get a bad repu­ta­tion, but if you’re after expos­ure this is by far the best bet.

The Facebook app store is browseable on the open web.

Facebook apps are essen­tially just iframes inside the Facebook chrome. You get a num­ber of cus­tom APIs on top of stand­ard HTML5 which let you do things like post on the user’s behalf and scour their friends list for con­nec­tions, and indeed the eco­sys­tem is heav­ily skewed toward doing so.

One of the down-sides of Facebook is that it’s a browser free-for-all, so you need to make sure your soft­ware works on everything includ­ing tra­di­tional browsers such as IE7+.

If you’re look­ing from some cheap expos­ure and your app doesn’t mind being squashed into a frame, con­sider pub­lish­ing on Facebook.

Chrome Web Store

The Chrome Web Store is an excel­lent way to get your web app out to Chrome users. The Web Store is built into the browser and lets you dis­trib­ute web apps in a num­ber of dif­fer­ent ways.

The Chrome Web Store comes with Chrome, but isn't accessible from other browsers.

Google have worked hard to bring some of the bene­fits of nat­ive apps to their ChromeBook devices, which also carry over to other plat­forms that run Chrome. You can cre­ate web apps that install and run com­pletely off­line or in a sep­ar­ate app-specific win­dow if that’s your thing. You can choose to dis­trib­ute your logic and assets inside the Chrome app when it’s installed, or simply cre­ate a wrap­per to your exist­ing web­site (although the lat­ter may be frowned upon by your users).

The bene­fits of the Chrome Web Store are that it’s Chrome-only so you know what you’re get­ting in terms of ren­der­ing engine, and you don’t have to be too con­cerned about wrangling with Internet Explorer. There are addi­tion­ally some pro­pri­et­ary APIs such as for inter­fa­cing with Google Drive and other Chromebook nat­ive things, although a stand­ard W3C com­pli­ant web app will work just fine.

The Chrome Web Store really is a good spot to pub­lish because there’s almost no effort required and your app becomes avail­able almost instantly. If you’re pub­lish­ing a web app, make sure you pub­lish it here.

Pokki

Pokki is a Windows-only app store that’s taken off recently with the launch of their “start menu replace­ment” for Windows 8.

The Pikki App Store is browseable online or from the Pokki app.

The soft­ware itself is based on Chromium and works very much the same as Chrome itself under the hood, so again you’re not devel­op­ing for mul­tiple plat­forms. The caveat is that wrapped apps aren’t allowed, so you’re going to have to do some work to get your app to work off­line or at least self-contained on the client-side.

While Pokki is Windows-only, it’s still a great way to get expos­ure for your app.

Publish here if your web app is mostly client-side and you’ve got a little time on your hands to adapt it to meet the Pokki review pro­cess.

Firefox Marketplace

The Firefox Marketplace is a rel­at­ive new­comer to the web app space, aim­ing to com­pete with the Chrome Web Store.

The Firefox marketplace is accessible from the web at large, but also comes on Firefox for Android and Firefox OS.

While much of the under­ly­ing tech­no­logy is dif­fer­ent, the same basic points apply as to the Chrome Web Store.

The main dif­fer­ence is that the Firefox Marketplace aims to use as many exist­ing web stand­ards as pos­sible, and allows you to host your app on your own server using the HTML5 Application Cache. You can also pack­age your logic and assets into a zip to dis­trib­ute it via the web store, although this isn’t a necessity.

The Firefox Marketplace is addi­tion­ally avail­able on both desktop and mobile, through Firefox for Android and the upcom­ing Firefox OS.

Publish here if you’ve got a respons­ive app and want to make if avail­able across a range of devices.

Where should I pub­lish my web app?

When pub­lish­ing your web app, you should choose the simplest options first. Once this is stable, think about wrap­ping or port­ing your app for Firefox and Chrome.

Facebook and Pokki are a little more tricky because they have cer­tain require­ments that need to be met through their review pro­cess, but both can be extremely valu­able for get­ting your app out there.

As an altern­at­ive, you may choose to reduce devel­op­ment costs by tar­get­ing more stand­ards com­pli­ant browsers and ini­tially such as Chrome or Firefox, then back­port­ing to Internet Explorer at a later date. This method can be use­ful for rap­idly get­ting your app out there, although you may be in for pain at a later date.

It’s best to look at each mar­ket­place and com­pare your options, you might be sur­prised at the bene­fits pub­lish­ing to a web app store can bring.

Android ImageButton Widgets

The ImageButton is a use­ful wid­get if you want to cre­ate a cus­tom designed but­ton. An ImageButton lets you spe­cify a default, hover and dis­abled state (among oth­ers), each with a cus­tom image of your choosing.

To cre­ate an ImageButton we need to:

  1. Add our images to our resources folder.
  2. Define a new ImageButton as an XML resource.
  3. Add our new but­ton to our XML.

Create ImageButton

Place your XML in res > drawable > mybutton.xml

First step, add your images to the rel­ev­ant draw­able folders. You need at least a default but­ton state, but it’s nice to add a “pressed” state too.

Second step is to cre­ate the XML defin­i­tion of your but­ton in res > drawable-somedpi > my_button.xml, repla­cing somedpi with any DPI of your choosing.

Use the fol­low­ing XML tem­plate as an example:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/info_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/info_pressed" android:state_focused="true" />
<item android:drawable="@drawable/info_enabled" android:state_enabled="true" />
<item android:drawable="@drawable/info_disabled" />
</selector>
  1. Default State

    default-fs8

    Other states aren’t active.

  2. state_enabled

    state_enabled

    The but­ton is enabled.
    android:state_enabled="true"

  3. state_pressed

    state_pressed

    The but­ton is being pressed.
    android:state_pressed="true"

The @drawable/somename entries refer to the images you pre­vi­ously added, without the file exten­sion. In the above example, you can see I’ve defined the following:

  1. state_pressed
  2. state_focused
  3. state_enabled: the default state of a newly cre­ated but­ton in Android.
  4. A fall­back “dis­abled” state. This will show when we dis­able the but­ton later on.

Using an ImageButton

To use an ImageButton, you can define it in your XML view.

<ImageButton
android:id="@+id/btnMyButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:contentDescription="A description of my button"
android:onClick="btnMyButton"
android:src="@drawable/my_button" />

In the above example, I have defined:

  1. id — An ID for my but­ton so we can refer to it later in  our code if need be.
  2. back­ground — Set to null to remove a solid back­ground col­our. This is use­ful when using PNG images to make sure the image doesn’t appear in a square box.
  3. con­tent­De­scrip­tion — This is the alt text, and is essen­tial to make sure our app is access­ible if the user is using access­ib­il­ity tools.
  4. onClick — This points to a method in our activ­ity that will be called when the but­ton is clicked.
  5. src — This tells the ImageButton to use the set­tings we defined in my_button.xml.

Disabled ImageButtons

If you want to dis­able an ImageButton so it can’t be clicked, you will need to do the following:

  1. Disable the button.
  2. Make the but­ton unclickable.

This can’t be done in the view defin­i­tion, but you can do it in your code:

ImageButton ib = (ImageButton)findViewById(R.id.btnMyButton);
ib.setEnabled(false);
ib.setClickable(false);

Android doesn’t provide a “dis­abled” state in our ini­tial XML declar­a­tion so we need to ensure that the default but­ton state in our defin­i­tion is the dis­abled image. We can then spe­cify a sep­ar­ate state_enabled image which will be used when the but­ton is enabled.

Liberated Pixel Cup

The Liberated Pixel Cup is a FSF pro­ject to cre­ate CC-BY-SA/GPL3 game art.

Liberated Pixel Cup aims to encourage game creation around a libre set of assets.

The first stage of the pro­ject will set out a style guide and get some pre­lim­in­ary art done up, and the second stage will encour­age the com­munity to par­ti­cip­ate in art and game cre­ation through a series of competitions.

The art so far looks super cute, and they’re look­ing for money to com­mis­sion ini­tial art and put toward prizes, and the first com­pet­i­tion phase is set to kick off in June.