Archive for category Web Standards

Threading in JavaScript with Web Workers

I’m about 5 weeks into the second 8 week game competition now building my, as yet unnamed, (original) Syndicate clone.

My levels consist of real images from Bing Maps (which I was surprised to find had nicer imagery when compared with Google, despite Google maps generally being my go-to maps site), which I then outline the buildings on using a level editor I built for the task, then save a big ol JSON array. This is then used in game to tell the little guys where they are and aren’t allowed to walk, amongst other things. The windy streets of my first level (Brighton, on the south coast of the UK) make for some difficult navigation- so I had to employ an A* search algorithm which would let my little guys find their way around these defined polygons which represent the footprints of the buildings. This all worked fine, however I noticed a the browser would lock up for a second or so while it ran through checking all the polygons and building paths for all four of your guys. “Wouldn’t it be great if I could do this in another thread” I thought…

Web Workers to the rescue!

Web workers are new in HTML5 and let you fire up another piece of javascript code in another thread, totally separate from the UI (so it will stop the freezeing I was seeing when the Javascript had to think really hard). You only have one mechanism (correct me if I’m wrong here) to send messages between your “Worker” thread and back to the parent application; the postMessage() method and onmessage callback function.

On the application side you create your new worker like this;


// setup the worker- giving it the url for the js file with the code to execute
var worker = new Worker('mysource.js'); 

// define a call back to handle messages we get from the worker
worker.onmessage = function(msg) {  
  alert(msg);
}

// send a message to the worker
worker.postMessage('shaw');  

Then on the worker side you have the same methods at your disposal;

// this exists in mysource.js
// setup a call back to handle messages we receive from the application
self.onmessage = function(msg) {  
  // post a message back to the application
  self.postMessage('hello ' + msg);  
}

In case you’ve not figured it out, in the above example you should expect to get an alert box saying “hello shaw”.

It’s also work pointing out that “self” is the global scope inside one of these web workers, as you won’t have access to any of the usual browser window or document objects.

So this is all pretty straight forward, but I still had a problem with my route finding example; I’d written a class which has a constructor accepting the polygon array and then a method which works out the route and returns it– how does that work in this model?? How do you call methods and constructors when the only access you have to your thread is a simple postMessage method?

Calling methods from ‘the other side’
postMessage() lets you send JSON as well as just plain old strings, which makes it quite a bit more useful. I used this to build a basic messaging system between the app and the thread- I would pass something like this;

worker.postMessage({ method: 'Init', args : [my_array, null, 5]})

then in the worker I would have a call back which looked like this;

self.onmessage = function(msg) {
    // the if catches the 'Init' special case- this instanciates a new RouteFinder
    if (msg.method == 'Init') 
    {
        // create a new instance of our route finder class, using it's constructor and passing in args
        self.MyRouteFinder = RouteFinder.apply( null, msg.args );
    }
    else  // the else catches all the other method calls, whatever they may be
    {  
        // find the method from the prototype chain, and apply it against our globally scoped object, again passing the args
        // the result of this method call is passed straight back to the application
        self.postMessage(RouteFinder.prototype[msg.method].call(self.MyRouteFinder, msg.args));
    }
}

This worked well for me though there are lots of (often better!) variations of this pattern on-line.

What if I don’t want to put my worker code in another file?

Also not a problem as detailed in this article on html5rocks.com. It basically involves grabbing your code from it’s own script tab on the same page, then smashing it into a Blob, then passing this blob into the construtor of your web worker.

Wait a sec.. how do I debug these workers?

You may have fired up some code in Chrome and noticed it hasn’t worked, so gone to the dev tools (F12) then flicked around in the scripts tab and… wait a minute… the web worker code doesn’t show up in the scripts panel! Well don’t worry- if you’re up to date with your copy of Chrome go down to the bottom right hand corner of the scripts panel where you’ll see one of the collapsably panels is called “Workers” and lists the code executing in each of your workers- just click one to launch another debug window which you can set break points on in the usual way.

No Comments

Adding cross browser consistent keyboard short-cuts to your website

I wanted to employ keyboard short cuts to a frequently used internal web app used within the company- Pinch o’ the proverbial piss I thought- I’ll just use access keys! I’ve used them before on front facing sites for accessibility- but when I actually came to document these keys for the users I realised that support across different browsers is a mess;

IE Alt + {key}then hit return
Firefox Alt + Shift + {key}
Chrome Alt + {key} (the most sensible implementation, in my opinion)

