Section3: Including Cell Based Images
Here, begin importing the raw images. If the image has multiple cells
make use of the cellImage1 utility. |
ImageBvr clouds,scene;
cellImage1 kite,ocean1,ocean2,palm1,palm2,palm3,beachboy;
URL mediaBase = getImportBase();
URL imgBase = buildURL(mediaBase, "image/");
URL geoBase = buildURL(mediaBase, "geometry/");
URL sndBase = buildURL(mediaBase, "sound/");
kite = new cellImage1(buildURL(imgBase, "kite.gif"),4);
scene = importImage(buildURL(imgBase, "scene.jpg"));
ocean1 = new cellImage1(buildURL(imgBase, "ocean.gif"),4);
ocean2 = new cellImage1(buildURL(imgBase, "ocean2.gif"),4);
palm1 = new cellImage1(buildURL(imgBase, "palm1.gif"),5);
palm2 = new cellImage1(buildURL(imgBase, "palm2.gif"),5);
palm3 = new cellImage1(buildURL(imgBase, "palm3.gif"),5);
clouds = importImage(buildURL(imgBase, "clouds.gif"));
beachboy = new cellImage1(buildURL(imgBase, "beachboy.gif"),2);
Here, use the synthetic ocean sounds that are explained in Section 5.
The event caused by a crashing wave is used to create an ocean index.
An animateTrees method is called to generate psuedo-random tree
indexes. These indexes will be used with the showIndex method to
determine which tree cell to display. |
oceanSynth ocean = new oceanSynth(add(toBvr(.2),windSpeed));
NumberBvr oceanIndex = animateOcean(ocean.soundEvent());
NumberBvr treeIndex1 = animateTrees(windSpeed, 1);
NumberBvr treeIndex2 = animateTrees(windSpeed, .88);
NumberBvr treeIndex3 = animateTrees(windSpeed, .71);
So how does cellImage1 work? The contructor takes an image and frame count
and imports that image. |
public class cellImage1 extends Statics {
public cellImage1(java.net.URL url, int frameCount) {
super();
_BaseImg = importImage(url);
_FrameCount = toBvr(frameCount);
}
To get a particular frame of the cellImage, the author can make a call to
the showIndex method. This will return a properly cropped image. The
following code calculates the minimum and maximum points of the indexed
image, crops the entire image, then centers the new image. |
public ImageBvr showIndex(NumberBvr index) {
NumberBvr actualIndex = sub(sub(_FrameCount, toBvr(1)), index);
Bbox2Bvr frame = _BaseImg.boundingBox();
NumberBvr cellHeight =
div(sub(frame.getMax().getY(),frame.getMin().getY()),
_FrameCount);
NumberBvr cellMin = add(frame.getMin().getY(), mul(cellHeight, actualIndex));
NumberBvr cellMax = add(cellMin, cellHeight);
ImageBvr cellImg =
_BaseImg.crop(
point2(frame.getMin().getX(), cellMin),
point2(frame.getMax().getX(), cellMax));
ImageBvr cntrImg =
cellImg.transform(
translate(toBvr(0), sub(neg(cellMin),div(cellHeight,toBvr(2)))));
return cntrImg;
}
The loopStrip is a handy method that cycles through all the cells at the
indicated speed (in frames per second). |
public ImageBvr loopStrip(NumberBvr speed) {
return showIndex(
mod(floor(mul(localTime,speed)),_FrameCount));
}
public ImageBvr _BaseImg;
public NumberBvr _FrameCount;
}
Here is how these two methods operate. |
private NumberBvr animateOcean(DXMEvent ev) {
Behavior[] calm = { toBvr(0), toBvr(1) };
Sequence for crashing wave. |
Behavior[] wave = { toBvr(2), toBvr(3), toBvr(2) };
Cycles through the calm values every 0.5 seconds. |
Cycler calmCycle = new Cycler(calm, timer(toBvr(.5)));
Cycles through the calm values every 0.25 seconds. |
Cycler crashCycle = new Cycler(wave, timer(toBvr(.25)));
Use an uninitialized behavior so it can refer to itself. |
NumberBvr animateOcean = NumberBvr.newUninitBvr();
The behavior is calmCycle until ev, then crashCycle for 0.75 seconds,
and then back to the initial state. |
animateOcean.init((NumberBvr)
until(calmCycle.getBvr(), ev,
until(crashCycle.getBvr(), timer(toBvr(.75)), animateOcean)));
return animateOcean;
}
private NumberBvr animateTrees(NumberBvr windSpeed, double seed) {
A jitter method gives a semi-random value that oscillates between
zero and one. |
NumberBvr jitter =
floor(mod(
add(DxmNumber.smooth0to1(mul(sub(toBvr(1.2),windSpeed), toBvr(10*seed))),
(NumberBvr)_breezeInterval.getBvr()),
toBvr(2)));
As the wind speed increases, the trees tend to bend back. To get this
effect increase the cell image used. |
NumberBvr normalIndex = floor(mul(toBvr(3), windSpeed));
The final index jiggles the bent tree. |
return add(normalIndex, jitter);
}
Here, construct moving clouds by translating an infinitely tiled
image of clouds by the windDistance. |
Bbox2Bvr BB = clouds.boundingBox();
Vector2Bvr cloudPos =
vector2(neg(mod(div(windDistance, toBvr(200)),
sub(BB.getMax().getX(), BB.getMin().getX()) )), toBvr(0));
ImageBvr xfClouds = clouds.transform(translate(cloudPos));
ImageBvr movingClouds = xfClouds.tile().crop(BB.getMin(), BB.getMax());
Here, create an array of all the time-varying sprite images, using
loopStrip and showIndex where appropiate. |
ImageBvr[] sprites = {
kite.loopStrip(add(windSpeed,toBvr(.2))),
scene,
ocean1.showIndex(oceanIndex),
ocean2.showIndex(oceanIndex),
palm1.showIndex(treeIndex1),
palm2.showIndex(treeIndex2),
palm3.showIndex(treeIndex3),
movingClouds,
beachboy.loopStrip(toBvr(1))
};
Also create an array of points which will be used as the initial
positions of the above mentioned time-varying sprites. |
Point2Bvr[] spritePos = {
kitePos,
point2(toBvr( 0),toBvr( 0)),
point2(mul(toBvr( 78),pixelBvr),mul(toBvr(-100),pixelBvr)),
point2(mul(toBvr(-252),pixelBvr),mul(toBvr( -21),pixelBvr)),
point2(mul(toBvr(-250),pixelBvr),mul(toBvr( 20),pixelBvr)),
point2(mul(toBvr(-158),pixelBvr),mul(toBvr( 2),pixelBvr)),
point2(mul(toBvr( -98),pixelBvr),mul(toBvr( -1),pixelBvr)),
point2(toBvr( 0),mul(toBvr( 106),pixelBvr)),
bboyPos
};
Then apply the sprite translation to all the sprites, to move them
to their initial location. |
ImageBvr[] iSprites = new ImageBvr[9];
for(int i=0; i< i++)
iSprites[i] = sprites[i]
.transform(translate(sub(spritePos[i],origin2)));
Overlay all the 2-D sprites (the first overlay is at the top
and the last will be at the bottom). This new composite is made
pickable for later use. |
PickableImage allSprites = new PickableImage(
overlay(iSprites[0], overlay(iSprites[8], overlay(kiteString,
overlay(iSprites[4], overlay(iSprites[5], overlay(iSprites[6],
overlay(iSprites[7], overlay(iSprites[2],
overlay(iSprites[3], iSprites[1] ))))))))));
Finally, obtain the upper right corner of the composite, which will
be used to scale the geometries. |
Point2Bvr imageUR = allSprites.getImageBvr().boundingBox().getMax();
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.