《making things move 》第八章
周末这两天休的,休懒了~~~加快速度看~~~
Easing 和 Spring
关于这章,以前webstudio根据这章翻译了一个简明教程:
http://www.nshen.net/blog/article.asp?id=303
Easing :
简单的easing就是我们常说的缓冲公式,就是每次走到目标距离的一半,你永远也到不了目标的那个。。。熟到不行的公式
例子:鼠标拖动试试
点这里 显示/隐藏 媒体
需要注意的是,easing 永远到不了终点,还是那句话“每次走到目标距离的一半,你永远也到不了目标”
flash中处理的坐标最小值是一twip,一twip是20分之1象素 ,0.05象素,所以你trace一个mc坐标时候都是0.05的倍数
This just loops through 20 times, moving the ball half the distance to the target. It’s basic easing code. I threw it in a for loop because I was only interested in tracing the positions, not actually seeing the motion. What you’ll find is that by the eleventh iteration, the ball has reached 99.95, and that’s as far as it gets.
In tracing positions, you might also notice that occasionally you get a number like 96.85000000000001. This has to do with the way fractions are stored in a binary format, and has nothing to do with pixels, twips, or Flash itself. For more information, do a web search for “binary round-off errors.”
距离目标足够近的话就假定他已经到了目标
Easing不只可以用在运动上:
透明度
Apply easing to the _alpha property of a clip. Start out by setting it to 0, and making the target 100:
ball._alpha = 0;
var targetAlpha:Number = 100;
Then you can fade it in with easing in an enterFrame handler:
ball._alpha += (targetAlpha − ball._alpha) * easing;
Or reverse the 0 and 100 to make it fade out.
旋转
Set the _rotation property and a target rotation. Of course, you need something that can be visibly rotated, like an arrow:
arrow._rotation = 90;
var targetRotation:Number = 270;
And then ease it:
arrow._rotation += (targetRotation − arrow._rotation) * easing;
颜色
If you are up for a real challenge, try easing on 24-bit colors. You’ll need to start with red, green, and blue initial values and target values, perform the easing on each separate component color, and then combine them into a 24-bit color. For instance, you could ease from red to blue. Start with the initial and target colors:
red = 255;
green = 0;
blue = 0;
redTarget = 0;
greenTarget = 0;
blueTarget = 255;
Then in your enterFrame handler, perform easing on each one. Here is just the red value:
red += (redTarget − red) * easing;
Then combine the three into a single value (as described in Chapter 4):
col = red << 16 | green << 8 | blue;
And use that for setRGB, or for a line, a fill color, or another element.
高级Easing
Robert Penner是这方面专家可以到他网站上看www.robertpenner.com.或自己看看flash中的tween类
Spring
Spring就像弹簧效果
加速度是距离的比例
点这里 显示/隐藏 媒体
发现停不下来 - -b,不像弹簧了,想想。。。
哦,肯定要加个摩擦力
点这里 显示/隐藏 媒体
Spring 到一个移动的目标
var ax:Number = (targetX - ball._x) * spring;
var ay:Number = (targetY - ball._y) * spring;
把target改成鼠标
var ax:Number = (_xmouse - ball._x) * spring;
var ay:Number = (_ymouse - ball._y) * spring;
点这里 显示/隐藏 媒体
Spring 链
点这里 显示/隐藏 媒体
第一个球,跟随鼠标,其他的球跟随前一个,并加一个重力加速度
Spring到若干目标
Each force is an acceleration, and you just add them on to the velocity, one by one. Well, since a spring is nothing more than something exerting acceleration on an object, it’s pretty simple to create multiple springs acting on a single object.
点这里 显示/隐藏 媒体
偏移:
点这里 显示/隐藏 媒体
若干object的spring
点这里 显示/隐藏 媒体
相同点:
You set a target.
You determine the distance to that target.
Your motion is proportional to that distance—the bigger the distance, the more the motion.
不同点:
The difference between easing and springing is in what aspect of the motion is proportional. In easing, velocity is proportional to the distance; the further away from the target, the faster the object moves. As it gets very, very close to the object, it’s hardly moving at all.
In springing, acceleration is proportional to the distance. If the object is far away from the target, a whole lot of acceleration is applied, increasing the velocity quickly. As the object gets closer to its target, less acceleration is applied, but it’s still accelerating! It flies right past the target, and then acceleration pulls it back. Eventually, friction causes it to settle down.
Easing 和 Spring
关于这章,以前webstudio根据这章翻译了一个简明教程:
http://www.nshen.net/blog/article.asp?id=303
Easing :
简单的easing就是我们常说的缓冲公式,就是每次走到目标距离的一半,你永远也到不了目标的那个。。。熟到不行的公式
ball._x += (targetX - ball._x) * easing;
ball._y += (targetY - ball._y) * easing;
ball._y += (targetY - ball._y) * easing;
例子:鼠标拖动试试