IE also seems to refuse to aknowlege the links unless they are currently visible, and as the options I was short cutting existed in drop down menus this was no good, as they existing in bulleted lists which are “display:none” until the user mouses-over the menu bar (using my tiny drop down menu code)!

So to get around this I wrote some jQuery which standardises the short cuts- note this is no good for normal accessibility uses as it’s a new key combo which none of the browsers use, so without documentation no one will know- but for my use on an internal system it’s perfect.

I took the decision to make all the short cuts Ctrl+Alt+{key}, and wanted to keep using the accesskey attribute on my links rather than introduce another mechanism for dictating which keys triggered what- I also wanted to ensure if the link had a javascript onclick handler, instead of navigating away, we respect the handler and simply trigger that. Here’s the code;

$(document).keydown(function(e) {
	if (e.ctrlKey && e.altKey && e.which >= 65 && e.which <= 122) {
		e.preventDefault();
		
		var key = String.fromCharCode(e.which);
		var the_link = $("a[accesskey=" + key.toLowerCase() + "]");
		
		if (typeof(the_link) != 'undefined') {
			// does this link have a javascript assigned click handler, or do we simply send the user to the links href value?
			var events = $.data( $(the_link).get(0), 'events' );
			if (typeof(events) != 'undefined') {
				if (typeof(events.click) != 'undefined') {
					$(the_link).click();
					return;
				}
			}
			window.location = $(the_link).attr('href');
		}
	}
});

1 Comment

Mobile HTML5 Offline app links

I’m looking at writing some apps I did on the iPhone a while ago (the first of which will be Karma) to be mobile html5 offline accessible apps, using html5 audio/ canvas etc- so I’ll use this post to collect some useful links for research;

Also decided to use this as an opportunity to mess with nodejs, using one of the “nosql” db platforms;

http://blog.mongodb.org/post/812003773/node-js-and-mongodb

http://nodejs.org/

1 Comment

Best program for creating favicon’s– infact maybe the best program… ever!

Well maybe not ever.. but it’s pretty good for Icons. It’s called IcoFX – and it’s free!!

No Comments

New Adobe HTML5 Animation tool “Edge”- free tech preview

A real nail in the coffin for Flash, as it’s own parents (Adobe) release a free tech demo version of Edge- A new editor that lets you make flash style animations– without Flash! Instead the animations are scripted using standards html5, JavaScript and CSS3. Having been hand coding stuff like this over the past year (for 8week game and the like) I’m interested to see what kind of code this tool actually spits out! Check it out herel; http://t.co/I46QFYm

3 Comments

Overlapping arrow style menu, and CSS sprite sheets.

Bit of a weird post I guess… I was explaining to a friend how to implement a design they had in html/css and nocked together a reeeeally basic example, and figured I would post it incase it’s of any use to anyone else starting out in html/css. It’s a basic navigation bar where each button is shaped like an arrow, so the buttons all kind of overlap. There is an icon in each, which changes on mouse over, along with the background image of the button. Click the link below and check out the source- the sprite sheet can be viewed here http://codeblog.shawson.co.uk/storage/arrow-nav-bar-sprite-sheet/Sprite-sheet.png

The main example is here;
http://codeblog.shawson.co.uk/storage/arrow-nav-bar-sprite-sheet/

No Comments

Adding minification and obfuscation of your Javascript and CSS to your ASP.net build process using Yahoo YUI Compressor

I’ve just finished integrating Yahoo’s YUI Compressor into the MSBuild process for a new web probject I’m working on, and I thought I would document the process as there doesn;t seem to be a start to finish guide about anywhere.

To start with, let me just explain the structure I use for new Solutions;

C:\_Dev\MyNewWebsite\
C:\_Dev\MyNewWebsite\Artwork\
C:\_Dev\MyNewWebsite\BuildTools\
C:\_Dev\MyNewWebsite\Docs\
C:\_Dev\MyNewWebsite\Source\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.sln
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Controls\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Images\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Scripts\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Services\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\Styles\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Web\MyNewWebsiteWeb.csproj
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Entities\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Entities\MyNewWebsiteEntities.csproj
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Interfaces\
C:\_Dev\MyNewWebsite\Source\MyNewWebsite.Interfaces\MyNewWebsiteInterfaces.csproj
C:\_Dev\MyNewWebsite\ThirdParty\

Firstly, download the dot net port of the YUI compressor from codeplex. I then extracted this into a new folder in the BuildTools folder. (there should be 2 dll files and one txt licence file.)

