Section6: Making the seagull react to the mouse

This section describes how to make the seagull react to the user's mouse. When the user clicks and holds down the left mouse button, the seagull can be dragged across the screen. When the mouse button is released, the seagull returns to its original path. First construct the seagull in the same manner as the weather vane in Section 4, and apply its flight path to it.

seagullSynth seagull = new seagullSynth(_actualPath);
GeometryBvr gull = seagull.getGeo(true, geoBase)
.transform(translate(toBvr(0), toBvr(.5), toBvr(0)));

The original path is then constructed with the help of the figure8 utility method. This method uses the spline method to return a path in the form of a figure8.

Vector3Bvr subPath =
(Vector3Bvr)(add( DxmVector3.figure8(),
vector3(sin(localTime),
sin(mul(localTime, toBvr(.25))),
sin(mul(localTime, toBvr(.33))))
.mul(toBvr(.25)) )).runOnce();
_originalPath = (Vector3Bvr)
subPath.transform(
compose( rotate(xVector3, toBvr(Math.PI/8)),
rotate(yVector3, toBvr(Math.PI/2)) ))
.substituteTime(div(localTime, toBvr(2)));

Next an event is created that triggers when the left mouse button is pressed on the pickable image that was created in section 3.

_grabEvent = andEvent(leftButtonDown, allSprites.getPickEvent());

Construct two class objects. Their classes handle the behavior of the bird when it is grabbed, and when it is released.

_grabbedNotify = new grabbedBird(this);
_thrownNotify = new thrownBird(this);

The grabbedBird is a callback just like the Breeze class in Section 2. It links the movement of the bird to the position of the mouse pointer.

class grabbedBird extends Statics implements UntilNotifier {
private lhouseModel _model;
public grabbedBird(lhouseModel model) {
_model = model;
}

Now in the notify method you can do some actual work.

public Behavior notify(Object eventData, Behavior curBvr, BvrsToRun lst) {

Grab the position of the mouse pointer from the eventData tree.

Vector2Bvr offset =
(Vector2Bvr)((PairObject)((PairObject)eventData)
.getSecond()).getSecond();
Vector3Bvr offset3d =
vector3( offset.getX(), mul(toBvr(.75), offset.getY()),
mul(toBvr(-.25),offset.getY()) ).mul(toBvr(30));
Vector3Bvr newPath = add((Vector3Bvr)curBvr, offset3d);
return newPath;
}
}

The thrownBird is a callback just like the Breeze class in Section 2. It returns the seagull to its original path when it's released by the user.

class thrownBird extends Statics implements UntilNotifier {
private lhouseModel _model;
public thrownBird(lhouseModel model) {
_model = model;
}

Now in the notify method you can do some actual work.

public Behavior notify(Object eventData, Behavior curBvr, BvrsToRun lst) {

Obtain actualPath from the lhouseModel class.

Vector3Bvr originalPath = _model._actualPath;

Obtain the initial position of the seagull.

Vector3Bvr pathVector = (Vector3Bvr)originalPath
.substituteTime(toBvr(0));

Create a 3-D vector that contains the postion of the finalPath vector (in class lhouseModel) when throwEvent is triggered.

Vector3Bvr throwVector = (Vector3Bvr)eventData;
Vector3Bvr throwDirection = derivative((Vector3Bvr)curBvr);
Vector3Bvr pathDirection = vector3(toBvr(-1), toBvr(0), toBvr(0));
Vector3Bvr[] points = {
throwVector,
add(throwVector, throwDirection),
add(add(throwVector, pathVector).div(toBvr(2)),
sub(throwDirection, pathDirection)),
sub(pathVector, pathDirection.div(toBvr(3))),
pathVector
};
NumberBvr[] knots = { toBvr(0), toBvr(0), toBvr(0),
toBvr(1), toBvr(2), toBvr(2), toBvr(2) };
NumberBvr[] weights = { toBvr(1), toBvr(1),
toBvr(1), toBvr(1), toBvr(1) };

Create a path from the point of where the seagull was released, to its original starting point.

Vector3Bvr spline = bSpline(3, knots, points, weights,localTime);

Let the seagull fly the path in two seconds, and then return to its original path.

Vector3Bvr throwPath = (Vector3Bvr)
until( spline, timer(toBvr(2)),originalPath);
return throwPath;
}
}

Create a behavior that starts out as _original path, and then changes to the behavior constructed in the grabbedBird class when _grabEvent is triggered.

Vector3Bvr finalPath = (Vector3Bvr)untilNotify(
_originalPath, _grabEvent, _grabbedNotify);

Create an event that gets triggered when the left mouse button is released. Also create an event that snapshots the value of finalPath when throwEvent is triggered.

DXMEvent throwEvent = leftButtonUp;
DXMEvent throwSnapEvent = throwEvent.snapshotEvent(finalPath);

Create a behavior that starts out as finalPath, and then changes to the behavior constructed in the thrownBird class when throwSnapEvent is triggered. This is the composite seagull path that allows the user to grab it, drag it, and release it.

_actualPath = (Vector3Bvr)untilNotify(
finalPath, throwSnapEvent, _thrownNotify);
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.