HTML and CSS Reference
In-Depth Information
Figure 13-4.
The beginnings of a walk cycle
But it doesn't really look like it's walking. Maybe it's a half-hearted attempt to kick a ball, but it's not
walking. What's happening now is that both segments are moving in the same direction at the same time.
They are in sync, which, if you were to analyze an actual walk cycle, is not how it works.
The segments are in sync because they are both using the
cycle
variable to calculate their angle. To
throw them out of sync, you can resort to using
cycle0
and
cycle1
variables, but you don't need to go
that far with it. Instead, you can offset
cycle
a bit when using it to find
angle1
, like so:
var angle1 = Math.sin(cycle + offset) * 45 + 45;
You need to define
offset
earlier in the code, but how much should
offset
be? Experiment until you find
something that looks good, but here's a hint: It should be a number between
Math.PI
and
-Math.PI
(or
3.14 and -3.14). Anything more or less than that is going to double back on itself. For instance, we use
-
Math.PI/2
, which puts it a quarter of a cycle behind
angle0
. Of course,
-Math.PI/2
is about -1.57, so
you might want to try other numbers around that value, like -1.7 or -1.3, and see whether that looks better
or worse. A little later, we throw in a slider to do it all dynamically. The file with this offset included is in
07-
walking-3.html
.
We should probably add another leg while we're at it. Start by throwing in two more segments, named
segment2
and
segment3
.
segment2
should be in the same position as
segment0
, because it will also be
the top level, or base, of the whole leg, and
segment3
should be positioned using
segment2
's
getPin()
method.
Rather than duplicate all the code that makes
segment0
and
segment1
walk, it has been abstracted into
its own method, called
walk
:
function walk (segA, segB, cyc) {
var angle0 = (Math.sin(cyc) * 45 + 90) * Math.PI / 180,
angle1 = (Math.sin(cyc + offset) * 45 + 45) * Math.PI / 180;
segA.rotation = angle0;
segB.rotation = segA.rotation + angle1;
segB.x = segA.getPin().x;
segB.y = segA.getPin().y;
}