Saturday 31 December 2011
Spring Cleaning & Updated Bio
I have been meaning to do this for a while, but never gotten round to it. Well more precisely other projects have always been more interesting so I pursued those instead ;) This Christmas however I decided it was about time that I finally did it.
Anyways I have finally given my bio on the About page abit of a spit shine. I originally wrote it based on my CV a long time ago and thought it deserved a little bit of love considering that it gets quite a few hits. Its all written in the third person, im not entirely sure why I decided to do it like that originally, oh well.
I have also rearranged some of my earlier work so best to give the archive a more accurate timeline.
Saturday 26 November 2011
Hxaria, Infinite Terrain [HaXe, WebGL,dat.GUI]
So I have been working on my "Terraria like Terrain" project "Hxaria" again.
Following on from the last post, I have now made it so that each particle can have its texture changed. This completes the functionality required to render each tile as a point sprite, as talked about in my previous post.
The way it works is that the entire world is recorded in a 2x2 array Tilemap. This 2x2 array holds a single Tile object for every single tile in the world:
[codesyntax lang="actionscript3" lines="normal"]
class Tile
{
public var x : Int;
public var y : Int;
public var type : Int;
public function new(x:Int, y:Int, type:Int) { this.x = x; this.y = y; this.type = type; }
}
[/codesyntax]
When the TileRenderer needs to render it asks this Tilemap for a Tile that represents that screen coordinate, the Tilemap then offsets the position due to the camera movement and returns a tile. So it looks something like:
The tile type is then passed to the shader in attribute buffers per point sprite / tile along with all the tiles which are stored on a single texture:
The shader then performs the neccessary calculations to work out what the UV coordinate in the texture. The Vertex Shader:
[codesyntax lang="glsl" lines="normal"]
uniform float amplitude;
uniform float tileSize;
uniform float texTilesWide;
uniform float texTilesHigh;
uniform float invTexTilesWide;
uniform float invTexTilesHigh;
attribute float size;
attribute vec3 customColor;
attribute float tileType;
varying vec3 vColor;
varying vec2 vTilePos;
void main()
{
vColor = customColor;
float t = floor(tileType/texTilesWide);
vTilePos = vec2(tileType-(t*texTilesWide), t); // +(.5/tileSize)
gl_PointSize = size;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
[/codesyntax]
And the Fragment Shader:
[codesyntax lang="glsl" lines="normal"]
uniform vec3 color;
uniform sampler2D texture;
uniform float invTexTilesWide;
uniform float invTexTilesHigh;
varying vec3 vColor;
varying vec2 vTilePos;
void main()
{
vec2 uv = vec2( gl_PointCoord.x*invTexTilesWide + invTexTilesWide*vTilePos.x, gl_PointCoord.y*invTexTilesHigh + invTexTilesHigh*vTilePos.y);
gl_FragColor = texture2D( texture, uv );
}
[/codesyntax]
So it works in a way very much like a raster engine. You only have to render as many particles as the screen can contain.
If the screen area moves beyond the extent of the Tilemap then more tiles are randomly generated:
The new tiles are randomly selected from 4 different types, Dirt, Gold, Diamonds and Rock. I have added some controls to the demo that allow you to tweak these values to demonstrate the random tile generation:
The UI may look familiar to people that have seen any experiments anyone who has worked with Three.js before, its the very popular dat.GUI. Its a really simple library written in javascript for creating controls that can be used to tweak experiments, perfect for me!
To get dat.GUI to work with haxe, I used the awesome Extern feature of HaXe. This means that all I have to do is provide a stub interface to dat.GUI rather than a full implementation in haXe. This is great as it allows me to rapidly begin to use the library but also have the type safety of HaXe. It didnt take long to stub out the bits of the library I needed in an extern:
[codesyntax lang="actionscript3" lines="normal"]
package dat;
/**
* ...
* @author Mike Cann
*/
extern class GUI
{
public function new(options:Dynamic) : Void;
public function add(options:Dynamic, name:String) : GUI;
public function name(value:String) : GUI;
public function min(value:Float) : GUI;
public function max(value:Float) : GUI;
public function step(value:Float) : GUI;
public function onFinishChange(f:Void -> Void) : GUI;
public function listen() : GUI;
}
[/codesyntax]
Then I used it like:
[codesyntax lang="actionscript3"]
package ;
import dat.GUI;
/**
* ...
* @author
*/
class GUIManager
{
public var goldChance : Float;
public var rockChance : Float;
public var diamondsChance : Float;
public var mapWidth : Int;
public var mapHeight : Int;
private var gui : GUI;
private var game : Game;
public function new(game:Game)
{
this.game = game;
gui = new GUI( { height : 5 * 32 - 1 } );
goldChance = game.tilemap.goldSpawnChance;
rockChance = game.tilemap.rockSpawnChance;
diamondsChance = game.tilemap.diamondsSpawnChance;
game.tilemap.mapResized = onTilemapResized;
mapWidth = 0;
mapHeight = 0;
gui.add(this, 'goldChance').name("Gold").min(0).max(1).step(0.001).onFinishChange(function() { game.tilemap.goldSpawnChance = goldChance; } );
gui.add(this, 'rockChance').name("Rock").min(0).max(1).step(0.001).onFinishChange(function() { game.tilemap.rockSpawnChance = rockChance; } );
gui.add(this, 'diamondsChance').name("Diamond").min(0).max(1).step(0.001).onFinishChange(function() { game.tilemap.diamondsSpawnChance = diamondsChance; } );
gui.add(this, 'mapWidth').listen();
gui.add(this, 'mapHeight').listen();
}
private function onTilemapResized(mapW:Int, mapH:Int):Void
{
mapWidth = mapW;
mapHeight = mapH;
}
}
[/codesyntax]
Simples!
Anyways you can check the final result out on this page: http://mikecann.co.uk/projects/hxaria/02/
(Click and drag to move the camera about)
I have also uploaded a quick video too:
I have also uploaded the source again to my github page: https://github.com/mikecann/Hxaria
(I have also created a tag, incase the source changes in the future)
Next up, lighting!
Sunday 20 November 2011
New Blog Host & Face-lift
Just a quick post to say I have finally moved away from my old hosting on WebFusion and now im on the cheaper (and hopefully) more reliable hosting by STRATO.
Its the first time I have had hosting on a windows machine and I must say I really like it. I feel much more at home on a windows machine, I know where everything is and im more familiar in a graphical OS. I had a couple of permissions problems related to uploading new images on wordpress but a quick Google turned up this post:
http://wordpress.org/support/topic/weird-permissions-with-iis7-and-uploaded-images
Apparently WordPress sticks new uploads in the c:\windows\temp directory, before it moves them to the usual \wp-content\ folder, so you have to ensure that temporary folder has the correct permissions for IIS_IUSRS too else it wont work correctly when the file is moved to the content folder.
You may also notice that I have decided to give the blog a little face-lift too with a new theme. I decided this time to go for a paid theme, as they aren't that expensive (compared to hosting costs) and the quality and customization with paid themes are go much better than their free counterparts. I found it on the excellent themeforest site, the theme is called PixelPower.
Anyways if you find any broken links or anything off with the site then let me know!
Thursday 17 November 2011
Hxaria, Terraria like terrain in HaXe and WebGL
I woke up the other day thinking about Terraria. No idea why as I haven't played it in ages, but its the type of game I really enjoy so it must have snuck into my dreams during the night.
Anyways, it got my thinking if it would be possible to make something similar to it in the browser using WebGL. For those not aware of Terraria, it looks something like this:
To produce the above you need several layers of tilemaps (background, water, foreground etc) that can potentially change every single frame (due to lighting environment effects etc). To do that at 1680x1050 at 16x16 per tile with only one layer changing each frame will be 6800 tile draws per frame.
Having calculated that I got thinking about the best way to render lots of tiles.
My first thought was to render each tile as a separate quad. That would certainty work, however it would mean that for each tile I would need 4 vertices, times that by say 4 layers that's 108,800 vertices. Its not a massive massive amount but sizable enough for me to wonder if there was a more efficient way.
My next thought was that I could share vertices by using vertex indices in a triangle-strip, that way at best each tile will only require just over one vertex per tile then arrange them in a lattice so that the vertices are shard between tiles:
This would then only require about 27,200 vertices which is really nice. I was hover having difficulties imagining how I would reference each tile individually in the shader so I could apply texture and color transformations and started wondering if another technique might work..
Having recently done some work with Point Sprite Particles I knew that the GPU was really good at rendering Point Sprites. So I thought to myself, why not just make each tile a point sprite. That way I could then represent each tile as a vertex then I could pass custom properties such as texture and color to the shader as vertex buffer attributes. Doing it this way means that you only need as many vertices as there are visible tiles (about 27,200 for 4 layers) and I can reference each tile individually in the attribute buffer.
So armed with the theory I set to work bashing out some code. Having worked with raw WebGL in haXe on my last few experiments I decided I didnt want to go through all that pain again just for the sake of a little more performance, so I decided to give Three.js another go in HaXe. Thankfully this time I was treading a known path so I could learn from existing threejs point-sprite particle samples. The bulk of the custom particle system logic I took from this rather excellent sample:
(http://alteredqualia.com/three/examples/webgl_custom_attributes_particles.html)
So once I had the project setup it took me no time at all to bash out a sample that showed that I could easily have 27k+ tiles changing size and color each frame:
http://mikecann.co.uk/projects/Hxaria/01/index.html
Pretty aint it?
What you are looking at is 40,000 point sprites changing to a random colour and size every frame, well above the 27k needed. As part of my testing I found that it can actually handle a lot more (hundreds of thousands) of individually updating tiles!
Im planning to continue work on this sample, my next step is to get each particle using a different tile type and changing each frame.
I have uploaded the source to github for your perousal: https://github.com/mikecann/Hxaria
Enjoy!
Saturday 29 October 2011
Terrainicles [WebGL & HaXe]
I have been playing with this thing, tweaking it, making changes for weeks. Theres so many different things I want to add. Different options, scenarios, optimisations etc. I decided however just to follow the 'release early and often' mantra and get this thing out now.
Before I go any further check out what im talking about here:
http://mikecann.co.uk/projects/WebGLTerrainicles/
(You will need a WebGL compatible browser, that means no IE)
Its a continuation of my earlier work on GPU particles using WebGL and HaXE. Im trying to emulate some work I did years ago in XNA, on the LieroXNA project.
It uses the same techniques for updating and rendering particles entirely on the GPU as my previous post. What that means is that is possible have millions of particles interacting updating and rendering simultaneously as all the operations are performed on the GPU.
What I have added this time is another texture for the particles to collide with as they move. I was originally working with the same dirt and grass texture as my XNA project but I thought as it was Halloween I would get into the spirit a little ;)
There are several options on the right hand side that can be used to tweak the properties of the simulation. I spent alot of time playing around with these, there are some really cool effects you can achieve with just simple modifications.
There are so many things I could add to improve this. You can see some of them in a video I made years ago:
There we have some cool stuff like Bloom, forces and multiple rendering layers going on. It would be nice to get those in this sample too.
For now however I think im going to have a break from this sample. I have spent quite a few weeks to get to this point so far, and I think I need a break for a little bit so I can work on other things. I may come back to it soon tho If people are interested or if (probably more likely) I think of some 'cool new thing' that will 'only take 5 mins'.
I have uploaded the source for this sample to Github for people to lookat/fork if they wish:
https://github.com/mikecann/WebGLTerrainicles
Enjoy!
Friday 21 October 2011
Why Developing for WebGL Sucks!
For some time now I have been working with WebGL and have developed a sort of love/hate relationship with it. I love the ability to instantly target millions of people with GPU accelerated code without any plugins or barriers (excluding the targets that dont support it). However as a developer, writing code that takes advantage of WebGL kinda sucks.
Procedural Based
First off is the way you have to structure your GL calls. For example take a look at the following generic bit of webGL harvested from the net:
[codesyntax lang="javascript" lines="normal"]
texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 64, 64, 0,
gl.RGB, gl.FLOAT, new Float32Array(pix));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
texture1 = gl.createTexture();
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 64, 64, 0,
gl.RGB, gl.FLOAT, new Float32Array(pix1));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
FBO = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, FBO);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, texture, 0);
FBO1 = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, FBO1);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, texture1, 0);
if( gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)
alert(err + "FLOAT as the color attachment to an FBO");
[/codesyntax]
All it does is create a couple of textures, setting their starting values and creates two frame buffers for rendering to. Its just it looks complicated and difficult to understand.
GL works on a procedural basis, so you tell GL that you are about to work on something by calling a function like "bindTexture()" then on the next line you perform an operation on it such as "pixelStorei()". Now this may have made perfect sense back when we were writing everything in C which is procedural anyway however this is Javascript (or haXe in my case) which is an Object based language, code like this is difficult to understand and follow.
The procedural nature of WebGL means you have to be much more careful about unsetting things you have previously set. For example if you bind a texture to perform some operation, you must then remember to unbind it else you could inadvertently cause operations to be applied to it on subsequent calls elsewhere in your codebase. It this 'hidden state' that has caused me alot of headaches when developing my samples.
The principal behind WebGL was to provide a very low-level library which other developers can build upon to build more complex and abstracted libraries. And there are numerous libraries out there. I personally have tried several of them including the very popular three.js. Three.js is great for doing common things like loading models and putting quads on the screen. I however encountered a problem with render targets which I struggled with for days before I discovered that you had to set "needsUpdate" to true on your texture before using it. In the end I decided to drop three.js beacuse of another issue I encountered and instead attempt to reduce my complications by working with webGL directly.
Flash11's Stage3D has the same philosophy as webGL, to provide a low level API for other developers to build libraries upon. The thing is Flash11's low-level API makes more sense and is more readable. For example the following to me is much more readable than its webGL equivalent:
[codesyntax lang="actionscript3" lines="normal"]
texture = c.createTexture(logo.width, logo.height, Context3DTextureFormat.BGRA, false);
texture.uploadFromBitmapData(logo);
[/codesyntax]
The Stage3D API also uses language like "upload" to let you know when you are transferring data to the GPU, for a new comer to GL you have no clue when things are going to the GPU. Its small things like this that reduce the "WTF?" factor when tackling the tricky world of hardware-accelerated 3D programming.
Cross-domain textures
This one cropped up around July time this year and took me ages to work out what was going on. For some inexplicable reason (or so it seemed) my code one day stopped working. When I looked for demo code online it all worked fine, however when I downloaded it and run it locally it also didnt work. I was getting errors like the following:
Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18
I was so baffled that I posted about it on the HaXe mailing list asking for help, thinking it was something I was doing wrong with HaXe. It turns out (after much wall-head-butting) this was a change that they brought into Chrome 13 and Firefox 5 to combat a security problem when using shaders that use textures from a different domain to the one running the code:
http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
Now I have no problem with cross-domain issues, im used to this from Flash where we have the same sort of setPixel() restrictions on cross-domain BitmapData's. The thing is, it appears that this restriction applies when running code locally too. So If you are developing something on your local machine and trying to access a texture from disk it throws the same security errors because the browser thinks you are reaching across domains to access the image.
At the time the only way to get around this was to create your own webserver that you run on localhost to server up the files. So to do that I had to download python so I could run a simple localhost commandline webserver from my bin directory. What an effort! There may be easier ways these days to solve it but at the time it really frustrated me and formed yet another barrier to developing webGL.
No Error Messages
This is by far the most annoying thing about developing for WebGL. So many times I have been trying to write something that I know SHOULD work but for some reason it doesn't. I dont get any error messages, nothing. It makes writing something from scratch neigh on impossible.
In my last post "GPU State Preserving Particle Systems with WebGL & HaXe" I started with an idea. I attempted to code it 'bottom-up'. That is start with nothing and then add more code until I reached what I wanted. Unfortunately having no error messages in WebGL makes this very difficult indeed. I would spend some time writing something really simple, like trying to get a textured quad to render on the screen only to find I get nothing. I double check my camera matrices my vertex and texture buffers, my shader and still nothing. Eventually I found that I hadn't bound something first before trying to operate on it *sigh*
In the end I found the best way to get anywhere is to go from the other direction, a 'top-down' method. Start with something kind of simmilar to what you want then cut bits out one line at a time until you get what you want. Its extremely time consuming and frustrating, but its less frustrating than going from the other way.
There are tools out there that help with debugging what is going wrong. Namely the WebGL Inspector (see above) is intended to provide gDEBugger / PIX like debugging information about what is going on inside webGL. Its a clever bit of tech, it lets you inspect buffers and traces each gl call, however it suffers from the same underlying problem of having no errors. You setup a buffer incorrectly and what you get is "INVALID_VALUE". No indication as to which of the values is invalid or what part of the call you messed up on :(
Googling Doesn't Help
If you do happen to get an error message (unlikely) or you word your problem in a sufficiently succinct and googaleble way you will then run into the next big problem with WebGL; theres very few people using it. Now I know I am likely to be flamed for that comment, but it just seems that way to me. Whenever I tried to google my problem, or google for what I was trying to achieve (because working bottom-up doesnt work) there would be a very sparse smattering of relevant posts. Usually the results are forum posts and are OpenGL not WebGL related and are from 5-10 years ago.
But..
Now having just ranted on for several hundred words about why it sucks im going to finish it off by saying that im going to continue to develop for WebGL using haXe regardless. Why? Well I just like making pretty things that run fast and GPGPU programming appeals to me for some unknown (likely sadistic) reason.
Labels:
Flash,
Javascript,
opengl,
Programming,
rant,
textures,
threejs,
WebGL
Thursday 20 October 2011
GPU State Preserving Particle Systems with WebGL & HaXe
Well this is the post I didnt think was going to happen. I have been struggling for weeks with this little bit of tech, ill explain more about why it has been so difficult in another post. For now however, ill just talk about this sample.
So the idea was to build upon what I had been working with previously with my stateless particles systems with WebGL and HaXe. The intention from the start was to replicate some of my very early work (from 2007) on state preserving particle systems in WebGL.
Before I go any further, you can check it out in action here:
http://mikecann.co.uk/projects/HaxeWebGLParticles/
First a quick reminder. The difference between a stateless and state-preserving particle simulation is that in the latter we store and update the positions, velocities and other properties of each particle per frame, allowing us to interact and control the simulation. This differs from the stateless particle simulation (detailed in my previous post), where the position for each particle is calculated each frame based on a fixed algorithm.
A fairly reccent addition to WebGL made this possible, namely texture lookups in the vertex shader (aka Vertex Texture Fetch). I wont go over the exact details how this makes state preserving particle systems possible as I have already documented it in my earlier work. A brief explanation is that it allows you to use the fragment shader to perform the updates on particle state stored in textures then use the vertex shader to map those states to a point-sprite vertex buffer.
Basically what this means is that the entire particle simulation can be contained and updated on the GPU, which means no read-back. This allows us to achieve simulations of millions of particles without too much difficulty (depending on GPU ofcourse).
I have uploaded the source for people to perouse at their leisure:
https://github.com/mikecann/HaxeWebGLParticles
As usual it was written using the JS target of HaXe so it should be fairly easy to understand whats going on if you have written any Ecma-script-like-language. Im going to detail this in my next post, but the code isnt the best I have ever written as its a result of a mish-mash of various samples and examples I have found on the web. If anyone has any comments on things that are wrong or could be done better I would be very happy to hear about them.
Labels:
complex,
GLSL,
gpu,
Hardware,
haxe,
HTML5,
Javascript,
Particles,
Personal Projects,
Programming,
WebGL
Thursday 13 October 2011
Game of Life HaXe & NME on iOS
For the last few days I have been playing around with trying to get the game of life sample from my previous post working on the iPhone using haXe with NME.
In theory NME should do all the heavy lifting for you so that it should be as simple as running:
[code lang="text"]
[/code]
Unfortunately however when I ran this I was getting rather cryptic errors:
[code lang="text"]
[/code]
I had read from the NME documentation page that this may have been fixed in the more reccent versions of NME. So I downloaded the beta version (you could checkout from SVN too if you wish) and told haxelib that im going to be working with a development version of NME with the following command:
[code lang="text"]
[/code]
Now when I try to build for ios I get success!
From there is a simple matter of opening the generated xcode project, connecting my iphone and hitting run:
I really like how easy the workflow is compared to the Adobe Air packaging system. Generating the xcode project makes things so much faster.
If I can get my hands on an Android phone next I think im going to have to have a go at getting this sample working on there too!
In theory NME should do all the heavy lifting for you so that it should be as simple as running:
[code lang="text"]
haxelib run nme build nmebuild.nmml ios
[/code]
Unfortunately however when I ran this I was getting rather cryptic errors:
[code lang="text"]
Called from ? line 1
Called from InstallTool.hx line 384
Called from a C function
Called from InstallTool.hx line 70
Called from a C function
Called from installers/InstallerBase.hx line 61
Called from installers/InstallerBase.hx line 668
Called from installers/InstallerBase.hx line 762
Called from haxe/xml/Fast.hx line 59
Uncaught exception - icon is missing attribute name
[/code]
I had read from the NME documentation page that this may have been fixed in the more reccent versions of NME. So I downloaded the beta version (you could checkout from SVN too if you wish) and told haxelib that im going to be working with a development version of NME with the following command:
[code lang="text"]
haxelib dev nme /Users/mikec/Documents/NME_3.1_Beta
[/code]
Now when I try to build for ios I get success!
From there is a simple matter of opening the generated xcode project, connecting my iphone and hitting run:
I really like how easy the workflow is compared to the Adobe Air packaging system. Generating the xcode project makes things so much faster.
If I can get my hands on an Android phone next I think im going to have to have a go at getting this sample working on there too!
Sunday 9 October 2011
Conway's Game of Life in haXe [NME & MassiveUnit]
The second day of try{harder} was dedicated to a single topic; test driven development (TDD).
The group was split into pairs and given the task of using TDD to write a solver for the game of life in AS3. After an hour we then threw away everything we had done, swapped partners and repeated the process.
This was extremely valuable for me as I had never written a unit test before. Seeing how different people tackled the same problem was fascinating and informative.
After repeating the process three times Stray asked if I was interested in teaming up with another attendee of the conference Alec McEachran to investigate unit testing in haXe. It was a great idea as it meant we both could investigate how unit testing worked in haXe and it would give me another code example for my talk the following day.
After a brief search we decided on Mike Stead's MassiveUnit for testing as the testing syntax looked similar to FlexUnit and it contained a toolchain for running the tests on multiple platforms.
An example of a test we wrote is:
[codesyntax lang="actionscript3" lines="normal"]
package ;
import massive.munit.Assert;
import Grid;
/**
* ...
* @author MikeC & Alec McEachran
*/
class GridTest
{
public var grid : Grid;
@Before
public function before():Void
{
grid = new Grid(3, 3);
}
@After
public function after():Void
{
grid = null;
}
@Test
public function initiallyThereAreNoLiveNeighbors():Void
{
var liveNeighbors = grid.getLiveNeighbors(1, 1);
Assert.isTrue(liveNeighbors == 0);
}
@Test
public function liveNeighborCountIsAccurate():Void
{
grid.set(0, 0, true);
grid.set(1, 0, true);
grid.set(2, 1, true);
var liveNeighbors = grid.getLiveNeighbors(1, 1);
Assert.isTrue(liveNeighbors == 3);
}
}
[/codesyntax]
It should look fairly familiar to anyone who has used FlexUnit before. The metatags @Before @After and @Test perform in exactly the same way as they do in FlexUnit. Another benefit of using munit over the built in testing framework in haXe is that you are given a tool to run tests on all platforms simultaneously:
[codesyntax lang="text"]
haxelib run munit test test.hxml
[/codesyntax]
When executed you get something that looks like the following:
Which presents a nice graphical representation of the tests run and which failed (if any).
Once built and tested we decided to give the code a simple visual representation. We wanted to show off the ability for haXe to target multiple platforms. To do this we decided to go with NME which I had been experimenting around with recently.
NME is a library and tool chain for haXe designed to allow the developer to use the flash API on multiple platforms. They achieve this by writing platform targeted version of the flash API. So what this means is code such as the following:
[codesyntax lang="actionscript3" lines="no"]
package ;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.geom.Rectangle;
/**
* ...
* @author MikeC & Alec McEachran
*/
class Render
{
private var _cellSize : Int;
private var _renderTarget : BitmapData;
private var _rect:Rectangle;
public function new(container:MovieClip, cols:Int, rows:Int, cellSize:Int)
{
_cellSize = cellSize;
_renderTarget = new BitmapData(cols * cellSize, rows * cellSize, false);
container.addChild(new Bitmap(_renderTarget));
_rect = new Rectangle(0, 0, _cellSize, _cellSize);
}
public inline function lock():Void
{
_renderTarget.lock();
_renderTarget.fillRect(_renderTarget.rect, 0xff0000);
}
public inline function renderCell(x:Int, y:Int, isLive:Bool):Void
{
if (isLive)
{
_rect.x = x * _cellSize;
_rect.y = y * _cellSize;
_renderTarget.fillRect(_rect, 0);
}
}
public inline function unlock():Void
{
_renderTarget.unlock();
}
}
[/codesyntax]
Will compile down to flash, c++ and Javascript! NME also includes packaging abilities for webos, android and ios. So with a few scripted command lines you can target most app marketplaces:
[codesyntax lang="text"]
haxelib run nme test YourProject.nmml flash
haxelib run nme update YourProject.nmml ios
haxelib run nme test YourProject.nmml webos
haxelib run nme test YourProject.nmml android
haxelib run nme test YourProject.nmml cpp
haxelib run nme test YourProject.nmml cpp -64
[/codesyntax]
What it means for this project is we could very quickly get a view for our game of life running in flash, JS and native desktop.
To show just how easy it is I made the following video:
You can see the HTML5 build here: http://mikecann.co.uk/projects/gameoflife/Export/html5/bin/
And the flash build here: http://mikecann.co.uk/projects/gameoflife/Export/flash/bin/MyApplication.swf
I have uploaded the source for the project here: http://mikecann.co.uk/projects/gameoflife/gameoflife.zip
Labels:
Flash,
haxe,
HTML5,
nme,
Personal Projects,
Programming,
testing
Saturday 8 October 2011
try {harder} - my haXe slides and code
This week was a week of firsts. It was the first meeting for the try {harder} conference. It was the first flash conference I have ever attended and it was my first time speaking infront of a group of my peers on a topic I feel passionate about.
The idea behind the conference was to introduce a smaller (16 people), more intimate conference environment where the key was to learn and inspire. And in that goal it certainty succeeded.
The fact that everyone had to give a talk encouraged attentiveness and participation as you knew it was only a matter of time before you were in the same situation. It also reduced the stress that comes from speaking to so many very intelligent people.
When Stray contacted me to suggest that my talk's topic was to be on haXe I was very uncertain. I didn't feel like I had enough experience with haXe to confidently speak about it having only worked with it for less than a year. It turned out however to be a good thing, it pushed me to find out more about haXe, research some areas I had heard about but never investigated.
When constructing my slides I knew that I could never cover all of haXe as its such a large topic with so many interesting facets. I decided that I should probably concentrate on targeting the talk towards my target audience. That is very experienced Actionscript and Flex developers who probably had heard of haXe but never really had any impotence to pick it up and use it any more.
With that in mind I structured my slides around what I considered the big advantages of haXe over Actionscript or Javascript. I also knew that my audience are all very experienced programmers so I tried to give plenty of code samples and examples.
Anyways, at the end of the day I really enjoyed preparing and giving my first talk at try {harder}. It was well received and I just hope I have succeeded in inspiring some more people into investigating and using haXe.
I wrote my slides in google docs which are viewable online: https://docs.google.com/present/view?id=dc6wvdg5_151frv985w7
The code samples and examples mentioned on slides are uploaded here: http://mikecann.co.uk/projects/TryHarder.zip
Saturday 1 October 2011
Windows Taskbar Monitor v0.3
I have just pushed a few small changes to one of my projects, Windows Taskbar Monitor.
One of the users of the app noted that they find it rather annoying having the animated progress bars and asked whether it would be possible to add an option to disable it. I agreed that it could get a little distracting so I added the option to disable the bars.
While I was there I also added a couple of command line arguments to the app so that you could configure each instance from a shortcut.
The options are:
-bars [true/false]
This tells the app to startup with the bars enabled or not, the default is true.
-type [cpu/mem/net]
This tells which of the three monitors the app should start up with, cpu, memory or network.
One way to get all three to start with different monitors when windows startup would be to use the statup folder in windows.
1) Click the windows start icon, then right click on "all programs" and click open:
2) Navigate to Programs > Startup then make three shortcuts to Windows Taskbar Monitor v0.3 you can rename the shortcuts if you like:
3) For each shortcut, right click and select properties:
4) Now enter your command line arguments in the Target field after the final .exe:
Et voilà when windows starts you should now have three different monitors opening!
I have pushed all the source code and the new binary files to my google code project: http://code.google.com/p/win7-taskbar-mon/
Enjoy!
Saturday 17 September 2011
Vietnam 2011
So I got back from my two week backpack around Vietnam last week and its taken me a while to upload my holiday snaps. As there are some 300+ (thats after trimming down too) of them I have decided to so a short writeup of the trip with some of the highlights.
So those of you interested in the fascinating country that is Vietnam continue on, else stick around, posts of a more technical nature will resume shortly ;)
Tuesday 23 August 2011
Artificial - Iridium [Trance, Electro, House]
Second part in a two part mix, see "Argon" for part 1.
What I have tried to do with these two mixes is present two sorts of music that are really floating my boat at the moment. This second part is a heavyer than the first, encompassing trance, electro and progressive.
Iridium by Artificial on Mixcloud
01. Arty & Matt Zo - Rebound
02. Marco V - Unprepared (Recharged Mix)
03. Sander Van Doorn - Renegade
04. Arnej - Dust In The Wind
05. Sander Can Doorn Feat. Carol Lee - Love is Darkness
06. Jochen Miller - Brace Yourself (Extended Mix)
07. Cold Blue - Lucidity
08. Cramp - Prelude (Extended Mix)
09. Mord Fustang - Lick The Rainbow
10. Spenser & Hill Feat. Lil Jon - Less Go! (Porter Robinson Mix)
11. Axwell - Heart Is King
Artificial - Argon [Tech, House, Progressive]
First part in a two part mix, see "Iridium" for part 2.
What I have tried to do with these two mixes is present two sorts of music that are really floating my boat at the moment. This first part is a much lighter, techhyer, houseyer affair than its counterpart, hence the noble gas Argon.
Argon by Artificial on Mixcloud
01. Nathan Fake - The Sky Was Pink (James Holden Remix)
02. Petter - Everyday Balloon
03. Delavari & Rouzbeh - LaLaLa (Ozgur Can Remix)
04. Who's Who - Klack (Inpetto Remix)
05. Matt Lange - Bad Year Blimp
06. Gui Boratto - No Turning Back
07. Second Left - Traffic Lights
08. Butch - Amelie
09. Deadmau5 & Kaskade - I Remember
Thursday 11 August 2011
5,000,000 Chrome Crawlers? Why not [haXe & WebGL]
Following on from my previous experiments into the world of haXe and HTML5 I have been playing around again with trying to get as many 2D sprites on screen as I can.
I started by reading some posts by google on how to render things fast in HTML5, and it got me thinking. Where I was likely going wrong with my HaXe + Three.js experiments was that I was making a separate draw call to WebGL for each and every crawler. Draw calls are expensive and hence I was reaching the draw call bottleneck at just 2000 sprites being rendered at once.
What I needed to do was batch the draw calls together and render them at once. I knew from my work on XNA you could group sprite render calls together quite nicely. So I started off coding up a WebGL equivillant of SpriteBatch from XNA. I managed to get it kind-of working but as is often the way another thought struck my brain, and I decided to tackle that instead.
My thought was; why not just render everything as 2D point sprites? I remembered from my XNA days you could achieve quite staggering numbers of 2D sprites in DirectX by using point spites.
So after a little bit of fiddling and hacking I managed to get point sprites correctly rendering:
You can play with it here: http://mikecann.co.uk/projects/HTML5SpeedTests/HaXeWebGL/bin/
The great thing about point sprites is that I only use one draw call per frame and the GPU is very good at rendering them. The only bottleneck really is the number of pixels you need to draw. With that in mind if you drop the size of the point sprite down to 1x1 you can render a very large (5million) points at interactive framerates (18fps):
I added a "dont use texture" option just out of interest to see how expensive the texture lookup in the fragment shader was, it didnt seem have much of an effect.
There are a few caveats to using point sprites:
Firstly in WebGL has a limit on how large you can make them currently it differs between graphics cards and browsers, a safe minimum is 64x64 so this means you cant have them and bigger and still want it to work in all situations.
Secondly, and this one is more important I cheated to get the numbers above. In my other experiments with haXe and WebGL I was using the CPU to update the positions of the crawlers each frame, having them bounce off the screen edges. In this point sprites demo however I have the points flowing out of a fountain, the simulation of which is entirely calculated on the GPU. The reason for this I talked about in a paper I wrote for a university project 4 years ago:
If I wasn't to perform the upates on the GPU but instead just use the CPU to update the crawlers that would mean the javascript (CPU) would need to update 5million crawlers each frame then re-upload the point sprite positions back to the GPU for rendering. This would obviously be a bad idea.
So I kind of cheated. The fountain simulation on the GPU isn't the same as my other examples. The crawlers don't bounce off the side of the screen. To make that that happen each crawler needs to somehow preserve its state between frames.
Currently each crawler's position is calculated in the vertex shader each frame like so:
[codesyntax lang="glsl"]
attribute float maxAge;
attribute float startingAge;
attribute float velX;
attribute float velY;
uniform float uTime;
uniform float uPointSize;
varying float invAgeRatioSq;
void main(void)
{
float age = mod(uTime+startingAge, maxAge);
float ageRatio = age / maxAge;
float invAge = 1.0 - ageRatio;
invAgeRatioSq = 1.0 - (ageRatio * ageRatio);
gl_Position = vec4((-velX*ageRatio*0.8), (velY*ageRatio)+(-0.4*age*ageRatio)-0.5, 0., 1.);
gl_PointSize = uPointSize;
}
[/codesyntax]
To preserve state between frames I need to use textures to record each crawlers position and velocity, then using Vertex Texture Fetch a vertices position can be calculated.
That however will have to wait for another evening ;)
I have uploaded the source for this project here incase anyone was interested:
http://mikecann.co.uk/projects/HTML5SpeedTests/HTML5SpeedTests_2.zip
I warn you its ugly and uncommented, however it should be enough of a start for anyone looking to do something similar.
Sunday 31 July 2011
From Dust
Its not often these days that I post about games I have been playing, usually I leave that sort of stuff in the realms of Twitter or social networks.
For "From Dust" however ill make an exception. It's also not often these days that I see some tech in a game and wonder to myself "how the hell did they do that?" or just "wow I have never seen that done before". From Dust made me think both those things this week.
From Dust is a god game that follows in the heels of other god games such as Populus and Black and White. The reason why it has attracted my attention so much is the incredible tech that the game employs.
Check out this tech-demo / trailer for the game:
When I watched that earlier in the week I was amazed but skeptical that everything shown was actually how it was in game. After downloading and playing it on xbox this week however I can confirm that everything shown in the above video is in game and more. Not only that its actually fun!
The water flows from the top of the mountains realistically, over time it erodes the landscape to form rivers. Water pressure builds up need harder rock causing bends in the river that threaten your villages. You have to think ahead about how to divert a river one way but making sure not to flood an area downstream. More often than not it takes several tries to get it right.
Lava is great. Several missions have volcanoes that you must be swift to tame else they can easily threaten your villages. The great this however is that there are many ways you can choose to solve a particular problem.
You could just manually suck up all the lava and drop it somewhere else, a somewhat temporary solution. You could try to build a channel for the lava to follow however lava has a habit of melting through any channels you build. You could use one of the spells your villagers to supply to aid you. You could divert the course of a river to cool the lava as it nears your village. You could use a "water tree" to cool the oncoming flow of magma. The choice is yours.
I have been pondering over the tech and thinking how they managed to get such a complex liquid simulation to run in realtime. Infact, how they managed to get several complex liquid simulations to run in realtime. The sand, the water, the lava and the rock all act as liquids with different properties, however they all interact with each other in different ways. Not only is the liquid tech impressive, the vegetation propagation and the fire mechanics are all seamless, and from what I could tell not a single frame was dropped.
It must be a GPU based liquid simulation (particularly as the xbox CPU is weak), however I didn't think they were good enough to do something like this. Perhaps they are using some optimized Smooth Particle Hydrodynamics such as that employed by Fairlight from the scene: http://directtovideo.wordpress.com/2011/05/03/numb-res/
Anyways, the game is available for download right now on xbox or if you are like me and are pc-inclined then it should be available on PC from the 17th of August.
Labels:
from dust,
Fun amp; Videos,
Games,
god game,
liquid,
pc,
Physics,
simulation,
xbox
Thursday 21 July 2011
FlashDevelop Obsidian Dark Theme For HaXe
Just a quick update this evening.
In an effort to to reduce some of the symptoms of eye strain I have been suffering from recently I decided to change the theme of FlashDevelop4 to something a little darker and easier on the eyes.
I took inspiration from the excellent Obsidian theme on the Eclipse Color Themes website.
Im still yet decided if it helps atall, tho I must admit I do like my IDE a little more colorful :)
I have uploaded the theme for download here: http://mikecann.co.uk/
Once downloaded just double click it to install, then restart FD, simples!
After posting the theme to the HaXe mailing list several people linked the themes they use, so if you are interested there's more themes here.
Sunday 10 July 2011
More HTML5 & HaXe Speed Tests
Ive spent a little more time this weekend looking at some more HTML5 with HaXe. Following on from my previous experiments with WebGL I decided to give HTML5's Canvas a a look as it was supposed to be designed specifically for the purpose of doing 2D.
I had heard from the HaXe mailing list that the Jeash project was a common way of interacting with the canvas in HaXe. Jeash is a remapping of the Flash API into JS so in effect I should beable to take any of my usual flash code, Sprite's, BitmapData's, etc and it should run on the canvas no problems. Nice!
So I coded up a quick blitting example to see what sort of performance I would get:
http://mikecann.co.uk/projects/HTML5SpeedTests/HaXeJeash/bin/
The results were okay (I get about 11FPS with 5,000 crawlers) however I was interested to know what sort of cost HaXe adds. So I decided to code up a second example, this time using pure JS:
http://mikecann.co.uk/projects/HTML5SpeedTests/JSCanvas/
The results this time were better (14FPS with 5,000 crawlers) so I now wondered what happens if I do without Jeash and just code up the example using pure HaXe. I was expecting to see the same sort of performance hit as Jeash:
http://mikecann.co.uk/projects/HTML5SpeedTests/HaXeCanvas/bin/
Surprisingly it actually runs faster (17FPS with 5,000 crawlers) ! This is quite a surprise and totally contradicts my notion that going from HaXe -> JS would incur a cost. I was expecting some cost, but a performance increase?! I can only speculate that behind the scenes the JS engine in the browser is able to JIT compile the HaXe JS much better than the hand-crafted JS and hence more speed.
If you are interested in the source then I have uploaded it here: http://mikecann.co.uk/projects/HTML5SpeedTests/HTML5SpeedTests_1.zip
P.S. All the test were run on Windows 7 x64 in Chrome 14 (dev)
Thursday 30 June 2011
30 Days 30 Photos - 2011
For the last 30 days me and some friends have been taking one photo every single day.
Why? No reason other than we can really. We did it a couple of years back and it was good fun, so thought it would be worth repeating :)
You can see a rather nice slideshow of all the images which I have uploaded to my Web Album.
I took each one using Instagram for the iPhone so all of them can also be found on my Instagrid.
I really enjoyed it although I must admit it was hard to find something worth photographing each day. I also wish I was better at taking pictures, but perhaps now I have a good camera Ill learn.
Sunday 19 June 2011
PostToTumblr 0.8 - 8000 Users and Counting
I cant believe how well my humble little extension for the chrome browser is doing. 8000 users when just a few months ago I was celebrating 1.5k.
There were so many requests for new features and things that I thought I would push an update out this evening to add a little more functionality.
From the change log:
- v.0.8 -- 19/06/11 --
+ Text, Page, and Links are now supported in addition to Images
+ Added an app icon to the bar for easy access to the options
To highlight these new changes I decided to update the promo video too:
I have also added a donation button into the options. I have no idea if anyone will click it, an interesting experiment tho.
If you have it installed it should auto-update, if not go grab it over on the chrome app store: https://chrome.google.com/webstore/detail/dbpicbbcpanckagpdjflgojlknomoiah
Bye Bye IntenseDebate, Hello Disqus
Just a quick post. I have swapped over my commenting system from IntenseDebate over to Disqus. I really didnt like some things IntenseDebate did. It also seemed to get alot more spam which I had to manually approve / disapprove all the time.
Hopefully all the comments should have been preserved in the move over.
Sunday 12 June 2011
Chrome Crawler, HaXe, Three.js, WebGL and 2D Sprites
Had a little free time this weekend so thought I would scratch an itch that has been bugging me for a while.
I started the second version of my Chrome Crawler extension a little while back. I have been using the language HaXe to develop it in. It's a great language and I wanted to explore its JS target a little more so I thought, why not make a chrome extension using it. I have had several emails from various people requesting features for Chrome Crawler so I thought I would extend the extension and rewrite it in HaXe at the same time.
I managed to get the basics of the crawler working a few months back but through lack of time got no further. The second thing I wanted to work on after the basic crawling code was how to represent the crawled data. The current method is simply as a list:
A while back however I recieved a mail from "MrJimmyCzech" who sent me a link to a video he had made using Chrome Crawler and Gephi:
As you can see its pretty cool, visually graphed out as a big node tree.
So it got me thinking, can I replicate this directly in Chrome Crawler? To do this I would need to be able to render thousands of nodes and hopefully have them all moving about in a spring like manner determined by the relationships of the crawled pages.
The first thing I tried was using the HaXe version of the Raphael library. The library is designed for graphing and uses the Canvas with SVG for rendering, so I thought it would be perfect for replicating Gephi. I tested it however and only managed about 300 circles moving and updating at 25FPS:
300 nodes just wasnt going to cut it, I needed more.
Enter the recent HaXe externs for Three.js and its WebGL renderer. Three.js is rapidly becoming the defacto 3D engine for Javascript and takes alot of the headaches away from setting up and rendering to WebGL.
After a little jiggery pokery with the still very new externs I managed to get something running:
Thats 2000 sprites running at 25fps which is less that I would have hoped for WebGL but still probably enough for ChromeCrawler. Im not too sure why the sprites are upside-down, nothing I can do seems to right them, perhaps someone can suggest the solution?
If you have a compatible browser you can check it out here. I have also uploaded the source to its own project if you are interested.
The next step is to take the data from the crawl and then render it as a node graph, exiting stuff!
Saturday 14 May 2011
Chrome Crawler v0.5
Just a quick update to my Chrome Crawler extension for chrome this afternoon after I received an email from Vinit Agrawal who had spotted and fixed a bug in the code :)
This is likely to be the last update of Chrome Crawler in its current form. Im currently working on a HaXe version of the extension which I hope will be better!
Anyways, it should update automatically but if not head over to the extension page: https://chrome.google.com/webstore/detail/amjiobljggbfblhmiadbhpjbjakbkldd
Monday 9 May 2011
Instagrid
I have just returned from a little trip to Germany.
While I was there I made extensive use of the Instagram app for iPhone. Its a great way to make normal pictures taken on your phone look semi good.
The only problem is that there is currently no web interface for the app, so all those great pictures you take cannot be shown off in a gallery format unless you "share" the image to a stream such as flickr or tumbr or something.
Third-party-apps to the rescue! Instagrid is one of many web apps designed to plug this gaping hole in Instagram. Its quick and easy to setup so I have done so:
http://instagrid.me/mikeysee/
Now all my instagram pics are easy to get at, splendid!
Sunday 24 April 2011
[Demoscene] Numb Res by Fairlight & CNCD 2011.1
This weekend was The Gathering, a massive gathering of nerds and gamers in Norway. What started out as a humble demoscene party has blossomed into a 5 day gathering of some of the best gamers and scene groups around.
The following is the offering by the ever excellent CNCD & Fairlight. I posted a particle-tastic video by them last year so if you like this sort of thing I strongly recommend that you check that out too.
Edit: Oh if you like the music on this video you should check out the artist album, its bloody fantastic! http://stereowildlife.co.uk/
The following is the offering by the ever excellent CNCD & Fairlight. I posted a particle-tastic video by them last year so if you like this sort of thing I strongly recommend that you check that out too.
Edit: Oh if you like the music on this video you should check out the artist album, its bloody fantastic! http://stereowildlife.co.uk/
Monday 11 April 2011
URI Parser For HaXe
Continuing on my theme of the moment haXe, I have another post regarding the development of my haXe rewrite of ChromeCrawler.
I was in need of a way to split a URL into its various parts. To do this in previous versions of ChromeCrawler I used a ready built one I found on the web.
I thought it should be a fairly simple matter to port this to haXe, unfortunately however this wasn't the case. The problem was that haXe, unlike JS, doesnt have the exec() method on its regular expression function. What this meant is that the URL couldnt be split in the same way.
Confused I jumped on the haXe IRC, unfortunately the solutions the kind people there provided didnt work. Instead I posted a message on the mailing list and within a few hours I had my answer. The solution was to use EReg.match() then EReg.matched() to get each part.
Anyways, I promised to share the code when I was done so here it is:
[codesyntax lang="javascript"]
[/codesyntax]
So for example the following use:
[codesyntax lang="javascript"]
[/codesyntax]
Will print the following:
[codesyntax lang="text"]
[/codesyntax]
Simples!
Im not sure how performant the reflection usage would be on the various platforms haXe targets but atleast it would work and its fairly elegant to boot ;)
Edit: Thank you Adrian Cowen for posting this as a haXe snippet: http://haxe.org/doc/snip/uri_parser
I was in need of a way to split a URL into its various parts. To do this in previous versions of ChromeCrawler I used a ready built one I found on the web.
I thought it should be a fairly simple matter to port this to haXe, unfortunately however this wasn't the case. The problem was that haXe, unlike JS, doesnt have the exec() method on its regular expression function. What this meant is that the URL couldnt be split in the same way.
Confused I jumped on the haXe IRC, unfortunately the solutions the kind people there provided didnt work. Instead I posted a message on the mailing list and within a few hours I had my answer. The solution was to use EReg.match() then EReg.matched() to get each part.
Anyways, I promised to share the code when I was done so here it is:
[codesyntax lang="javascript"]
package utils;
import haxe.Http;
/**
* ...
* @author mikecann.co.uk
*/
class URLParser
{
// Publics
public var url : String;
public var source : String;
public var protocol : String;
public var authority : String;
public var userInfo : String;
public var user : String;
public var password : String;
public var host : String;
public var port : String;
public var relative : String;
public var path : String;
public var directory : String;
public var file : String;
public var query : String;
public var anchor : String;
// Privates
inline static private var _parts : Array<String> = ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];
public function new(url:String)
{
// Save for 'ron
this.url = url;
// The almighty regexp (courtesy of http://blog.stevenlevithan.com/archives/parseuri)
var r : EReg = ~/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
// Match the regexp to the url
r.match(url);
// Use reflection to set each part
for (i in 0..._parts.length)
{
Reflect.setField(this, _parts[i], r.matched(i));
}
}
public function toString() : String
{
var s : String = "For Url -> " + url + "\n";
for (i in 0..._parts.length)
{
s += _parts[i] + ": " + Reflect.field(this, _parts[i]) + (i==_parts.length-1?"":"\n");
}
return s;
}
public static function parse(url:String) : URLParser
{
return new URLParser(url);
}
}
[/codesyntax]
So for example the following use:
[codesyntax lang="javascript"]
trace(new URLParser("http://www.mikecann.co.uk/programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home"));
[/codesyntax]
Will print the following:
[codesyntax lang="text"]
For Url -> http://www.mikecann.co.uk/programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home
source: http://www.mikecann.co.uk/programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home
protocol: http
authority: www.mikecann.co.uk
userInfo: undefined
user: undefined
password: undefined
host: www.mikecann.co.uk
port: undefined
relative: /programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home
path: /programming/haxe/haxe-jqueryextern-gotcha
directory: /programming/haxe/haxe-jqueryextern-gotcha
file:
query: somevar=1242
anchor: home
[/codesyntax]
Simples!
Im not sure how performant the reflection usage would be on the various platforms haXe targets but atleast it would work and its fairly elegant to boot ;)
Edit: Thank you Adrian Cowen for posting this as a haXe snippet: http://haxe.org/doc/snip/uri_parser
Sunday 10 April 2011
HaXe & jQueryExtern Gotcha
As some of you may know, I have been getting into haXe reccently. For those of you dont know what haXe is, this is taken from haxe.org:
haXe (pronounced as hex) is an open source programming language
While most other languages are bound to their own platform (Java to the JVM, C# to .Net, ActionScript to the Flash Player), haXe is a multiplatform language.
I have been aware of haXe for a long time, infact I used to make extensive use of precursor to haXe, MTASC the alternative compiler for AS2. Since the launch of AS3 however, Nicolas Cannasse of Motion-Twin has moved onto HaXe, and the project has flourished.
I have used HaXe in the past for various small projects, usually to take advantage of some of the features that the language offers Flash developers that AS3 cant offer us. Features such as function inlining and the fast memory ops mean that flash developers can really get some great performance out of their libraries while at the same time still able to compile to SWC's.
Recently I have been exploring the various other targets offered by haXe, not just the flash one. Currently haXe supports the following targets:
Javascript : You can compile a haXe program to a single .js file. You can access the typed browser DOM APIs with autocompletion support, and all the dependencies will be resolved at compilation time.
Flash : You can compile a haXe program to a .swf file. haXe is compatible with Flash Players 6 to 10, with either "old" Flash 8 API or newest AS3/Flash9+ API. haXe offers very good performance and language features to develop Flash content.
NekoVM : You can compile a haXe program to NekoVM bytecode. This can be used for server-side programming such as dynamic webpages (using mod_neko for Apache) and also for command-line or desktop applications, since NekoVM can be embedded and extended with some other DLL.
PHP : You can compile a haXe program to .php files. This will enable you to use a high level strictly-typed language such as haXe while keeping full compatibility with your existing server platform and libraries.
C++ : You can now generate C++ code from your haXe source code, with the required Makefiles. This is very useful for creating native applications, for instance in iPhone development.
C# and Java targets are coming soon! (from @cwaneck)
The target that has taken my interest recently has been Javascript.
Having recently worked in Javascript on my Chrome extensions PostToTumblr and ChromeCrawler I have gained a better understanding of how JS works and how to code in it. Despite this however I still cant get over what I consider some "very nasty" things in the language. Lack of type safety, nested anonymous functions and lack of proper classes just have my stomach all in knots thinking about them.
So I was extremely happy to discover that haXe now targets Javascript. It meant I could write the next version of ChromeCrawler in type-safe, class-happy haxe and it would simply hide all the nastyness from me once it compiles. (You can ofcourse modify the JS that is exported if you so wish however)
So now, finally to the point of this post. I sat down to write the core functionality of the crawler. To do the URL crawling so far I had been using jQuery's get() method to load an external page.
How was I to use the jQuery library in haXe I wondered. Well thankfully this has already been thought of with the special "extern" keyword: http://haxe.org/doc/js/extern_libraries
Thankfully Andy Li has also already provided an excellent version of the library for haXe in his jQueryExtern project. Using the haxelib command I downloaded the project and started coding.
It wasnt long however before I ran into a compilation issue when I tried to use the static function get() on the JQueryS class:
characters 2-9 : Unknown identifier : JQueryS
This confused me as no matter what I did, I couldn't get the haXe compiler to recognise the class. Having spent an evening stuck on the problem I decided to email the creator of the project Andy Li.
It turns out that to beable to use the JQueryS class you must first import the JQuery class:
import JQuery;
Low and behold that worked!
As I couldn't find the solution to this problem on a Google search I thought I would write up the solution myself so that others don't stumble on this rather singular gotcha.
Wednesday 23 March 2011
Liero3D Progress
Just thought I would report on a project my friend Michael Lindholm has been working on for a while now. Its Liero but in 3D! As some of you may know I have dabbled with making a remake of Liero several times in the past.
Anyways, it looks like its coming along nicely. He's gone for a voxel-like engine, with screen space ambient occlusion for shading. Personally I think the effect works really well for the game. Check it out:
If you are interested you should follow his blog for the project: http://liero3d.blogspot.com/
Subscribe to:
Posts (Atom)