var easing:Number = 0.2;
var targetX:Number = Stage.width / 2;
var targetY:Number = Stage.height / 2;
var dragging:Boolean = false;
ball.onPress = function()
{
dragging = true;
this.startDrag();
}
ball.onRelease = ball.onReleaseOutside = function()
{
dragging = false;
this.stopDrag();
}
onEnterFrame = function ()
{
if(!dragging)
{
var vx:Number = (targetX - ball._x) * easing;
var vy:Number = (targetY - ball._y) * easing;
ball._x += vx;
ball._y += vy;
}
};
var targetX:Number = Stage.width / 2;
var targetY:Number = Stage.height / 2;
var dragging:Boolean = false;
ball.onPress = function()
{
dragging = true;
this.startDrag();
}
ball.onRelease = ball.onReleaseOutside = function()
{
dragging = false;
this.stopDrag();
}
onEnterFrame = function ()
{
if(!dragging)
{
var vx:Number = (targetX - ball._x) * easing;
var vy:Number = (targetY - ball._y) * easing;
ball._x += vx;
ball._y += vy;
}
};
需要注意的是,easing 永远到不了终点,还是那句话“每次走到目标距离的一半,你永远也到不了目标”
flash中处理的坐标最小值是一twip,一twip是20分之1象素 ,0.05象素,所以你trace一个mc坐标时候都是0.05的倍数
var targ:Number = 100;
ball._x = 0;
for(var i:Number=0;i<20;i++)
{
trace(i + ": " + ball._x);
ball._x += (targ - ball._x) * .5;
}
ball._x = 0;
for(var i:Number=0;i<20;i++)
{
trace(i + ": " + ball._x);
ball._x += (targ - ball._x) * .5;
}
This just loops through 20 times, moving the ball half the distance to the target. It’s basic easing code. I threw it in a for loop because I was only interested in tracing the positions, not actually seeing the motion. What you’ll find is that by the eleventh iteration, the ball has reached 99.95, and that’s as far as it gets.
In tracing positions, you might also notice that occasionally you get a number like 96.85000000000001. This has to do with the way fractions are stored in a binary format, and has nothing to do with pixels, twips, or Flash itself. For more information, do a web search for “binary round-off errors.”
距离目标足够近的话就假定他已经到了目标
var easing:Number = 0.2;
var targ:Number = Stage.width / 2;
onEnterFrame = ease;
function ease() {
var dx:Number = targ - ball._x;
if(Math.abs(dx) < 1)
{
ball._x = targ;
delete onEnterFrame;
trace("done");
}
else
{
var vx:Number = dx * easing;
ball._x += vx;
}
};
var targ:Number = Stage.width / 2;
onEnterFrame = ease;
function ease() {
var dx:Number = targ - ball._x;
if(Math.abs(dx) < 1)
{
ball._x = targ;
delete onEnterFrame;
trace("done");
}
else
{
var vx:Number = dx * easing;
ball._x += vx;
}
};
Easing不只可以用在运动上:
透明度
Apply easing to the _alpha property of a clip. Start out by setting it to 0, and making the target 100:
ball._alpha = 0;
var targetAlpha:Number = 100;
Then you can fade it in with easing in an enterFrame handler:
ball._alpha += (targetAlpha − ball._alpha) * easing;
Or reverse the 0 and 100 to make it fade out.
旋转
Set the _rotation property and a target rotation. Of course, you need something that can be visibly rotated, like an arrow:
arrow._rotation = 90;
var targetRotation:Number = 270;
And then ease it:
arrow._rotation += (targetRotation − arrow._rotation) * easing;
颜色
If you are up for a real challenge, try easing on 24-bit colors. You’ll need to start with red, green, and blue initial values and target values, perform the easing on each separate component color, and then combine them into a 24-bit color. For instance, you could ease from red to blue. Start with the initial and target colors:
red = 255;
green = 0;
blue = 0;
redTarget = 0;
greenTarget = 0;
blueTarget = 255;
Then in your enterFrame handler, perform easing on each one. Here is just the red value:
red += (redTarget − red) * easing;
Then combine the three into a single value (as described in Chapter 4):
col = red << 16 | green << 8 | blue;
And use that for setRGB, or for a line, a fill color, or another element.
高级Easing
Robert Penner是这方面专家可以到他网站上看www.robertpenner.com.或自己看看flash中的tween类
Spring
Spring就像弹簧效果
加速度是距离的比例
var spring:Number = 0.1;
ball._x = 0;
ball._y = Stage.height / 2;
var targetX:Number = Stage.width / 2;
var vx:Number = 0;
onEnterFrame = function () {
var ax:Number = (targetX - ball._x) * spring;
vx += ax;
ball._x += vx;
};
ball._x = 0;
ball._y = Stage.height / 2;
var targetX:Number = Stage.width / 2;
var vx:Number = 0;
onEnterFrame = function () {
var ax:Number = (targetX - ball._x) * spring;
vx += ax;
ball._x += vx;
};

