Sam MacPherson

Flash, Haxe, Game Dev and more…

Category Archives: Uncategorized

iOS Safari Mobile Absolute Position Bug

This bug has gotten me twice with two separate HTML5 games so I figured I’d share. Seeing as most cross-platform HTML5 games have to run on a bunch of different screen resolutions it’s fairly common to see games resize a canvas to fit the screen. It’s for this reason that we need to be able to accurately determine the width and height available to us.

If you are just using a canvas element then you should be fine, but a lot of the time I’m seeing absolutely positioned elements above the canvas (such as for text display). The problem comes in when you move an absolutely positioned element off the screen – even partially. Most browsers respect that absolutely positioned elements should not affect the dimensions of the parent element, but for iOS Mobile Safari this is not the case. Off screen absolute elements will change the dimensions of the page and cause width and height measurements to be wrong which in turn causes the canvas to resize to an amount larger than the screen.

Until they fix this it seems the only solution I could find was to change position: absolute to position: fixed for these elements. As long as the page doesn’t move it will produce the same effect. Cheers.

Lighting and Particle Demo

Here is a demo of the effects that I have been working on in my upcoming game – Zed. The video is intended for the gamers, but you can also get a glimpse at the tech side of things.

Why Haxe is Just Awesome Pt 2

Ok, so as always I end up doing way more work then I need to due to my lack of knowledge. After some development, the javascript interface I was explaining in my previous post ended up getting a little sloppy. Turns out for more AJAX intensive parts of my site resolving html elements was getting harder and harder. A lot of the time I ended up just navigating the dom by relative parent/child pointers which of course is terrible if you want to have a manageable long-term code-base. Having the static event handlers just wasn’t cutting it. So I did some looking around and it turns out Haxe already has a solution!

Serialization is the answer and the haxe.Serializer and haxe.Unserializer classes provide just the solution. Now instead of transmitting the html (

tags, etc) from the server I just send the client a serialized version of the dom representation and the javascript on the client can recreate the exact same structure on the client! A webpage ends up looking like this:

<html><head><title>Home</title><link type='text/css' href='/style.css' rel='stylesheet'></link><script type='text/javascript' src='/client.js'></script><meta name='data' content='cy12:www.dom.HTMLy8:childrenlcy12:www.dom.Heady6:parentr0R1lcy13:www.dom.Titley4:texty4:HomeR3r2R1lhy3:tagy5:titley7:attribsbhgcy18:www.dom.StyleSheetR3r2R1lhR7y4:linkR9by4:typey10:text%2Fcssy4:hrefy12:%2Fstyle.cssy3:rely10:stylesheethgcy18:www.dom.JavascriptR3r2R1lhR7y6:scriptR9bR12y17:text%2Fjavascripty3:srcy12:%2Fclient.jshghR7y4:headR9bhgcy12:www.dom.BodyR3r0R1lcy11:www.dom.DivR3r14R1lcy12:www.dom.LogoR3r16R1lcy11:www.dom.ImgR3r18R1lhR7y3:imgR9bR21y20:%2Fimages%2Flogo.pnghghR7y3:divR9by5:classy4:logohgcy13:www.dom.LoginR3r16R1lcy17:www.dom.form.FormR3r24R1lcy19:www.dom.form.HiddenR3r26R1lhR7y5:inputR9by4:namey1:aR12y6:hiddeny5:valuey5:loginhgcR35R3r26R1lhR7R36R9bR37y4:hashR12R39R40y32:2h4i27uutas7l02dild8t8hzbi0489f7hgcy18:www.dom.form.InputR3r26R1lhR7R36R9bR37y4:userR12R5y2:idy2:e1R31y72:input-empty%20__clswww.dom.form.Input%20__ed.e1.onfocus%20__ed.e1.onblurR40y8:Usernamehgcy21:www.dom.form.PasswordR3r26R1lhR7R36R9bR37y4:passR12R5R46y2:e2R31y75:input-empty%20__clswww.dom.form.Password%20__ed.e2.onfocus%20__ed.e2.onblurR40y8:Passwordhgcy21:www.dom.form.CheckboxR5y16:Remember%20Me%3FR3r26R1lhR7R36R9bR37y8:rememberR12y8:checkboxR40y4:truehgcy19:www.dom.form.SubmitR3r26R1lhR7R36R9bR12y6:submitR31y15:__ed.e3.onclickR40y5:LoginhghR7y4:formR9by6:actiony0:y6:methody4:posty7:enctypey35:application%2Fx-www-form-urlencodedR46y2:e3R31y18:__clswww.dom.Loginhgcy9:www.dom.AR5y24:Register%20an%20account.R3r24R1lhR7R38R9bR14y11:%2FregisterhghR7R30R9bR31y7:accounthgcR25R3r16R1lcy15:www.dom.NavListR3r51R1lcy10:www.dom.LIR3r53R1lcR73R5R6R3r55R1lhR7R38R9bR14y3:%2FhghR7y2:liR9bhgcR78R3r53R1lcR73R5y5:GamesR3r61R1lhR7R38R9bR14y8:%2FgameshghR7R80R9bhgcR78R3r53R1lcR73R5y7:ProfileR3r67R1lhR7R38R9bR14y10:%2FprofilehghR7R80R9bhgcR78R3r53R1lcR73R5y6:GroupsR3r73R1lhR7R38R9bR14y9:%2FgroupshghR7R80R9bhgcR78R3r53R1lcR73R5y5:ForumR3r79R1lhR7R38R9bR14y8:%2FforumhghR7R80R9bhghR7y2:ulR9bhghR7R30R9bR31y10:navigationhghR7R30R9bR31y6:headerhgcR25R3r14R1lcR25R3r88R1lcR25R3r90R1lhR7R30R9bR31y5:errorhgcR25R3r90R1lcy22:www.dom.home.GameSmallR3r95R1lcR25R3r97R1lcy10:www.dom.H1R5y3:ZedR3r99R1lhR7y2:h1R9bhghR7R30R9bR31y16:game-small-titlehgcR25R3r97R1lcy19:www.dom.AnchorImageR5R66R3r105R1lcR27R3r107R1lhR7R28R9bR21y25:%2Fimages%2Fgames-zed.pnghghR7R38R9bR14y3:%23hghR7R30R9bR31y34:game-small-image%20__ed.e0.onclickhgcR25R3r97R1lcy9:www.dom.PR5y229:Pick%20a%20class%2C%20kill%20zombies%20and%20level%20up%20your%20character.%20Features%20will%20include%20an%20extensive%20item%20system%2C%20very%20customizable%20skill-sets%2C%20large%20re-playable%20worlds%20and%20much%20more.R3r114R1lhR7y1:pR9bhghR7R30R9bR31y15:game-small-deschghR7R30R9bR46y2:e0R31y33:game-small%20__clswww.dom.GameDOMhghR7R30R9bhghR7R30R9bR31y7:contenthghR7R30R9bR31y29:content-wrapper%20columns-onehgcR25R3r14R1lcR102R5y6:FooterR3r124R1lhR7R104R9bhghR7R30R9bR31y6:footerhgcy13:www.dom.CoverR3r14R1lhR7R30R9bR37y5:coverhgcy15:www.dom.GameDOMR3r14R1lhR7R30R9bR37y4:gamehgcy12:www.dom.DockR3r14R1lcy19:www.dom.FriendsListR3r136R1lcR73R5y7:FriendsR3r138R1lhR7R38R9bR14R100R31y15:__ed.e4.onclickhghR7R30R9bR46y2:e4R31y43:dock-friend-list%20__clswww.dom.FriendsListhghR7R30R9bR37y4:dockR31R122hghR7y4:bodyR9bR46R123hghR7y4:htmlR9bhg' id='__DATA__'></meta></head></html>

As you can see the html is fairly boiler-plate save for the massive meta tag. The meta tag contains the entire webpage along with the back-end to make AJAX stuff a LOT easier. I can then run this on the client:

ROOT = Unserializer.run(js.Lib.document.getElementById("__DATA__").getAttribute("content"));

What does all of this give me? Very intuitive code that seamlessly integrates the server and the client. For example I can write this:

var body:Body = new Body();
var button = new Submit("MyButton");
button.addEventListener(Event.CLICK, onClick);
body.add(button);

function onClick (e) {
	body.remove(button);
}

Amazingly this code will add a button to the body of an html document then (when clicked) will remove itself. How does this work? The body and button tags are generated on the server and transmitted through the serialized data meta tag then unserialized and javascript sets up the listeners on the client. Once the button is pressed the function onClick() is called (In javascript) and the body element removes the button child. Of course some code is missing but you get the idea. Very cool stuff!