Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   программная анимация рандомного движения (http://www.flasher.ru/forum/showthread.php?t=118680)

dashaaa 01.12.2008 12:49

программная анимация рандомного движения
 
Добрый день,

подскажите, как заставить мувиклип "вибрировать" на одном месте. То есть плавно сдвигаться на небольшое расстояние в произвольном направлении, потом возвращаться назад, и снова, без остановки, двигаться уже в другом направлении.

Лучшее, чего мне удалось достичь - это вот
Код AS1/AS2:

FunnyAnimation = new Tween(this, "_x", Regular.easeInOut, this._x, initX+x_shift, duration, true);
FunnyAnimation1 = new Tween(this, "_y", Regular.easeInOut, this._y, initY+y_shift, duration, true);
FunnyAnimation.onMotionFinished = function () {
        this.yoyo();
        }
FunnyAnimation1.onMotionFinished = function () {
        this.yoyo();
        }

Но здесь нет никакой случайности в направлении движения - туда-сюда-туда-сюда...

NoCD 01.12.2008 13:44

то есть нужно просто рандомное движение в какое нибудь из четырех направлений, пока не дойдет до точки никуда не должен сворачивать??

dashaaa 01.12.2008 14:07

По идее да

NoCD 01.12.2008 15:27

Вложений: 1
Надеюсь то, что нужно.
Если переделать пример, то можно с помощью точек регистрации задать движение мувику

dashaaa 02.12.2008 13:44

Вложений: 1
NoCD, большое спасибо за пример и за внимание к вопросу!
Я только сегодня увидела ответ, поэтому вчера сама тоже до чего-то дошла.
Во-первых, предположительно, анимация с помощью класса Tween более плавная, чем если писать координаты, куда мувику переместиться (и удобнее - легко варьировать скорость движения в секундах).
Поэтому, я сделала вот так:
Код AS1/AS2:

import mx.transitions.Tween;
import mx.transitions.easing.*;
import mx.utils.Delegate;
class Ball extends MovieClip {
var initX:Number;
var initY:Number;
var FunnyAnimation:Tween;
var FunnyAnimation1:Tween;
var duration:Number = 2;
var comeBack:Boolean = false;
// максимальный сдвиг от начального положения. Можно сделать больше, для наглядности анимации
static var vibrShift = 10;
var lastShift:Number = 0;
var yo:Boolean = false;
 
function funAnimProlong() {
        FunnyAnimation1.onMotionFinished = null;
        FunnyAnimation.onMotionFinished = null;                       
        Vibration();
}
public function shift(x_shift:Number, y_shift:Number):Void {
        FunnyAnimation = new Tween(this, "_x", None.easeNone, this._x, initX+x_shift, duration, true);
        FunnyAnimation1 = new Tween(this, "_y", None.easeNone, this._y, initY+y_shift, duration, true);
        FunnyAnimation.onMotionFinished = Delegate.create(this, funAnimProlong);
}
public function Vibration():Void {
        var direct:Number = Math.floor(Math.random()*4);
        if (direct == lastShift) {direct = (direct+1)%4;}
        lastShift = direct;
        var shX:Number = 5+Math.floor(vibrShift*Math.random());
        var shY:Number = 5+Math.floor(vibrShift*Math.random());
        switch (direct) {
                case 0 :shift(shX,shY);break;
                case 1 :shift(shX,(-1)*shY);break;
                case 2 :shift((-1)*shX,shY);break;
                case 3 :shift((-1)*shX,(-1)*shY);break;
        }
}
public function Ball() {
        initY = this._y;
        initX = this._x;
        Vibration();
}
}

Вот здесь можно лицезреть результат: Вложение 20971

И, пока мувиклипов, которые двигаются таким образом мало (25) всё работает хорошо. Но когда их 100 начинаются подёргивания. Но мне-то нужно 100 :wacko:
Может можно переписать как-нибудь, чтобы не дёргалось? Вообще-то правильность функции funAnimProlong() вызвает у меня сомнения :rolleyes:
И ещё вопрос - можно ли сделать чтобы анимация из одной точки в другую была не по прямой, а по какой-нибудь плавной линии?

goarcade 02.12.2008 17:46

Не поленился и набросал код моего подхода, т.к. задача показалась интересной:) надеюсь он будет полезным!

Код AS1/AS2:

import flash.geom.Point; 
 
 
var ballList:Array = new Array();
 
for(var i:Number=0;i<100;i++)
{
        var w:Number = 550;
        var h:Number = 400;
        ballList.push(createBall(w/10*(i%10)+w/20,h/10*Math.floor(i/10)+h/20));
}
 
function onEnterFrame():Void
{
        for(var i:Number=0;i<ballList.length;i++)
        {
                steer(ballList[i]);
                if(ballList[i].position.subtract(ballList[i].target).length<10)
                {
                        createTarget(ballList[i],20);
                }
        }
}
 
 
function steer(mc:MovieClip):Void
{
        var target:Point = mc.target;
        var position:Point = mc.position;
        var velocity:Point = mc.velocity;
 
        var max_speed:Number = mc.max_speed;
 
        var target_offset:Point = target.subtract(position)
        var ramped_speed:Number = max_speed * (target_offset.length/10)
        var clipped_speed:Number = Math.min(ramped_speed, max_speed)
        var desired_velocity:Point =  target_offset.clone();
        desired_velocity.normalize(desired_velocity.length*(clipped_speed / target_offset.length));
 
 
        velocity = mc.velocity.add(truncate (desired_velocity.subtract(velocity), 0.5));
        truncate (velocity, max_speed)
 
 
        position = position.add(velocity);
 
        mc._x = position.x;
        mc._y = position.y;       
        mc.position = position;
        mc.velocity = velocity;       
}
function createBall(x:Number,y:Number):MovieClip
{
        var mc:MovieClip = createEmptyMovieClip("ball"+getNextHighestDepth(),getNextHighestDepth());
        mc.beginFill(0xffffff*Math.random());
        drawRect(mc,5);
        mc.endFill();
 
        mc._x = x;
        mc._y = y;
 
        mc.position0 = new Point(x,y);       
        mc.position = new Point(x,y);
        mc.target = new Point(x,y);
        mc.velocity = new Point(0,0);
        mc.max_speed = 3;
        return mc;
}
 
 
function createTarget(mc:MovieClip,r:Number):Void
{
        mc.target = new Point(mc.position0.x+Math.random()*r-r/2,mc.position0.y+Math.random()*r-r/2);
}
 
 
function truncate(p:Point,maxLength:Number):Point
{
        if(p.length>maxLength)p.normalize(maxLength);
        return p;
}
 
function drawRect(mc:MovieClip, r:Number):Void {
        mc.moveTo(-r,-r);
        mc.lineTo( r,-r);
        mc.lineTo( r, r);       
        mc.lineTo(-r, r);       
}


dashaaa 03.12.2008 14:37

goarcade, получилось очень круто :D
Похоже, даже, что это решение будет нормально и без тормозов работать в реальной задаче (там каждый мувик не просто фигура, а две наложенные друг на друга картинки, и таких мувиков там около 40)
А ещё, после того как я почитала Ваш код, Point, со всеми своими методами, стал моим любимым классом (раньше мы не встречались) %)
В общем, бурные апплодисменты и огромное спасибо! :yahoo:


Часовой пояс GMT +4, время: 18:05.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.