发现停不下来 - -b,不像弹簧了,想想。。。
哦,肯定要加个摩擦力
var spring:Number = 0.1;
var friction:Number = 0.95;
ball._x = 0;
ball._y = Stage.height / 2;
var targetX:Number = Stage.width / 2;
var vx:Number = 0;
onEnterFrame = function () {
var ax:Number = (targetX - ball._x) * spring;
vx += ax;
vx *= friction;
ball._x += vx;
};
var friction:Number = 0.95;
ball._x = 0;
ball._y = Stage.height / 2;
var targetX:Number = Stage.width / 2;
var vx:Number = 0;
onEnterFrame = function () {
var ax:Number = (targetX - ball._x) * spring;
vx += ax;
vx *= friction;
ball._x += vx;
};

Spring 到一个移动的目标
var ax:Number = (targetX - ball._x) * spring;
var ay:Number = (targetY - ball._y) * spring;
把target改成鼠标
var ax:Number = (_xmouse - ball._x) * spring;
var ay:Number = (_ymouse - ball._y) * spring;

Spring 链

第一个球,跟随鼠标,其他的球跟随前一个,并加一个重力加速度
var spring:Number = 0.1;
var friction:Number = 0.8;
var gravity:Number = 5;
var ballCount:Number = 5;
for(var i=0;i<ballCount;i++)
{
var ball:MovieClip = attachMovie("ball", "ball" + i, i);
ball.vx = 0;
ball.vy = 0;
}
onEnterFrame = function () {
clear();
lineStyle(1, 0, 100);
moveTo(_xmouse, _ymouse);
ball0.vx += (_xmouse - ball0._x) * spring;
ball0.vy += (_ymouse - ball0._y) * spring;
for(var i=0;i<ballCount;i++)
{
var ballA:MovieClip = this["ball" + i];
if(i > 0)
{
var ballB:MovieClip = this["ball" + (i-1)];
ballA.vx += (ballB._x - ballA._x) * spring;
ballA.vy += (ballB._y - ballA._y) * spring;
}
ballA.vy += gravity;
ballA.vx *= friction;
ballA.vy *= friction;
ballA._x += ballA.vx;
ballA._y += ballA.vy;
lineTo(ballA._x, ballA._y);
}
};
var friction:Number = 0.8;
var gravity:Number = 5;
var ballCount:Number = 5;
for(var i=0;i<ballCount;i++)
{
var ball:MovieClip = attachMovie("ball", "ball" + i, i);
ball.vx = 0;
ball.vy = 0;
}
onEnterFrame = function () {
clear();
lineStyle(1, 0, 100);
moveTo(_xmouse, _ymouse);
ball0.vx += (_xmouse - ball0._x) * spring;
ball0.vy += (_ymouse - ball0._y) * spring;
for(var i=0;i<ballCount;i++)
{
var ballA:MovieClip = this["ball" + i];
if(i > 0)
{
var ballB:MovieClip = this["ball" + (i-1)];
ballA.vx += (ballB._x - ballA._x) * spring;
ballA.vy += (ballB._y - ballA._y) * spring;
}
ballA.vy += gravity;
ballA.vx *= friction;
ballA.vy *= friction;
ballA._x += ballA.vx;
ballA._y += ballA.vy;
lineTo(ballA._x, ballA._y);
}
};
Spring到若干目标
Each force is an acceleration, and you just add them on to the velocity, one by one. Well, since a spring is nothing more than something exerting acceleration on an object, it’s pretty simple to create multiple springs acting on a single object.