I then created a new MSBuild file called build-minify.xml, in the MyNewWebsite.Web project folder. That file looks like this;

<?xml version="1.0" encoding="utf-8"?>
<!-- http://yuicompressor.codeplex.com/wikipage?title=Sample%20MSBuild.xml%20File&amp;amp;amp;amp;amp;ProjectName=yuicompressor -->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask
         TaskName="CompressorTask"
         AssemblyFile="..\..\BuildTools\Yahoo.Yui.Compressor-v1.5.0.0\Yahoo.Yui.Compressor.dll" />

  <ItemGroup>
    <CssFiles Include="$(SourceLocation)Styles\Fonts.css"/>
    <CssFiles Include="$(SourceLocation)Styles\Site.css"/>

    <CssIE Include="$(SourceLocation)Styles\IE.css"/>
    <CssIE6 Include="$(SourceLocation)Styles\IE6.css"/>

    <JsAll Include="$(SourceLocation)Scripts\jquery-1.6.1.min.js" />
    <JsAll Include="$(SourceLocation)Scripts\jquery-ui-1.8.14.custom.min.js" />
    <JsAll Include="$(SourceLocation)Scripts\json2.js" />
    <JsAll Include="$(SourceLocation)Scripts\jqModal-r14.js" />
    <JsAll Include="$(SourceLocation)Scripts\jquery.tipsy.js" />
    <JsAll Include="$(SourceLocation)Scripts\jquery.scrollTo-1.4.2.min.js" />
    <JsAll Include="$(SourceLocation)Scripts\jquery.localscroll-1.2.7.min.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-alert.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-validation.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-rollovers.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-custom-accordion.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-vehicle-lookup.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-sandbox.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-finance-calculator.js" />
    <JsAll Include="$(SourceLocation)Scripts\chinook-apply-now.js" />
    
  </ItemGroup>

  <Target Name="Minimize">
    <CompressorTask
              CssFiles="@(CssFiles)"
              DeleteCssFiles="false"
              CssOutputFile="Styles/Site.rel.css"
              CssCompressionType="YuiStockCompression"
              DisableOptimizations="Nope"
              EncodingType="Default"
              LineBreakPosition="-1"
              LoggingType="ALittleBit"
              ThreadCulture="en-gb"
              IsEvalIgnored="false"
            />

    <CompressorTask
              CssFiles="@(CssIE)"
              DeleteCssFiles="false"
              CssOutputFile="Styles/IE.rel.css"
              CssCompressionType="YuiStockCompression"
              DisableOptimizations="Nope"
              EncodingType="Default"
              LineBreakPosition="-1"
              LoggingType="ALittleBit"
              ThreadCulture="en-gb"
              IsEvalIgnored="false"
            />

    <CompressorTask
              CssFiles="@(CssIE6)"
              DeleteCssFiles="false"
              CssOutputFile="Styles/IE6.rel.css"
              CssCompressionType="YuiStockCompression"
              DisableOptimizations="Nope"
              EncodingType="Default"
              LineBreakPosition="-1"
              LoggingType="ALittleBit"
              ThreadCulture="en-gb"
              IsEvalIgnored="false"
            />
    
    <CompressorTask
      JavaScriptFiles="@(JsAll)"
      ObfuscateJavaScript="true"
      PreserveAllSemicolons="true"
      DisableOptimizations="false"
      EncodingType="Default"
      DeleteJavaScriptFiles="false"
      LineBreakPosition="-1"
      JavaScriptOutputFile="Scripts/chinook.rel.js"
      LoggingType="ALittleBit"
      ThreadCulture="en-gb"
      IsEvalIgnored="false"
		/>
  </Target>
</Project>

You can create whatever ItemGroups you’d like- then just create a compressor task for each. For a rundown of the settings, check out the link in the comment at the top of the XML there. In the above file I had decided to compress all of my Javascript into a single file called chinook.rel.js, and my fonts and site css file rolled into one file, keeping the ie6 css separate, but still minifying it down.

The next step is to add it to the normal build. I opened the solution in Visual Studio, right clicked my web project and selected properties. Go to “Build Events” and add the following post-build event;

$(MSBuildBinPath)\msbuild.exe  $(ProjectDir)build-minify.xml /target:Minimize

Now you can test it out by building your project. The new minified files are dumped out, in my case to the Scripts folder. Now that the files are there, I need a way of telling my release version of the website to use these instead of the raw, human-readable versions; but I still want to continue using the human-readable versions for development.

