6th May 2012
Filter-based movement
Introduction
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
automata.
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.
Proper movement
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.
Advert
Discussion
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
should move.
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.
Functions covered
- displacementMapFilter : With a suitable 'looped' displacement bitmap, enables discrete object movement.
Advert
Comments