Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Плавное движение по точкам (http://www.flasher.ru/forum/showthread.php?t=152202)

Universe 13.03.2011 17:20

Плавное движение по точкам
 
Делаю сейчас одну игрушку в которой объект движется по заданному пути, от точки к точке. Но на большой скорости становится заметным угловатость этого движения. Как можно это исправить? Чтобы объект на любой скорости двигался плавно?

Вот код который есть пока:
Код AS3:

var speed:uint = 5;
var velX:Number;
var velY:Number;
var pointNum:uint;
var points_arr:Array = new Array();
 
fillArray();
ball_mc.addEventListener(Event.ENTER_FRAME, moveBall);
 
function fillArray():void
{
        for(var i:uint; i< this.numChildren; i++)
        {
                if(getChildAt(i).name == "point" + i)
                {
                        points_arr.push(getChildAt(i));
                }
        }
        trace(points_arr.length);
}
 
function moveBall(e:Event):void
{
        var dx = points_arr[pointNum].x - ball_mc.x;
        var dy = points_arr[pointNum].y -ball_mc.y;
        var dist = Math.sqrt(dx*dx+dy*dy);
        //var angle = Math.atan2(dy, dx);
        //movieClip1_mc._rotation = angle*180/Math.PI;
 
        if (dist>speed)
        {
                velX = dx/dist*speed;
                velY = dy/dist*speed;
                ball_mc.x += velX;
                ball_mc.y += velY;
        }
        else
        {
                if(pointNum < points_arr.length-1)
                {
                        trace("Point CHANGED");
                        pointNum++;
                }
                else
                {
                        //e.target.removeEventListener(Event.ENTER_FRAME, moveBall);
                        pointNum = 0;
                }
        }
}


Jewelz 13.03.2011 17:35

я делал через Bezier

Universe 13.03.2011 17:54

а кокой нибудь примерчик кода можно?

Jewelz 13.03.2011 18:00

не найду =)

но суть такова - по точкам строим кривую безье (я пользовался безье Дембицкого)

а дальше по ENTER_FRAME делаем приращение времени (скорость), получаем новую точку на нашей кривой, и размещаем там объект

spooner 13.03.2011 18:27

Не то?

ЗлОй ПрОграММер 13.03.2011 23:16

http://bezier.ru/

Universe 13.03.2011 23:46

а можно у них как то эту библиотеку вытянуть без настройки SVN? работаю в Flash IDE

Bgg 14.03.2011 00:09

э
http://bezier.googlecode.com/files/bezier.swc

Universe 14.03.2011 00:17

извиняюсь за нубовский вопрос, но как открыть swc? Никогда с ним не работал. Пробовал при помощи winRar, но классов внутри не обнаружил, только xml и swf

Bgg 14.03.2011 00:36

Первая страница гугла: http://www.infogroupindia.com/blog/posts/513

kseniya 14.03.2011 05:33

Может быть TweenLite поможет? http://www.greensock.com/as/swf/EaseVisualizer.swf

Universe 14.03.2011 11:07

to kseniya та нет, это не то немного. Тут нужно именно построение кривой.
Зашёл на сайт bezier.ru - на их сайте есть хорошие демки, только вот не могу исходники к ним найти. Может есть возможность глянуть на код исходника, в частности интересует пример № 6

shootkin 14.03.2011 13:26

Для интерполяции движения по ключевым точкам больше подойдут не кривые Безье, а, например, сплайны Катмулла-Рома. Вот пример с функцией построения сплайна. Правда он на корейском :) Но исходники достаточно очевидные.

Universe 14.03.2011 16:36

ну честно сказать немного не понял, в чём преимущества Катмулл-Рома? По-моему точки на примере проставляет точно также

shootkin 14.03.2011 17:14

Если реализовывать с нуля, то сплайны Катмулл-Рома проще. Возможно и оптимальнее по вычислительным затратам.

Universe 15.03.2011 22:38

Но всё-таки хотелось бы покапаться в демках от Bezier.ru! Ну или хотя бы какой нить простенький примерчик с реализацией движения по точкам, а то как то странно, вроде хороший сайт, а примеров использования класса нету

Alex Lexcuk 16.03.2011 00:46

Цитата:

Сообщение от Universe (Сообщение 980721)
Но всё-таки хотелось бы покапаться в демках от Bezier.ru! Ну или хотя бы какой нить простенький примерчик с реализацией движения по точкам, а то как то странно, вроде хороший сайт, а примеров использования класса нету

Набросал по быстрому
Код AS3:

package  
{
 
        import flash.display.*;
        import flash.events.*;
        import flash.geom.*;
        /**
        * ...
        * @author Alex Lexcuk
        */

        public class DocMoveCurve extends Sprite
        {
 
                public var debSp:Sprite;
                public var lastM:Point = new Point();
                public var curM:Point = new Point();
                public var b:Point = new Point();
                public var speedStep:int = 10;//перелет по 10 пикселов
                public var speedFrameStep:int = 10;
                public var frameCount:int;
 
                public var curveArr:Vector.<Point> = new Vector.<Point>();
                public var persSp:Sprite;
                public function DocMoveCurve()
                {
                        addChild(debSp = new Sprite());
                        addChild(persSp = new Sprite());
                        debSp.graphics.lineStyle(0);
                        persSp.graphics.beginFill(0xFF0080);
                        persSp.graphics.drawCircle(0, 0, 5);
                        curveArr.push(new Point());
                        stage.addEventListener(MouseEvent.CLICK, stageClickHandler);
                        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
                }
 
                public function enterFrameHandler(e:Event):void {
                        persSp.x = curveArr[frameCount].x;
                        persSp.y = curveArr[frameCount].y;
                        frameCount++;
                        if (frameCount >= curveArr.length) frameCount = 0;
                }
 
                public function stageClickHandler(e:MouseEvent):void {
                        drawMousePath();
                }
 
                public function drawMousePath():void {
                        var mx:Number = debSp.mouseX;
                        var my:Number = debSp.mouseY;
                        var p:Point = new Point(mx, my);
 
                        if (b.x == 0 && b.y == 0) {//первый старт
                                p.normalize(p.length/1.5);
                                p = new Point(p.y, -p.x);//левая нормаль
                                p = p.add(new Point(mx/1.5, my/1.5));
                                b = p.clone();//плавная точка бизера
                        } else {//второй и следующие старты
                                //вектор предыдущей точки плавности на пред мышкину точку
                                var bt:Point = new Point(lastM.x - b.x,lastM.y - b.y);
                                //вектор предмышки на мышку
                                var mt:Point = new Point(lastM.x - mx, lastM.y - my);
                                bt.normalize( mt.length / 2);
                                b = bt.add(lastM);
                        }
                        debSp.graphics.moveTo(lastM.x, lastM.y);
                        debSp.graphics.curveTo(b.x, b.y, mx, my);
                        debSp.graphics.drawCircle(b.x, b.y, 4);
 
                        curM = new Point(mx, my);
                        addToArrPosCurve();
                        lastM = new Point(mx, my);
                }
 
                public function addToArrPosCurve():void {
                        var i:int;
                        var p:Point = new Point();
                        var lp:Point = lastM.clone();
                        var sp:Point;
                        for (i = 0; i < 100; i++) {
                                p.x = myCurveTo(lastM.x, b.x, curM.x, i / 100);
                                p.y = myCurveTo(lastM.y, b.y, curM.y, i / 100);
                                sp = p.subtract(lp);
                                if (sp.length > speedStep) {
                                        lp = p.clone();
                                        curveArr.push(p.clone());
                                        debSp.graphics.drawCircle(p.x, p.y, 4);
                                }
                        }
                }
 
                public function myCurveTo(param1:int, param2:int, param3:int, param4:Number):Number{
                        return (1 - param4) * (1 - param4) * param1 + 2 * param4 * (1 - param4) * param2 + param4 * param4 * param3;
                }
        }
 
}

http://murmadillo.tut.su/m/doc-move-curve.swf
Надо мышкой кликать, потом будет шарик по мышиной бизерной кривой летать.

Universe 16.03.2011 01:25

Пошарив по нету нарыл интересную библиотеку по имени Grape.
Поюзав примеры понял что штука интересная и вполне подходит под мои нужды, но всё таки осталось пару вопросов которые я пока не выяснил:
1. Как остановить процесс рендеринга? Я трейсю события TICK, но он продолжает тикать даже после завершения анимации. Должен ли я просто удалить слушатель в функции COMPLETE? Будет ли срабатывать сборщик мусора после удаления слушателя, или я должен сделать что-то еще, чтобы остановить анимацию?
2. Как я могу включить реверс анимации / изменить скорость анимации в любой момент времени? Я имею в виду, представьте, 2 шара, движущегося в разных направлениях, когда они ударяются друг от друга, они изменяют своё движения на противоположное, как я могу сделать что-то вроде этого?
3. Как я могу остановить анимацию?
4. Какую информацию я могу получить от объектов во время анимации? Например, мне нужно знать, какое расстояние прошёл объект, передаваемый по кривой и сколько осталось идти. Или как я могу вытянуть свойства объекта на пути? Например, как сделать увеличение объекта, когда он движется по кривой?
5. Как я могу заставить объект поворачиваться на пути - чтото типа "Orient to path"?

Добавлено через 3 минуты
Вот ссылка на саму библиотеку :
http://code.google.com/p/grape-as3/
Немного описаловки и примеров:
http://blog.generalrelativity.org/ac...comment-166445

Могу выслать свой класс по работе с этим Grape, если кому надо.

ЗлОй ПрОграММер 16.03.2011 09:54

Чтобы повернуть обьект(object) в сторону точки (NextPoint) подойдёт вот этот код:
(за вами остаётся только каждый раз вычислять координату обьекта и точку в которую он будет двигаться)

Код AS3:

dx = objectPoint.x - NextPoint.x;
dy = objectPoint.y - NextPoint.y;
 
if (dx < 0) angle1 = Math.atan(dy/dx)*180/Math.PI+90
else angle1 = 359 + Math.atan(dy/dx)*180/Math.PI-90;
 
if (object.rotation >= 0) angle2 = object.rotation
else angle2 = 360 + object.rotation;
 
dAngle = Math.abs(angle1-angle2);
 
if (dAngle > 2.7) {
  if (dAngle < (360 - dAngle)) {
        if (angle1 < angle2) object.rotation -=2
        else object.rotation += 2;
  }
  else {
        if (angle1 < angle2) object.rotation += 2
        else object.rotation -= 2;
  }                                               
}

можете сделать чтобы он поворачивался за курсором мыши тогда код:
Код AS3:

dx = objectPoint.x - stage.MouseX;
dy = objectPoint.y - stage.MouseY;



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

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