6th May 2012
In the last article I described one method by which game-data could
be held as a bitmap yet still drawn attractively. In both preceeding articles I considered
filter-based code for dealing with some sort of general process, like wind, or for a cellular
Now, suppose one wished instead to move a large number of objects. I use the term gameplay objects to mean discrete, moving or movable entities like wandering creatures, enemies, and potentially collectable items and so on. The difficulty with using a convolutionFilter-based approach is that there's a very limited bandwidth for individual object data, and that's coupled with a tendency for information to be duplicated or lost. It certainly can used for dealing with many, very simple objects like sand particles, but beyond that one quickly hits the limitations of filters.
It turns out that actual movement is possible, in several, useful styles - with only
a little cunning. If you've read the previous article, you may have guessed that the
displacementMapFilter will have something to do with it - and it does!
As a displacementMapFilter has only one input per cell, there is no merging step - so each cell can use and pass on its entire data (three or four 8-bit channels) to the destination. This is only half the story, however. One cannot simply generate a random 'read-from-a-neighbour' displacement map, since some positions will be addressed multiple times, and some none at all.
The basic 'trick' to making this work for movement is to to recognise that every active position also has to have exactly one output. (Both input and output will generally be neighbouring positions.) If two cells read from the same input then object replication will occur. So, how do these restrictions apply to a 2D bitmap? Well, in theory, to give every position one output, it must be part of a closed loop.
Here is an example with fixed loops:
Filter-based movement of 255 types of object
Use the mouse menu to change iteration speed
This demo uses graphics by ORYX from TIGSource.
In practice for a game, one may have unreachable positions or inputs forming the start of a chain - when an object reaches the last position in the chain, it will be overwritten in the next cycle.
Generating the loops or paths becomes a large part of the burden of implementing this method, and will depend intimately on what you want to do with it.
There are still some difficulties to deal with when using this process to move objects around.
The movement function is a feature of the play-area rather than a responsibility of the object.
Furthermore, displacementMapFilters are 'come-from' rather than 'go-to', so it's the destination
position which pulls the object. This means it isn't trivial for an object to declare how it
Similarly, it may not be acceptable for objects to move without animation from one tile position to another.
As usual, I will say that if any of these are needed badly enough, there are ways of achieving them.
All of these topics, along with many others are potential future articles.
- displacementMapFilter : With a suitable 'looped' displacement bitmap, enables discrete object movement.