var spring:Number = 0.1;
var friction:Number = 0.9;
var vx:Number = 0;
var vy:Number = 0;
handle0.onPress = doDrag;
handle0.onRelease = handle0.onReleaseOutside = doDrop;
handle1.onPress = doDrag;
handle1.onRelease = handle1.onReleaseOutside = doDrop;
handle2.onPress = doDrag;
handle2.onRelease = handle2.onReleaseOutside = doDrop;
onEnterFrame = function () {
vx += (handle0._x - ball._x) * spring;
vy += (handle0._y - ball._y) * spring;
vx += (handle1._x - ball._x) * spring;
vy += (handle1._y - ball._y) * spring;
vx += (handle2._x - ball._x) * spring;
vy += (handle2._y - ball._y) * spring;
vx *= friction;
vy *= friction;
ball._x += vx;
ball._y += vy;
clear();
lineStyle(1, 0, 100);
moveTo(ball._x, ball._y);
lineTo(handle0._x, handle0._y);
moveTo(ball._x, ball._y);
lineTo(handle1._x, handle1._y);
moveTo(ball._x, ball._y);
lineTo(handle2._x, handle2._y);
};
function doDrag()
{
this.startDrag();
}
function doDrop()
{
this.stopDrag();
}
var friction:Number = 0.9;
var vx:Number = 0;
var vy:Number = 0;
handle0.onPress = doDrag;
handle0.onRelease = handle0.onReleaseOutside = doDrop;
handle1.onPress = doDrag;
handle1.onRelease = handle1.onReleaseOutside = doDrop;
handle2.onPress = doDrag;
handle2.onRelease = handle2.onReleaseOutside = doDrop;
onEnterFrame = function () {
vx += (handle0._x - ball._x) * spring;
vy += (handle0._y - ball._y) * spring;
vx += (handle1._x - ball._x) * spring;
vy += (handle1._y - ball._y) * spring;
vx += (handle2._x - ball._x) * spring;
vy += (handle2._y - ball._y) * spring;
vx *= friction;
vy *= friction;
ball._x += vx;
ball._y += vy;
clear();
lineStyle(1, 0, 100);
moveTo(ball._x, ball._y);
lineTo(handle0._x, handle0._y);
moveTo(ball._x, ball._y);
lineTo(handle1._x, handle1._y);
moveTo(ball._x, ball._y);
lineTo(handle2._x, handle2._y);
};
function doDrag()
{
this.startDrag();
}
function doDrop()
{
this.stopDrag();
}
偏移:
var spring:Number = 0.1;
var friction:Number = 0.9;
var springLength:Number = 75;
var vx:Number = 0;
var vy:Number = 0;
onEnterFrame = function () {
var dx:Number = ball._x - _xmouse;
var dy:Number = ball._y - _ymouse;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = _xmouse + Math.cos(angle) * springLength;
var targetY:Number = _ymouse + Math.sin(angle) * springLength;
vx += (targetX - ball._x) * spring;
vy += (targetY - ball._y) * spring;
vx *= friction;
vy *= friction;
ball._x += vx;
ball._y += vy;
clear();
lineStyle(1, 0, 100);
moveTo(ball._x, ball._y);
lineTo(_xmouse, _ymouse);
};
var friction:Number = 0.9;
var springLength:Number = 75;
var vx:Number = 0;
var vy:Number = 0;
onEnterFrame = function () {
var dx:Number = ball._x - _xmouse;
var dy:Number = ball._y - _ymouse;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = _xmouse + Math.cos(angle) * springLength;
var targetY:Number = _ymouse + Math.sin(angle) * springLength;
vx += (targetX - ball._x) * spring;
vy += (targetY - ball._y) * spring;
vx *= friction;
vy *= friction;
ball._x += vx;
ball._y += vy;
clear();
lineStyle(1, 0, 100);
moveTo(ball._x, ball._y);
lineTo(_xmouse, _ymouse);
};

