2013-08-11 3 views
1

저는 AS3을 사용하여 베 지어 곡선을 애니메이션하는 가장 좋은 방법을 찾으려고 노력했습니다. 이것에 의해 지금까지 가장 좋은 해결책은 다음과 같습니다.AS3을 사용하여 베 지어 곡선을 애니메이션화하는 방법은 무엇입니까?

import flash.display.*; 
import flash.display.Sprite; 
import flash.geom.*; 
import com.greensock.TweenMax; 
import com.greensock.easing.*; 

public class Waves extends MovieClip 
{ 

    public var piste:Number = stage.stageHeight; 
    public var piste2:Number = 0; 

    var a:Sprite = new Sprite(); 
    var coord:Vector.<Number> = new Vector.<Number>(); 
    var com:Vector.<int> = new Vector.<int>(); 

    public function Waves() 
    { 

     addChild(a); 

     coord.push(0, 30); 
     com.push(1); 
     coord.push(260, piste, stage.stageWidth, 30); 
     com.push(3); 

     tweenNumbers(); 

    } 

    public function tweenNumbers():void { 

      TweenMax.to(this, 0.45, {piste:piste2, repeat:-1, yoyo:true, immediateRender:true, ease:Expo.easeOut, onUpdate:draw}); 

    } 

    public function draw():void { 

     coord[3] = piste; 
     a.graphics.clear(); 
     a.graphics.lineStyle(1,0x990000,1); 
     a.graphics.drawPath(com, coord); 


    } 

} 

커브를 움직이게하려면 실제로 graphics.clear를 사용해야합니까? 더 효율적인 방법이 있습니까? 트위닝이 1 초보다 빠르면 렌더링이 지연되고 이전 줄을 볼 수 있습니다. 제거 할 방법이 있습니까?

답변

1

흠. TweenMax의 사용 된 버전을 게시하여 문제를 올바르게 디버깅해야합니다. 몇몇은 비동기 적으로 디스패치 된 "update"이벤트를 사용하고, 일부는 enterframe 리스너를 사용하여 각 업데이트 루틴이 각 프레임이라고 불리는 것을 확인합니다. 따라서 그래픽 지터 링은 비동기식 시나리오에서 발생할 수 있습니다. 다른 질문에

:

  1. 예, 그래픽이 질문에 개체를 다시 그릴 필요가,이 graphics.clear()를 호출이 포함됩니다. Graphics 객체가 블랙 박스 엔티티 인 경우, 커브의 제어점에 직접 도달하여 어떻게 든 트위닝 할 수는 없습니다. 따라서 커브의 한 점을 변경하려면 다시 그려야합니다.

  2. 더 효율적인 방법은 입력 프레임 리스너와 트위닝에서 좌표 보간에 사용되는 Strong.easeOut과 비슷한 기능을 통해 Sprite에서 직접 트위닝을 에뮬레이션하는 것입니다. 그런 다음 TweenMax 라이브러리에 포함 된 모든 추가 프레임 워크를 제거하고 이벤트 및 코드 흐름을 완전히 제어합니다. 그러나 이것은 yoyo 동작, 시간 설정 동작, 프레임 속도 동작 ("시간 = 프레임"접근 방식으로 전환하여 문제 중 하나 제거) 및 동작 완화를 모방하는 일부 작업입니다. tweenNumbers는 다음과 같이 표시됩니다


var isYoyo:Boolean=false; 
var currentFrame:int; 
var maxFrame:int; 
function easingFunction(frame:int,maxframe:int,a:Number,b:Number):Number { 
    var x:Number=Number(frame)/maxframe; 
    return a+(b-a)*(x*x*(3-2*x)); // 3x^2-2x^3, a double-easing Perlin function 
    // recreate your needed function here! 
} 
var piste1:Number=0; // storing start coordinate 
private function tweenNumbers():void { 
    maxFrame=Math.round(0.45*stage.frameRate); // from seconds to frames 
    currentFrame=0; 
    isYoyo=false; 
    a.addEventListener(Event.ENTER_FRAME,onUpdate); 
} 
private function onUpdate(e:Event):void { 
    if (!isYoyo) { 
     currentFrame++; 
     if (currentFrame==maxFrame) isYoyo=true; 
    } else { 
     currentFrame--; 
     if (currentFrame==0) isYoyo=false; 
    } // advance time 
    coords[3]=easingFunction(currentFrame,maxFrame,piste1,piste2); 
    // tween the coords[3] manually 
    a.graphics.clear(); 
    a.graphics.lineStyle(1,0x990000,1); 
    a.graphics.drawPath(com, coord); 
    // draw updated path 
} 

desynching의 보장하지만,하지만, 일반적으로 작동합니다. 또한 무대 프레임 속도를 너무 높게 설정하면 대상 장치의 비디오 서브 시스템이 한 번에 많은 프레임을 그릴 수 없기 때문에 desynch (이전 행 참조)가 발생할 수 있습니다.

+1

내가 제공 한 방법을 사용했지만 지연이 여전히있었습니다. 그런 다음 다시 영화의 프레임 속도를 높이면 문제가 사라졌습니다. 나는 항상 실제 렌더링 및 애니 메이톤 프레임 속도가 플래시에 첨부되어 있지 않다고 생각했습니다. TweenMax 라이브러리를 사용하는 버전이 위 코드만큼 빠르다는 것을 알았 기 때문에 사용하기 쉽기 때문에 계속 사용하고 있습니다. TweenMax의 버전은 12입니다. –

관련 문제