Monday, 6 October 2014

Creating a vector-based map editor

With summer finally receding from the south coast this weekend, and the rain starting to take hold, there's nothing to beat closing the curtains, blocking out the weather, and spending a few hours in the warm, cranking out (yet more) code.

This time we added  a few functions to our vector-based collision detection routines - specifically to test for collision between a vector and a circle. Further details and code will be posted when it's been cleaned up a bit. In the meantime, here's the results of testing:

Not immediately obvious from the screenshot, but the testing routine is able to check both "entrance" and "exit" points in a circle and reports back the "closest" to the source (if there is both an entrance and exit point, it returns the entrance point - if there is no entrance point and only an exit point, the line has started inside the circle and if there is only an entrance point with no exit point, the line ends inside the circle).

We've not yet written our ricochet routines for circles (we would expect the angle of ricochet to be the same as the angle of approach with the tanget to the circle, at the point of contact) but this is likely to be more than a few hours work, so we'll need to a whole evening (with nothing on the telly) to work on that one!

So far our collision routines work on two and three intersecting vectors.
What we really need is a whole load of vectors to test against, to create some new, vector-based, line of sight algorithms. Which means we need some kind of map editor.

This weekend offered the perfect opportunity to spend a few hours to practice our (relatively) newly acquired jQuery and php skillz. Using the HTML5 canvas object, some jQuery/jQueryUI plugins, and a bit of homebrew, old-fashioned javascript to pull it all together, we had a simple editor up and running inside a few hours:

The editor allows the user to draw single or multi- lines over some uploaded bitmap graphics. This array of lines will become our collision vectors in the final game. The editor looks nasty, but works. Hopefully Steve can take some time out from his awesome homebuild conservatory project and work some magic on it, to make a half-decent, user-friendly interface. With a decent interface, we'll be able to open up the game and make it fairly "hacker-friendly" and even give users the tools to create their own maps and collision layers for the game(s).

The current interface allows multiple lines to be drawn and each line can represent a different type of barrier or wall in the game. In the screenshot above, we split the horizontal wall into three sections - the middle one (highlighted in yellow) has been set up to be a door which players can destroy.

The "properties panel" shows that this particular line has a no-rebound surface (bullets do not bounce off it) cannot be seen through, and bullets do not pass through it. But it can be destroyed, and has a "strength" of six - it must be shot a number of times, or by a powerful enough weapon, and will then be removed from the board - simulating a door which can be shot off it's hinges! If the player is using doors with windows in them, they can set the "can see through" to yes while leaving the "can shoot through" at no - so any opponents will be able to see playing pieces behind the door, but be unable to shoot directly at them.

In a nod towards making it suitable for many different genres of games, it'd even be possible to create "smoke barriers" - perhaps for WWII wargames or simliar: set a line (or circle) to "can shoot through" but "cannot see through" and you've simulated an area of smoke or thick fog.

In a wild west game, wooden walls and fences can be simulated by setting the surface type to "no rebound" - any bullets hitting the obstacle indicated by these lines are "absorbed" or embedded into it; the same parameters could be used, along with "non-destructable" for a force-field on a spaceship, or some other sci-fi based game. Shiny metal spaceship interiors could be made of walls with "smooth" surfaces, which reflect laser beams perfectly (the ricochet angle is a mirror of the angle the laser hit the wall). Stone walls could be made of "rough" surfaces: these lines create a ricochet angle and then randomize it by, say, 20%, and maybe reduce the "exit" velocity by 30% or so.

Many different types of wall surface can be simulated by tweaking a few parameters for each line on the collision layer.

The amount of cover offered by each line/wall can also be simulated by giving each line a "cover" percentage. This could represent the percentage chance of the bullet hitting the wall, or passing through (or over it). So a low wall might offer 75% cover. This could simulate a player hunkering down low, out of the line of fire, but popping up every now and again to see what is going on: every three out of four shots would hit the low wall, but maybe every one in four might happen just as the character taking cover peeks out over the wall?

A wooden picket fence might have a 50% cover - this represents the gaps and slats in the wooden fence - some shots would be embedded into the wood, and some might find their way through and hit their target.

There are loads of possibilities for different terrain types, and ways to implement rules for cover and destructible terrain. Once we've finished this map editor, we'll be able to load a few maps into our new vector-based collision detection routines and see how they perform!