现在的位置: 首页 > 综合 > 正文

《making things move 》第六章

2013年12月05日 ⁄ 综合 ⁄ 共 5839字 ⁄ 字号 评论关闭
《making things move 》第六章

这章实在太熟了。。。直接大块贴代码了

飞船飞到边界外边回不来了 [sweat]处理边界问题:

当一个物体跑出flash显示区域的边界外时,通常有以下4种方法,处理这个物体

1 删掉

2 再利用,拿回来当成新的物体一样

3 饶一圈又从另一边回来了,就像换个位置一样

4 反弹回显示区域

从最基础的开始。。。

1. 删掉:

ball的注册点都在中间,ball._x - ball._width / 2 就是ball的右侧,以此类推

边界值就是影片的大小

top = 0;
left = 0;
bottom = Stage.height;
right = Stage.width;

看代码:

init();
function init()
{
 count = 20;
 top = 0;
 left = 0;
 bottom = Stage.height;
 right = Stage.width;
 balls = new Array();
 for (var i = 0; i < count; i++)
 {
 var ball = attachMovie("ball", "ball" + i, i);
 ball._x = Math.random() * Stage.width;
 ball._y = Math.random() * Stage.height;
 ball.vx = Math.random() * 2 - 1;
 ball.vy = Math.random() * 2 - 1;
 balls.push(ball);
 }
}
function onEnterFrame(Void):Void
{
 for (var i:Number=balls.length − 1;i>=0;i--)
 {
 var ball = balls[i];
 ball._x += ball.vx;
 ball._y += ball.vy;
 if (ball._x - ball._width / 2 > right)
 {
 ball.removeMovieClip();
 balls.splice(i, 1);
 }
 else if (ball._x + ball._width / 2 < left)
 {
 ball.removeMovieClip();
 balls.splice(i, 1);
 }
 if (ball._y - ball._height / 2 > bottom)
 {
 ball.removeMovieClip();
 balls.splice(i, 1);
 }
 else if (ball._y + ball._height / 2 < top)
 {
 ball.removeMovieClip();
 balls.splice(i, 1);
 }
 }
}

2. 再利用:

出界了,就把那个拿回到原始位置,初始速度

ball._x = Stage.width / 2;
ball._y = Stage.height;
ball.vx = Math.random() * 2 - 1;
ball.vy = Math.random() * -10 - 10;

完整代码:

init();
function init()
{
 count = 50;
 top = 0;
 left = 0;
 bottom = Stage.height;
 right = Stage.width;
 gravity = 0.5;
 balls = new Array();
}
function onEnterFrame(Void):Void
{
 var ball:MovieClip;
 var index:Number = balls.length;
 if (index < count)
 {
 ball = attachMovie("ball", "ball" + index, index);
 ball._x = Stage.width / 2;
 ball._y = Stage.height;
 ball.vx = Math.random() * 2 - 1;
 ball.vy = Math.random() * -10 - 10;
 balls.push(ball);
 }
 for (var i = 0; i < balls.length; i++)
 {
 ball = balls[i];
 ball.vy += gravity;
 ball._x += ball.vx;
 ball._y += ball.vy;
 if (ball._x - ball._width / 2 > right ||
 ball._x + ball._width / 2 < left ||
 ball._y - ball._height / 2 > bottom ||
 ball._y + ball._height / 2 < top)
 {
 ball._x = Stage.width / 2;
 ball._y = Stage.height;
 ball.vx = Math.random() * 2 - 1;
 ball.vy = Math.random() * -10 - 10;
 }
 }
}

想一想怎么再加个风力?变成这样

3. 反方向出现

还是宇宙飞船的例子

init();
function init()
{
 vr = 5;
 thrust = 0.2;
 vx = 0;
 vy = 0;
 left = 0;
 right = Stage.width;
 top = 0;
 bottom = Stage.height;
 ship = attachMovie("ship", "ship", 0);
 ship._x = Stage.width / 2;
 ship._y = Stage.height / 2;
}
function onEnterFrame(Void):Void
{
 if (Key.isDown(Key.LEFT))
 {
 ship._rotation -= vr;
 }
 else if (Key.isDown(Key.RIGHT))
 {
 ship._rotation += vr;
 }
 if (Key.isDown(Key.UP))
 {
 var radians:Number = ship._rotation * Math.PI / 180;
 var ax:Number = Math.cos(radians) * thrust;
 var ay:Number = Math.sin(radians) * thrust;
 vx += ax;
 vy += ay;
 ship.gotoAndStop(2);
 }
 else
 {
 ship.gotoAndStop(1);
 }
 ship._x += vx;
 ship._y += vy;
 if (ship._x - ship._width / 2 > right)
 {
 ship._x = left - ship._width / 2;
 }
 else if (ship._x + ship._width / 2 < left)
 {
 ship._x = right + ship._width / 2;
 }
 if (ship._y - ship._height / 2 > bottom)
 {
 ship._y = top - ship._height / 2;
 }
 else if (ship._y < top - ship._height / 2)
 {
 ship._y = bottom + ship._height / 2;
 }
}