To achieve this I use pre-processor directives. These are most commonly seen in the c# code behind files, but can also be used in the aspx files. I added the following lines at the bottom of my master page;

    <% #if (!DEBUG) %>
    <script src="Scripts/chinook.rel.js" type="text/javascript"></script>
    <% #else %>
    <script src="Scripts/jquery-1.6.1.min.js" type="text/javascript"></script>    
    <script src="Scripts/jqModal-r14.js" type="text/javascript"></script>
    <script src="Scripts/chinook-alert.js" type="text/javascript"></script>
    <script src="Scripts/jquery-ui-1.8.14.custom.min.js" type="text/javascript"></script>
    <script src="Scripts/chinook-vehicle-lookup.js" type="text/javascript"></script>
    <script src="Scripts/chinook-sandbox.js" type="text/javascript"></script>
    <script src="Scripts/chinook-finance-calculator.js" type="text/javascript"></script>
    <script src="Scripts/jquery.scrollTo-1.4.2.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.localscroll-1.2.7.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.tipsy.js" type="text/javascript"></script>
    <script src="Scripts/json2.js" type="text/javascript"></script>
    <script src="Scripts/chinook-validation.js" type="text/javascript"></script>
    <script src="Scripts/chinook-apply-now.js" type="text/javascript"></script>
    <script src="Scripts/chinook-rollovers.js" type="text/javascript"></script>
    <script type="text/javascript" src="Scripts/chinook-custom-accordion.js"></script>
    <% #endif %>

So if the project is NOT running in debug mode, I import my full chinook.rel.js include which has everything already included, otherwise I manually include all the human readable, separate files.

And that’s pretty much it. Make sure you thoroughly retest your site with your combined java script file, as sometimes minification can cause issues with some code.

2 Comments

Handy article on running IE 6, 7 & 8 alongside each other on Win7 using XP mode

http://www.sitepoint.com/ie6-ie7-ie8-win7-xp-mode/#fig_xmpuser

No Comments

Work Starts on my WebGL Game!

Caught up in all the excitement of WebGL becoming more mainstream, I’m building another javascript game. My first offering to the browser based game community was Manic Spaceman, a straight platform game based on ManicMiner which was a little rough around the edges, but boshed out on the quick for the 8weekgame competition.

This time round I intend to go full 3d, taking advantage of WebGL, and make a desert strike style game. I considered starting from scratch, as I did with Manic Spaceman, and writing my own engine to power it all, however given that I’ve next to no 3d experience I thought I would reduce the scope a little and use an engine that’s already out there. After about a week of research I’ve settled for Three.js – I say “settled”, but it’s actually shaping up to be a pretty awesome engine. There’s are a few decent engines out there, all obviously in their infancy, but having reviewed the feature set and looked at the demo’s and read around other developers experiences,  Three feels like the best choice. The other’s I considered were;

The Short List

Other contenders

I only considered open source offerings and looked for engines which

  • were still being actively developed (!)
  • seemed performant with high poly counts
  • handle shadows/ reflections
  • exposed access to GLSL
  • UV Mapping support
  • be relatively stable.

It was surprising how many engines had broken demo’s on their site, which never bodes well, but on the whole, they are all good offerings with almost all of them fulfilling my requirements.

While building my game, I shall be working through some OpenGL tutorials I found- a port of the well known NeHe OpenGL tutorial set, on LearningWebGL.com, which should put me in good stead to build my next game totally from scratch.

I shall post updates as I have something to show.  So far I’ve written a HeightMap generator which works from a greyscale bitmap to build terrains, and I’m currently working on getting the model to follow the landscape; I’ve a long road ahead!

3 Comments

ManicSpaceMan now works in IE(9)!

Cast your mind back to about 6 months ago when Gareth, Martin and myself did the first 8WeekGame competition- Controversially I didn’t use XNA, but instead created a game which would run from your browser, using the new HTML5 canvas support- at the time it was a niche feature without wide browser support, but with the recent release of IE9, you can now finally play ManicSpaceman in IE! So go upgrade your browser and give it a go! Although I should note– for some reason the sounds don’t play in IE, despite me creating a whole MP3 set of the sounds specifically for it; so the best experience is still in FireFox or Chrome!

While on the subject of IE9- see here for the terribly useful developer notes on the new browser detailing all the new cool stuff it supports (css3/ html5 features) http://msdn.microsoft.com/en-us/ie/ff468705#_Intro

2 Comments