Defining Sprite Motion
This is part of a series of pages describing the Sprites and Paths dialog. This page
describes the Motion tab.
This tab defines what controls a sprite's motions. The first
field defines which tiles on the sprite's layer the sprite sees
as solid. This affects the sprite's motion in that the sprite is
prevented from moving through solid objects. To define this, you
must have a "Solidity Definition" which can be created
on the Tile Categories dialog. A
Solidity Definition categorizes tiles within a tileset into
categories representing various shapes, such as
"solid", "uphill", "downhill" etc.
In order for the "Solid tiles" list to be populated,
a path must be selected in the "Paths" list. This is
because the path is the only reference a sprite has to the layer
in which it resides, and therefore the only reference to the
tileset which that layer uses. In order for the dialog to know
which solidity definitions are applicable, it must know on which
tileset the sprites using this template will be travelling.
The "Up requires solid" checkbox determines whether
this sprite can go up when there's nothing solid underneath it.
For a sprite that is supposed to be walking on the ground (with a
side view, gravity going downwards) it doesn't make sense for the
sprite to go up whenever it wants. Checking this box ensures that
"Up" will only work when the sprite is in contact with
solid ground. And when this is the case, instead of slowly
accelerating upward, the motion acts more like a jump,
immediately skipping to the velocity specified by "Jump
height" (higher velocity = higher jump). If the
sprite's gravity goes upwards, everything is reversed and "Up
requires solid" effectively becomes "Down requires
solid". Note: This setting does not apply
to 360°/10° sprites! I can't make sense of this setting for
this type of sprite and it's therefore not implemented.
The "Controlled by" setting is the most interesting.
This determines who's responsible for the sprite's movement. The
possible values are:
- Follow approximate path - Try to follow the path
designated by the path setting, but don't stick to it
with inhuman accuracy. This sometimes results in the
sprite having to turn around to go back and try to hit
the point on the path that it missed. One reason you
might prefer this over the next option is that it maintains
the DX and DY properties more accurately, which is good
for platform sprites. Platforms must maintain the DY
property very well in order for other sprites to be
able to land on them reliably.
- Follow path exactly - Ensures that the sprite follows the
path as cleanly as possible. Only a solid wall can stop
it from being exactly on its path.
- Input device - The sprite responds to keyboard or joystick
input (determined by the controller
settings dialog). This should be selected for the
player sprite - at least most of the time. Setting a
sprite as the player does not correlate automatically to
being controlled by the keyboard, rather it just
determines which sprite the map should follow, and which
sprite can pick up inventory and activate special
functions.
- Toward nearest sprite - This setting enables the
"Follow nearest" list (new with version 1.3)
at the right. From that list you can
select which class or classes of sprites this sprite type
will follow. It will always follow the nearest sprite that
matches its criteria. The classes are based on the collision
classes. You can make a sprite a member of a collision class
on the Collisions tab. Selecting
"(All)" from this list allows it to follow the
nearest sprite regardless of its class (Even if it's not
a member of any class). This is the default behavior for
projects before version 1.3.
- Toward player sprite - This sprite always moves toward
the player sprite.
- Follow flat floor - The sprite will move stright left or
straight right as long as there's nothing in its way and
as long as there's solid ground below it. When it
encounters ground that isn't flat, a hole or an obstacle,
it turns around and starts moving the other direction.
- Follow floor and slopes - The sprite will move left or
right regardless of the shape of any ground that may be
below it. It continues in that direction until it can no
longer move in that direction at which point it turns around
and continues as before.
- Follow flat wall - If the sprite is adjacent to a vertical
surface it will start following it up and down. When it
gets to the top or bottom (there's an empty space or a slope
or an obstacle) it turns the opposite direction and follows
the wall back in the same pattern as before. It will not
turn around if a wall on one side of the sprite ends
while an adjacent wall on the other side continues; as long
as the sprite can continue to move straight up or down with
a flat vertical wall touching it, it will continue to move in
that direction. If the sprite is not adjacent to a vertical
surface, it will look for one within 3 sprite widths and move
toward it. If it does not find one, it simply assumes a bias
of going to the right and continues in this direction until it
finds a wall. A motionless sprite along the vertical center
of a wall has a downward bias.
- Follow left wall - Your standard "follow the left wall" path.
Actually a good deal more complicated that one might think
considering all the sprite has to go on is whatever solid
pixels it can find in the vicinity and its current velocity.
The exact details of the algorithm won't be laid out here, but
these sprites can follow horizontal, vertical and diagonal
walls. They never leave a solid wall once they find one (at
least they're not designed to, and I haven't seen one do so
yet, unless a wall disappears while its being followed).
They never turn back to go the direction they came
except for the case where the passage they've entered is a dead
end just wide enough to fit them, but they will be "attached"
to the opposite wall on the way out. This type of sprite will
traverse every wall in the type of maze generated by the maze
generator in the map editor. In the absence of walls, this
type of sprite has a leftward bias.
- Follow right wall - Similar to follow the left wall. This
sprite sticks to the wall at its right and has a rightward
bias in the absence of walls. Another "maze solving"
sprite.
- Follow sloped floor; jump at gaps - This is like "Follow floor
and slopes" except the sprite attempts to jump if it encounters
what looks like a "cliff" which it would not be able to climb
back up if it fell off. This may not work very well if the
sprite is going downhill. (A similar difficulty exists even
when the sprite is controlled by the input device, you can't
always jumps while going downhill because you're not always
touching the ground.) A short ledge before a gap can help.
- Inert - Just like any other sprite except no forces act on this
sprite other than gravity and other sprites (and possibly script
code). It will continue in its current heading if it has velocity
(after being bounced by another sprite or set in motion by script)
and its velocity will decay according to the inertia setting.
- Simple - After discovering that all the coding behind sprites tends
to get pretty slow after about 30 sprites on the map at once, I
decided there needed to be a type of sprite that could squeeze in
every bit of performance and squeeze out every bit of unnecessary
code that I could for those sprites that really didn't need any
help from the code and were perhaps scripted. This type of sprite
does not respond to solidity on the map or collisions with other
objects. The data is all there (in case you want to access it
through scripting) but is not observed by the engine. All "simple"
type sprites are appended to the end of the sprites array while all
other sprites are inserted before the first simple sprite (after
the last non-simple sprite). Whenever GameDev encounters a simple
type sprite, it exits the processing loop it's in and does no
processing for simple sprites. When performing the "advance" loop
(where all the sprites are moved) GameDev will stop at the start
of the simple sprites section and finish with a tight loop that
performs 3 simple actions on the simple sprites: 1) Move the
sprite according to its velocity (no gravity, intertia or speed
considered); 2) Animate the sprite according to its current state.
Normally a sprite animates according to its velocity. A simple
sprite animates as if it were moving 1 pixel all the time; 3)
eliminate the sprite if it's off the edge of the map (which can
be common if there's no solidity stopping the sprite). The only
way to change the state of a simple sprite is through script. It
will not automatically take on a state consistent with its current
direction of travel. This resulted in an (eyeballed) 50% - 100%
performance gain. Not as much as hoped, but worth keeping.
- Path vector - Introduced in 1.4, this will start off with an
initial velocity determined by the direction of the first two
points in its path and then act like an inert sprite. This is
handy for creating bullets or projectiles thrown by the player.
It works better than making the sprite follow a path because
if the sprite hits a solid wall before reaching its target
it will just remain inert instead of continuing to try to reach
the second point in the path. While the direction that
the sprite travels is determined by the vector formed by the
first two points on the path, the speed that it initially
travels is determined by the sprite template's movement speed
setting.
- Follow path random direction - This behaves like "Follow
approximate path" except rather than always heading for
the next point in the path, it will randomly pick the previous
or the next point in the path after reaching a point. It is
possible to select a value other than "Cycle to starting
point" for the "At end of path"
setting, however the results may be awkward or unexpected for
this type of sprite.
- Follow path random points - This behaves like "Follow
approximate path" except rather than always heading for
the next point in the path, it will randomly pick a nearby
point in the path after reaching a point. The range of points
that it can pick from is determined by the distance between the
first and second points in the path. Say the first point is
50 pixels away from the second point. After reaching any point
in the path, the sprite will look for any point within 50 pixels
of the current point to head toward next.
- Strict path random direction - This behaves like "Follow
path random direction" except it follows the path exactly
like the "Follow path exactly" setting instead of
following it approximately.
- Strict path random points - This behaves like "Follow
path random points" except it follows the path exactly
like the "Follow path exactly" setting instead of
following it approximately.
The movement speed setting determines how fast the sprite can
move (maximum speed). The maximum value is 10 pixels per frame
and the minimum value is 1 pixel per frame. For sprites
controlled by anything other than the input device, the movement
speed determines how fast the sprites usually go since
automatically controlled sprites are almost always in motion.
The jump height setting determines how high a sprite can jump
if the "Up requires solid" box is checked. Before version
1.3, this value came from the movement speed setting. When loading
a project older than version 1.3, this setting will default to the
movement speed setting. But now you can specify a jump height higher
(or shorter) than the movement speed setting would dictate. Now
you can get more realistic jumps. Rather than affecting the height
of the jump directly, this setting only affects the vertical
velocity that the sprite adopts when up is pressed while
standing on solid ground. (When down is pressed if gravity goes
upward.)
The gravity power setting determines what kind of gravity this
sprite experiences. Each sprite template can have its own gravity
setting -- there is no overall map or project gravity setting.
The maximum value in either direction is 1 pixel per frame per
frame. Since the acceleration speed is also hard coded at 1 pixel
per frame per frame, setting gravity at the most extreme values
exactly counteracts acceleration. For a 360° sprite, this means
that gravity can barely be counteracted when pointing straight
up, but cannot be overcome. For any other type of sprite with
"Up requires solid" checked, since acceleration for
this type of sprite is instantaneous to maximum velocity, maximum
gravity can be temporarily overcome.
The inertia setting determines how much of the
sprite's velocity is retained after each frame. The right end of
the scale corresponds to perfect inertia in which an object in
motion remains in motion (unless it hits something). Setting the
slider to the left end of the scale will cause the sprite to stop
moving immediately when the thrust ceases, unless there is
gravity.
There are two new settings with version 1.3 on this tab:
- Auto delete: This allows you to pick conditions under
which the sprite will be automatically deleted. The available
values have been expanded for version 1.4. You can delete:
- Never: Always keep the sprite active (never
delete it implicitly).
- 1. When off map: Delete the sprite when it goes off the
edge of the map.
- 2. 1 or off display: Delete the sprite when it goes off the
edge of the screen.
- 3. 2 or motionless: Delete the sprite when it goes off the
edge of the screen or becomes motionless (good for
something like a bullet or fireball).
- 4. 1 or hit solid: Delete the sprite when it goes off the
edge of the map or when its velocity is affected by a
solid.
- 5. 2 or hit solid: Delete the sprite when it goes off the
edge of the screen or when its velocity is affected by a
solid.
- 6. 3 or hit solid: Delete the sprite when it goes off the
edge of the screen or becomes motionless or when its
velocity is affected by a solid (even better for bullets
than option 3).
- At end of path: This allows you to pick an action to take
when a path-following sprite reaches the end of its path:
- Cycle to starting point: This is the default behavior for
projects before version 1.3. The sprite heads toward the
first point after reaching the last.
- Jump to starting point: The sprite immediately appears back
at the beginning of the path.
- Delete sprite: The sprite is terminated after it reaches
the end of the path.
- Activate EOP_<SpriteName>*: Allows you to activate
special functions when the sprite reaches the end of its path.
When the sprite reaches the end, all functions on the sprite's
layer are searched and any function whose name matches the
pattern is triggered. The pattern always begins with
"EOP_". This is followed by the name of
the sprite definition and then any text you want. For instance,
if you have a sprite definition "Bomb1" that refers
to template "Bomb", you may want to set the Bomb
template to activate special function EOP_<SpriteName>*
at the end of the path. Then you would need to create a
special function called (for instance) EOP_Bomb1Explode if you
want a function that matches the pattern. Note:
EOP_BombExplode would not match the pattern because
the name of the sprite definition is Bomb1. The pattern does
not use the template name, but the sprite definition name.