若干object的spring

var spring:Number = 0.1;
var friction:Number = 0.9;
var springLength:Number = 75;
ball0.vx = 0;
ball0.vy = 0;
ball0.onPress = doDrag;
ball0.onRelease = ball0.onReleaseOutside = doDrop;
ball1.vx = 0;
ball1.vy = 0;
ball1.onPress = doDrag;
ball1.onRelease = ball1.onReleaseOutside = doDrop;
onEnterFrame = function () {
springTo(ball0, ball1);
springTo(ball1, ball0);
clear();
lineStyle(1, 0, 100);
moveTo(ball0._x, ball0._y);
lineTo(ball1._x, ball1._y);
}
function springTo(ballA, ballB)
{
if(!ballA.dragging)
{
//ballB是中点
var dx:Number = ballA._x - ballB._x;
var dy:Number = ballA._y - ballB._y;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = ballB._x +
Math.cos(angle) * springLength;
var targetY:Number = ballB._y +
Math.sin(angle) * springLength;
ballA.vx += (targetX - ballA._x) * spring;
ballA.vy += (targetY - ballA._y) * spring;
ballA.vx *= friction;
ballA.vy *= friction;
ballA._x += ballA.vx;
ballA._y += ballA.vy;
}
};
function doDrag()
{
this.dragging = true;
this.startDrag();
}
function doDrop()
{
this.dragging = false;
this.stopDrag();
}
var friction:Number = 0.9;
var springLength:Number = 75;
ball0.vx = 0;
ball0.vy = 0;
ball0.onPress = doDrag;
ball0.onRelease = ball0.onReleaseOutside = doDrop;
ball1.vx = 0;
ball1.vy = 0;
ball1.onPress = doDrag;
ball1.onRelease = ball1.onReleaseOutside = doDrop;
onEnterFrame = function () {
springTo(ball0, ball1);
springTo(ball1, ball0);
clear();
lineStyle(1, 0, 100);
moveTo(ball0._x, ball0._y);
lineTo(ball1._x, ball1._y);
}
function springTo(ballA, ballB)
{
if(!ballA.dragging)
{
//ballB是中点
var dx:Number = ballA._x - ballB._x;
var dy:Number = ballA._y - ballB._y;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = ballB._x +
Math.cos(angle) * springLength;
var targetY:Number = ballB._y +
Math.sin(angle) * springLength;
ballA.vx += (targetX - ballA._x) * spring;
ballA.vy += (targetY - ballA._y) * spring;
ballA.vx *= friction;
ballA.vy *= friction;
ballA._x += ballA.vx;
ballA._y += ballA.vy;
}
};
function doDrag()
{
this.dragging = true;
this.startDrag();
}
function doDrop()
{
this.dragging = false;
this.stopDrag();
}
相同点:
You set a target.
You determine the distance to that target.
Your motion is proportional to that distance—the bigger the distance, the more the motion.
不同点:
The difference between easing and springing is in what aspect of the motion is proportional. In easing, velocity is proportional to the distance; the further away from the target, the faster the object moves. As it gets very, very close to the object, it’s hardly moving at all.
In springing, acceleration is proportional to the distance. If the object is far away from the target, a whole lot of acceleration is applied, increasing the velocity quickly. As the object gets closer to its target, less acceleration is applied, but it’s still accelerating! It flies right past the target, and then acceleration pulls it back. Eventually, friction causes it to settle down.