Bouncing

For the purposes of this section, Ill be talking about bouncing off a flat surface. In other words, one that aligns perfectly with the x, y, or z axis. This is analogous to the bouncing off the sides of the screen you did in 2D.

Single object bouncing

With bouncing in 3D, again you detect when the object has gone past a boundary, adjust it to sit on that boundary, and then reverse its velocity on the appropriate axis. One of the differences with 3D is in how you decide where the boundaries are. In 2D, you generally use the stage coordinates or some other visible rectangular area. In 3D, things arent quite so simple. There is no real concept of a visible edge, unless you draw one in 3D. Youll get to drawing in 3D in the next chapter, so for now, youll be bouncing off arbitrarily placed invisible walls.

So, you set up your boundaries the same as before, but now you are setting them up in a 3D space, which means that they can be negative as well as positive. You also have the option of setting up a boundary on the z axis. The boundaries now look something like this:

 var top:Number = -250; var bottom:Number = 250; var left:Number = -250; var right:Number = 250; var front:Number = 250; var back:Number = -250; 

Then, after determining the objects new position, you need to check it against all six boundaries. Remember that you take half of the objects width into account in checking for the collision. Rather than recalculate that six times per frame, I stored it in a variable called radius . Heres the full code for 3D bouncing ( ch15_04.fla ):

 var x:Number = 0; var y:Number = 0; var z:Number = 0;  var vx:Number = Math.random() * 10 - 5;   var vy:Number = Math.random() * 10 - 5;   var vz:Number = Math.random() * 10 - 5;   var top:Number = -100;   var bottom:Number = 100;   var left:Number = -100;   var right:Number = 100;   var front:Number = 100;   var back:Number = -100;   var radius:Number = 15;  var fl:Number = 250; var vpX:Number = Stage.width / 2; var vpY:Number = Stage.height / 2; function onEnterFrame():Void {       x += vx;       y += vy;       z += vz;  if(x + radius > right)   {   x = right - radius;   vx *= -1;   }   else if(x - radius < left)   {   x = left + radius;   vx *= -1;   }   if(y + radius > bottom)   {   y = bottom - radius;   vy *= -1;   }   else if(y - radius < top)   {   y = top + radius;   vy *= -1;   }   if(z + radius > front)   {   z = front - radius;   vz *= -1;   }   else if(z - radius < back)   {   z = back + radius;   vz *= -1;   }  if(z <= -fl)       {             ball._visible = false;       }       else       {             ball._visible = true;             var scale:Number = fl / (fl + z);             ball._xscale = ball._yscale = scale * 100;             ball._x = vpX + x * scale;             ball._y = vpY + y * scale;       } } 

Note that I removed all of the key-handing stuff and just gave the ball a random velocity on each axis. Now you can see it is definitely bouncing around, but you cant really tell what it is bouncing againstas I said, these are arbitrarily placed invisible boundaries.

Multiple object bouncing

One thing you could do to help visualize the walls a little better would be to fill up the space with more objects. In ch15_05.fla , Ive removed the ball from the stage and attached 50 of them dynamically instead. Each one now gets its own x , y , z and vx , vy , vz . The onEnterFrame function now loops through, doing the same thing to each ball instead of just one. Heres the code:

 var numBalls:Number = 50; var top:Number = -100; var bottom:Number = 100; var left:Number = -100; var right:Number = 100; var front:Number = 100; var back:Number = -100; var radius:Number = 15; var fl:Number = 250; var vpX:Number = Stage.width / 2; var vpY:Number = Stage.height / 2; init(); function init() {       for (var i:Number = 0; i<numBalls; i++) {             var ball:MovieClip = attachMovie("ball", "ball" + i, i);             ball.x = Math.random() * 200 - 100;             ball.y = Math.random() * 200 - 100;             ball.z = Math.random() * 200 - 100;             ball.vx = Math.random() * 10 - 5;             ball.vy = Math.random() * 10 - 5;             ball.vz = Math.random() * 10 - 5;       } } function onEnterFrame():Void {       for (var i:Number=0;i<numBalls;i++) {             var ball:MovieClip = this["ball" + i];             ball.x += ball.vx;             ball.y += ball.vy;             ball.z += ball.vz;             if (ball.x + radius > right) {                   ball.x = right - radius;                   ball.vx *= -1;             } else if (ball.x - radius < left) {                   ball.x = left + radius;                   ball.vx *= -1;             }             if (ball.y + radius > bottom) {                   ball.y = bottom - radius;                   ball.vy *= -1;             } else if (ball.y - radius < top) {                   ball.y = top + radius;                   ball.vy *= -1;             }             if (ball.z + radius > front) {                   ball.z = front - radius;                   ball.vz *= -1;             } else if (ball.z - radius < back) {                   ball.z = back + radius;                   ball.vz *= -1;             }             if (ball.z <= -fl) {                   ball._visible = false;             } else {                   ball._visible = true;                   var scale:Number = fl / (fl + ball.z);                   ball._xscale = ball._yscale=scale*100;                   ball._x = vpX + ball.x * scale;                   ball._y = vpY + ball.y * scale;             }        }  } 

When you run this file, the balls largely fill up the space between the six boundaries, as shown in Figure 15-5, and you can get an idea of the shape of this space.

image from book
Figure 15-5: Bouncing 3D balls

Z-sorting

Now, this addition of multiple objects reveals something lacking in the code you have so farsomething called z-sorting . Z-sorting is pretty much what it sounds like: how things are sorted on the z axis, or which one goes in front of another one. In Flash, z-sorting is done by the depth of the object, which is determined when you place the object on stage or when you attach it. Movie clips with a higher depth appear in front of ones with a lower depth.

Flash doesnt know that you are simulating 3D. It just knows that youre moving and scaling movie clips. And it certainly doesnt know if youre using a left-hand or right-hand coordinate system. So, it has no idea that because this ball is farther away, it should appear behind this other one that is closer. It just sorts them according to the depth they were originally given. If you want to change that, you need to tell Flash the order you want to use for them. You can do that by using the MovieClip method swapDepths to send the clip to the appropriate depth.

The problem is that the z-sorting youre using is opposite to Flashs ordering. With the right-hand system, objects with a higher z value are farther away. But theres a simple fix. Just use ˆ z to determine the depth, like so: ball.swapDepths(-ball.z) . Its no problem to swap a movie clip to a negative depth. As you may recall from Chapter 2, movie clips placed on stage already have a negative depth. The only caveat is that if you want to remove these clips at some point with removeMovieClip , youll need to swap them back to a higher depth.

Heres the updated block of code from the onEnterFrame function:

 } else {       ball._visible = true;       var scale:Number = fl / (fl + ball.z);       ball._xscale = ball._yscale=scale*100;       ball._x = vpX + ball.x * scale;       ball._y = vpY + ball.y * scale;  ball.swapDepths(-ball.z);  } 

If you thought the example looked a little strange for some reason, you can add this single line to the file. Note that this is not a 100% fix. If you have a lot of objects on stage, there may be several very close to each other on the z axis. The swapDepths function takes only integers, so if you use it on three movie clips at z positions of ˆ 100.3, ˆ 100.0, and ˆ 99.7, they all will try to change their depths to 100. The last one will wind up at 100, but the first two will be swapped out to some other coordinate, possibly giving you some minor visual glitches. But generally, this is a very quick, easy, and effective technique for z-sorting.



Foundation ActionScript. Animation. Making Things Move
Foundation Actionscript 3.0 Animation: Making Things Move!
ISBN: 1590597915
EAN: 2147483647
Year: 2005
Pages: 137
Authors: Keith Peters

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net