I was trying out some HTML5 when I stumbled into this site. I am still a bit unsure about HTML5, but it has its potential. If I manage to finish my tiny project I will show the results on this blog.
Category Archives: Programming
BoardBuilder design
Introduction
BoardBuilder is a factory class used for creating Board model for the Farout game. In following I will briefly go through the design of the BoardBuilder and give you reasoning behind my decisions. In my next post I will go in more detail by showing you some source code and hopefully I have a working example as well.
By creating dedicated builder class we separate construction role from the model role that the Board class represents. It also keeps Board class simpler and makes it possible to change construction process without a need to touch Board’s implementation.
During the construction we have to allocate memory blocks which are no longer needed when construction has finished. By keeping those allocations in builder only it is easier for us to control how memory is used and when it is freed.
Construction process is divided into small simple steps to make source code easier to understand and maintain. As a rule of thumb every function has only one purpose and if I see copy paste code anywhere I will move that code into own function. I prefer a lot of small methods to few monolithic ones, therefore my classes usually have quite long definition.
Below is the static model of the BoardBuilder and after that you can find description of each class and their purpose.
Vertex
Vertex represents single point in 2-dimensional world. It has x and y value defined as floating point numbers.
Segment
Segment represents one line segment that is constructed of two or more Vertices. Vertices are referenced by the Segments. Therefore same Vertex can be used in several Segments.
Hexagon
Hexagon represents one hexagon and is constructed of exactly six Segments. Neigbouring Hexagons share one segment with each other. Segments are referenced by the Hexagon instances, that way we can modify Segment and modifications are instantly visible in every Hexagon referencing the modified Segment.
Region<T>
Region is a tile that is constructed from one or more Hexagons. Region is defined as generic class and the unqualified type parameter is used for referencing the actual region data. Regions own instance of java.awt.Polygon that defines their shape. Polygon class is created because it can be used as a tool for several tasks. E.g.
- To check if certain point is located inside Region (e.g. region.shape().contains(x, y)).
- To mask (clip) textured blitting (e.g. graphics.setClip(region.shape())).
- To draw region borders (e.g. graphics.drawPolygon(region.shape())).
- To get maximum bounds of the Region (e.g. region.shape().getBounds()).
BoardBuilder
Board construction is handled by the BoardBuilder class. Construction parameters are given in a BoardBuilderParameters class. Construction happens in following order.
- Hexagonal Vertices are constructed
- Segments are constructed by connecting proper Vertices
- Hexagons are constructed by collecting proper Segments from all Segments
- Hexagons are dehexified as described in earlier post
- Regions are constructed from Hexagons by combining selected neighbour Hexagons, adjacency is validated when new Hexagon is added to a Region and if the added Hexagon is valid all, except the connecting Segment, are added to the Region
- Shape is constructed for each Region
- Board is created and ownership of the created Regions is transferred to the Board
- Created Board instance is returned to the caller and is ready to be used
About depixelizing
In my search for a solution to make my graphics scalable I heard a rumor about Nintendo having released their pixels-to-vector algorithm as open source! Could this be true? I haven’t found any reliable information of this yet.
What I am talking about is something like Johannes Kopf and Dani Lischinski had developed and described in their paper Depixelizing Pixel Art. Sadly, their solution is not available for public and it seems that I end up looking this paper after every search attempt… There is something going on at the SNES scene, for example xBr 2.2, but real time shaders aren’t exactly what am looking for.
I am starting to like C#’s versatility
I have been coding small utility for my own use. This utility is about parsing rss feeds and juggling with files. Names of the files come from feed, so I may get anything. This project is also a learning project for C# and .NET, so it is not always clear how to achieve certain outcomes.
A problem I faced with file names is that they can contain illegal characters and therefore I would have to strip or replace illegal characters from the original string. How can this be done using C#? The answer is Regular expressions. Just by looking the example below you will see how versatile C# really is.
[scode]
public static string ValidFilenameFromString(string name)
{
string invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars()));
string invalidRegexpStr = string.Format(@”[{0}]+”, invalidChars);
return Regex.Replace(name, invalidRegexpStr, “_”);
}
[/scode]
Deform algorithms for dehexifying process
In my last post I talked about how to make hexagon map look less dull using dehexifying algorithm. I mentioned that we need to deform vertices but I did not give any examples how to do it. As you probably remember we need to do deformation in two steps, first for the hexagon vertices and later for segment vertices.
Deforming the hexagon vertices is pretty straightforward. We just move all the vertices by certain random amount. One thing to remember though, do not move any vertex more than half the width of the hexagon, and tag vertices that have already been deformed because same vertex can be referenced by several hexagons. Below is a very simple deformation algorithm implemented in Java.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
// Vertex
class Vertex {
static Random R = new Random();
public float x;
public float y;
boolean deformed;
public void deform(float range) {
if (!deformed) {
deformed = true;
x += (R.nextFloat() – 0.5f) * range;
y += (R.nextFloat() – 0.5f) * range;
}
}
}
// Hexagon
class Hexagon {
List<Vertex> vertices;
public void deformVertices(int size) {
for (Vertex v in vertices) {
v.deform(size);
}
}
}
[/xscode]
Next I will show the simplest possible segment deformation algorithm. It is virtually same as Hexagon vertex deformation algorithm except for the range of deformation and how it is calculated. I have added Rules class to maintain creation variables. In example below we query segment deformation range from Rules class using method segmentVertexDeformRange() which takes number of vertices in the segment as parameter.
Using the number of vertices as damping factor we have better control of what the deformation result will look like. It is also good for preventing overflows in deformation which would result in silly looking hexagons.
In Hexagon class we just loop through every segment and call deformVertices() for each one. In Segment class deform() is called for each Vertex referenced by the segment.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
// Hexagon
class Hexagon {
List<Segment> segments;
public void deformSegments() {
for (Segment s in segments) {
s.deformVertices(Rules.segmentVertexDeformRange(s.vertexCount()));
}
}
}
// Segment
class Segment {
List<Vertex> vertices;
public void deformVertices(float range) {
for (Vertex v in vertices) {
v.deform(range);
}
}
}
[/xscode]
In this naive solution borders can appear jagged. Jagginess can be controlled by tweaking the Rules, but what if we wanted smoothly curved borders? One possible solution would be the use of splines. Below is a sample implementation that uses Java 2D API for this task.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
class Segment {
public void deformSplines(float range) {
deformVertices(range);
createSplineVertices(range);
}
void createSplineVertices() {
// Create path
Path2D.Float path = new Path2D.Float();
Vertex v = vertices[0];
path.moveTo(v.x, v.y);
for (int i = 1; i < vertices.size; i++) {
Vertex vold = v;
v = vertices[i];
Point2D.Float[] cps = randomControlPoints(vold, v);
path.curveTo(cps[0].x, cps[0].y, cps[1].x, cps[1].y, v.x, v,y);
}
// Collect new vertices from path
List<Vertex> cubicVertices = new ArrayList<Vertex>();
PathIterator pi = path.getPathIterator(null);
FlatteningPathIterator fi = new FlatteningPathIterator(pi, 0.1f);
while (!fi.isDone()) {
float[] p = new float[6];
fi.currentSegment(p);
cubicVertices.add(new Vertex(p[0], p[1]));
fi.next();
}
// Preserve reference starting and ending points
cubicVertices[0] = vertices[0];
cubicVertices[cubicVertices.size() – 1] = vertices[vertices.size() – 1];
// Apply new vertices
vertices = cubicVertices;
}
Point2D.Float[] randomControlPoints(Vertex b, Vertex e) {
Point2D.Float[] cps = new Point2D.Float[2];
float r = b.distanceFrom(e) / 2.0f;
float a = R.nextFloat() * PI_2;
cps[0].x = b.x + r * cos(a);
cps[0].y = b.y + r * sin(a);
a = R.nextFloat() * PI_2;
cps[1].x = e.x + r * cos(a);
cps[1].y = e.y + r * sin(a);
return cps;
}
}
[/xscode]
It is possible to mix naive and curved implementations to create even more realistic looking tiles. Just add random threshold point that will decide which implementation to use for the segment.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
class Segment {
public void deformRandomly(float range) {
if (R.nextFloat() <= Rules.percentageOfCurvedSegments() / 100.0f) {
deformSplines(range);
} else {
deformVertices(range);
}
}
}
[/xscode]
We have seen that using deform algorithms it is possible to create realistic looking map tiles for hexagon maps. Deformation can be done in many ways and I have shown two different algorithms to do this. Next I would suggest you to experiment with different algorithms to generate even more realistic looking tiles.
Dehexifying a hex map. Say what?
Hexagon has appealing characteristics for a map tile. It has six neighbours and the distance from any hexagon to its neighbour is exactly same. More traditional square based map tile has eight neighbours and distance varies from 1 to 1.414.., depending on in which direction particular neighbour is located at. However, they both have one characteristic in common, they look dull.
If you take a closer look at Small World map you will see that map tiles have hexagonal aspect and they do not look dull. Tiles have pretty strong border in high contrast which separates tiles from each other. Hexagon segments have been deformed and the tiles are textured using hand drawn textures with some extra details on top of them. These little finishing touches make them look great and pretty hard to spot hexagon aspect when you look at the map.
As a part of Farout project I have been playing around with Dehexifying algorithm to make hexagon map looks something like Small World map in the image above. Algorithm is simple, yet the results are quite stunning. Algorithm can be divided into following steps:
- Create vertices for hexagon map (in my implementation caller gives number of hexagons in horizontal and vertical direction, and width of one hexagon as parameters)
- Connect vertices into segments, every segment contains exactly two vertices at this point (segments reference to vertices, therefore altering one vertex affects every other segment using same vertex)
- Create hexagons from segments (hexagons reference segments, therefore modifying one segment alters other hexagons using same segment)
- Deform the vertices (this could be done before step 3 it just happens to be 4th step in my implementation)
- Split segments into several vertices. Number of vertices created for segment depends on the segment’s length after step 4. The longer the segment is the more vertices will be created.
- Deform newly created vertices to make segments non planar.
After these six steps hexagon map looks surprisingly lot like a Small World map, depending on how well your deforming algorithms work. One has to remember that this is just a model for the dehexified map – what it really looks like depends on rendering algorithm, which I will talk more about in my next post.