4. 反弹

这个也是最复杂的一个

我们要做3件事

Check if the object went past any boundary.

If so, place it on the edge of that boundary.

Then reverse the velocity.

init();
function init()
{
 top = 0;
 left = 0;
 bottom = Stage.height;
 right = Stage.width;
 ball = attachMovie("ball", "ball", 0);
 ball._x = Stage.width / 2;
 ball._y = Stage.height / 2;
 vx = Math.random() * 10 - 5;
 vy = Math.random() * 10 - 5;
}
function onEnterFrame(Void):Void
{
 ball._x += vx;
 ball._y += vy;
 if (ball._x + ball._width / 2 > right)
 {
 ball._x = right - ball._width / 2;
 vx *= -1;
 }
 else if (ball._x - ball._width / 2 < left)
 {
 ball._x = left + ball._width / 2;
 vx *= -1;
 }
 if (ball._y + ball._height / 2 > bottom)
 {
 ball._y = bottom - ball._height / 2;
 vy *= -1;
 }
 else if (ball._y - ball._height / 2 < top)
 {
 ball._y = top + ball._height / 2;
 vy *= -1;
 }
}

虽然看上去很真实,但他并不是真实的,因为我们修正位置时候跟真实世界是不符的,下边的图说明了这个问题

attachments/200611/02_165027_1.jpg

不过已经很不错了,如果要更真实的,不如去换个软件试试 ,在flash世界里,没有必要那么做 - -b

能量损耗

在真实世界里反弹是有能量损耗的,我们这个看上去永远不会停下来,下边加上重力和弹力损耗

init();
function init()
{
 bounce = -0.7;
 gravity = 0.5;
 top = 0;
 left = 0;
 bottom = Stage.height;
 right = Stage.width;
 ball = attachMovie("ball", "ball", 0);
 ball._x = Stage.width / 2;
 ball._y = Stage.height / 2;
 vx = Math.random() * 10 - 5;
 vy = Math.random() * 10 - 5;
}
function onEnterFrame(Void):Void
{
 vy += gravity;
 ball._x += vx;
 ball._y += vy;
 if (ball._x + ball._width / 2 > right)
 {
 ball._x = right - ball._width / 2;
 vx *= bounce;
 }
 else if (ball._x - ball._width / 2 < left)
 {
 ball._x = left + ball._width / 2;
 vx *= bounce;
 }
 if (ball._y + ball._height / 2 > bottom)
 {
 ball._y = bottom - ball._height / 2;
 vy *= bounce;
 }
 else if (ball._y - ball._height / 2 < top)
 {
 ball._y = top + ball._height / 2;
 vy *= bounce;
 }
}

摩擦力

真实的摩擦力应该

speed = Math.sqrt(vx * vx + vy * vy);
angle = Math.atan2(vy, vx);
if(speed > friction)
{
 speed -= friction;
}
else
{
 speed = 0;
}
vx = Math.cos(angle) * speed;
vy = Math.sin(angle) * speed;

但是我们注意到摩擦力其实就是对速度的阻碍,所以我们可以简化他

vx *= friction;
vy *= friction;

例子:

init();
function init()
{
 friction = 0.97;
 vr = 5;
 thrust = 0.2;
 vx = 0;
 vy = 0;
 left = 0;
 right = Stage.width;
 top = 0;
 bottom = Stage.height;
 ship = attachMovie("ship", "ship", 0);
 ship._x = Stage.width / 2;
 ship._y = Stage.height / 2;
}
function onEnterFrame(Void):Void
{
 if (Key.isDown(Key.LEFT))
 {
 ship._rotation -= vr;
 }
 else if (Key.isDown(Key.RIGHT))
 {
 ship._rotation += vr;
 }
 if (Key.isDown(Key.UP))
 {
 var radians:Number = ship._rotation * Math.PI / 180;
 var ax:Number = Math.cos(radians) * thrust;
 var ay:Number = Math.sin(radians) * thrust;
 vx += ax;
 vy += ay;
 ship.gotoAndStop(2);
 }
 else
 {
 ship.gotoAndStop(1);
 }
 vx *= friction;
 vy *= friction;
 ship._x += vx;
 ship._y += vy;
 if (ship._x - ship._width / 2 > right)
 {
 ship._x = left - ship._width / 2;
 }
 else if (ship._x + ship._width / 2 < left)
 {
 ship._x = right + ship._width / 2;
 }
 if (ship._y - ship._height / 2 > bottom)
 {
 ship._y = top - ship._height / 2;
 }
 else if (ship._y < top - ship._height / 2)
 {
 ship._y = bottom + ship._height / 2;
 }
}

var vr:Number = Math.random() * 100 - 50;
var friction:Number = 0.95;

function onEnterFrame(Void):Void
{
  vr *= friction;
  arrow._rotation += vr;
}

抱歉!评论已关闭.