03 Jul 2016 - by 'Maurits van der Schee'
I confess: I love Flash and I think it is much better than HTML5. But Flash is dead now (I blame Apple) and we have to build in HTML5. Actionscript 3 was a beautiful and powerful language, especially for games. In this post I will describe how to port an application from beautiful Actionscript 3 code (Flash) to the ugly Javascript reality (HTML5).
Drawing graphics in Flash was easy and your drawings could be combined and even easily animated. Flash scaled seamlessly in high quality so that you did not have to bother about screen sizes. There was only one runtime implementation, so there were hardly any compatibility bugs. Animations performed great, even on older computers. It really was a developer dream come true. Now we have to work with Javascript, SVG and all kinds of different browser implementations, a huge step backwards.
In Flash we had a library of graphics that could reference each other. Some of the graphics could be marked as "export for Actionscript" and given an identifier for programmatic access. Fortunately we can also make a library in a SVG file. Below is an example of my library for Tic-Tac-Toe:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="empty">
<rect x="0" y="0" width="160" height="160" fill="#eee"/>
<rect x="5" y="5" width="150" height="150" rx="15" ry="15" fill="silver"/>
</g>
<g id="cross">
<use xlink:href="#empty"/>
<path stroke="red" stroke-width="35" d="M75,0 L75,150Z M0,75 L150,75z" transform="translate(80,-25) rotate(45) " />
</g>
<g id="circle">
<use xlink:href="#empty"/>
<circle stroke="blue" stroke-width="35" cx="80" cy="80" r="50" fill="none" />
</g>
</defs>
</svg>
As you can see we export the "g" (group) definitions by giving it an "id" property, which is the name we will use to reference the graphic in the code.
We can load the SVG using jQuery (as you can see below) or we can statically add the SVG to the HTML in a non-displayed "div" element.
<script type="text/javascript">
$(function(){
$.ajax({
url: "graphics.svg",
dataType: "text",
success: function(response){
$(document.body).prepend('<div style="display:none">'+response+'</div>');
// start game here
}
});
})
</script>
You should only start to run the game once the SVG is injected, because otherwise your xlink references won't work when drawing the graphics.
In Flash we used to have a MovieClip tree with a root element. In HTML5 we can work with the DOM. To load the "cross" graphic from the SVG library we use the following SVG code:
<svg role="img">
<use xlink:href="graphics.svg#cross"/>
</svg>
This can either just be added to the HTML body or injected or replaced using jQuery as you can see in the snippet below from a "draw" function:
var html = '';
for (var y=0;y<3;y++) {
for (var x=0;x<3;x++) {
html+= '<svg role="img" viewBox="0,0,160,160" width="200" height="200">';
html+= '<use xlink:href="graphics.svg#'+field[x][y]+'"/>';
html+= '</svg>';
}
}
$('#game').html(html);
Note that although the cross in the library has width x height of 160 x 160, it is actually drawn at 200 x 200, but without loss of fidelity. If you use the CSS style "positioning: absolute", then you can position the SVG at an arbitrary position and also easily overlay them (using "z-index").
Javascript is not object oriented. This does not mean you can't follow a OOP style of programming. One of the best explanations of how this can be applied can be found on javascript.info. I also think you should read chapter 8 of Eloquent Javascript by Marijn Haverbeke.
With the above tools you can start porting you Flash game to HTML5. I have put a simple game template on Github for you to start from.
PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.