Homebrewin’ Tip

This post is a little off the normal beaten track for my blog. I have been so super busy of late on a project that I havent really had any time for technical personal projects.

I have however had time to do a little home-brewing so I thought I would share a little tip I had picked up. A little white back a friend lent me his kit for homebrewing. Its so simple all you have to do is fill a two litre bottle with juice and sugar, add a little yeast and cap it off with a simple valve-cap. Leave it for a few weeks and you have a ‘tastey’ strong beverage.

The problem however is knowing how long to leave it. The instructions say 2-3weeks but that is heavily dependant on a number of factors such as the ambient temperature of the room. At first what I was doing was putting the juice, yeast and sugar in at the same time then giving it a good shake so all the sugar was disolved.

I have discovered a better way of doing things however. If you put the sugar in the bottom then put the yeast on top then gently pour in the juice over it then you get a rough indicator of when the fermentation process has completed. As the yeast grows and respirates it burns its way down through the sugar slowly converting the sucrose to alcohol. What this results in is a slowly shifting yeast layer as it works it way down. When the layer hits the bottom, no more sugar left and the brew is ready for drinking :)

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.

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 2×2 array Tilemap. This 2×2 array holds a single Tile object for every single tile in the world:

<pre>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; }
}</pre>
[/code ]

&nbsp;

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:

<a href="http://mikecann.co.uk/wp-content/uploads/2011/11/tm.png"><img class="alignnone size-full wp-image-1795" title="tm" src="http://mikecann.co.uk/wp-content/uploads/2011/11/tm.png" alt="" width="600" height="357" /></a>

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:

<a href="http://mikecann.co.uk/wp-content/uploads/2011/11/tilescompressed.png"><img class="alignnone size-full wp-image-1803" title="tilescompressed" src="http://mikecann.co.uk/wp-content/uploads/2011/11/tilescompressed.png" alt="" width="256" height="352" /></a>

The shader then performs the neccessary calculations to work out what the UV coordinate in the texture. The Vertex Shader:

1
<pre>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 );
}</pre>
[/code ]

&nbsp;

And the Fragment Shader:

1
<pre>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 );
}</pre>

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:

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;
}

[/code ]

Then I used it like:

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;
	}
}

[/code ]

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!