Gaming Your Way

May contain nuts.

Time based movement and tracks/tiles ...

Long time no post, so I thought it might be the time to do so again ...

While still working on the last GOL game ("The Day of the Triffids"), my mind starts wondering off to the next big project, the "logimotion" game.

I do dimmly recall that when doing the Wintertales/Deserrunner game I said something about explanation, but I guess it somehow slipped through just waiting there to be recalled now ...

So here we go:

Time based movement and tracks/tiles ...

While doing the engine I came to the point where I had to move the sprite over the player created tracks, two ways came to mind:

a) write some fancy stuff for each tile, using the sprite and offset it's coords according to the need of the tile.
b) write some fancy stuff that works whth each tile, using some other approach.

I decided to try the latter one.

What bothered me with the first method was that I had to map out coordinates or tween the sprite along the tracks which somehow wasn't what I wanted.

The second method wasn't that clear. I needed to find a way to move the sprite from the starting point of the tile/track to it's end ... after a few pointless tries I thought that I could just do it time based instead of position based.
This proved to be a very easy and re-useable way.

screenie of the car in motion, showing the track, too.

As the car isn't shown top/dow, there needed to be some sort of animation and we wanted to be able to move with different speeds, too.

My first task was to invent some sort of naming convention which helps me to sort the different tiles and tell the code *what* this tile does without adding to much fuzz to the map.

So I decided to use a for digit code like 0011 for a corner from west to south, giving each direction either 1 for "exit" and 0 for "no" exit.
Then I decided to use "easings" to move from the starting point of the track to end point of the track. Moving a stright line (0101, or from west to east) would just ease the x value linear in say 16 frames (and because I had 16 animation frames ... you guess right).

This is what I stored for the tile:

this._tile_array[22] = {sx: 1, sy: 1, t: TileEngineClass.TILE_TRACK, f: "t_0101", d: "0101"};

sx/sy: size
t: tile type
f: frame in the tile mc
d: direction information

And this is what the player sprite "knows":

this._track_array["0101"] = new Array();
this._track_array["0101"][1] = {sx: _x0, sy: _y1, ex: _x2, ey: _y1, fx: EaseUtil.easeLinear, fy: EaseUtil.easeLinear, nd: 1};
this._track_array["0101"][3] = {sx: _x2, sy: _y1, ex: _x0, ey: _y1, fx: EaseUtil.easeLinear, fy: EaseUtil.easeLinear, nd: 3};

sx/sy/ex/ey: start coords/end coords for the easing
fx/fy: easing method for x/y
nd: the new direction after reaching the end point, used for corners mainly.

The sprite knows which direction (0-3, according to the 4 digits of the name) it's moving, the animation it should use ("0101" + frame for the current time) and it's time.

If the sprite reaches the endpoint of the ease, I can look up the next tile in the map array (because if the direction of the next tile is 1, I take the next tile east of the current tile).
If the next tile is empty, well the player creashes.

Easy, isn't it?

Here's the data for a corner:

this._track_array["1100"] = new Array();
this._track_array["1100"][2] = {sx: _x1, sy: _y0, ex: _x2, ey: _y1, fx: EaseUtil.easeInSin, fy: EaseUtil.easeOutSin, nd: 1};
this._track_array["1100"][3] = {sx: _x2, sy: _y1, ex: _x1, ey: _y0, fx: EaseUtil.easeOutSin, fy: EaseUtil.easeInSin, nd: 0};

In order make it faster I just reduce the time needed to get from start to end, though it's a good idea to use something that can be devided by 2, so the animation isn't messed up

You can see it in action: here (German version, though)

Back to the Triffids ...

"Some people are heroes. And some people jot down notes."
        -- (Terry Pratchett, The Truth (us, de))

Comments are closed