2010-06-20 3 views
2

Я безуспешно пытаюсь повернуть прямоугольник вокруг внешней точки во время твинирования. Я пытаюсь зафиксировать верхнюю часть красного прямоугольника на линии, пока он изменяет слева направо и поворачивается от 0º до 90º.ActionScript 3 - Tweening rotateAroundExternalPoint

alt text http://www.freeimagehosting.net/uploads/0b937c92e6.png

изображение выше показывает 3 состояния анимации движения. состояние 1 показывает красный прямоугольник в начале строки без угла. состояние 2 показывает, что красный прямоугольник движется наполовину вдоль линии с углом 45º, что также составляет половину общего угла 90º. состояние 3 показывает конечное положение твина, где красный прямоугольник имеет угол 90º и расположен на краю линии.

Кажется, проблема, с которой я столкнулся, заключается в том, что во время твинирования вращение приводит к тому, что верхняя часть красного прямоугольника теряет синхронизацию с черной линией.

вот мой код, который не работает, но, надеюсь, даст вам более четкое представление о том, что я пытаюсь.

var angle:Number = 90; 
var previousAngle:Number = 0; 

var distanceObject:Object = new Object(); 
distanceObject.distance = line.width; 

distanceTween = new Tween(distanceObject, "distance", None.easeNone, 0, distanceObject.distance, 5, true); 
distanceTween.addEventListener(TweenEvent.MOTION_CHANGE, tweenHandler); 

function tweenHandler(evt:TweenEvent):void 
    { 
    var angleShift:Number = (angle/distance) * distanceObject.distance; 

    //1:tween RedBox position 
    redBox.x = line.x + line.width * distanceObject.distance; 

    //2:tween RedBox angle 
    var externalPointMatrix:Matrix = redBox.transform.matrix; 
    MatrixTransformer.rotateAroundExternalPoint(externalPointMatrix, 0 + redBox.width * distanceObject.distance, 0, angleShift - previousAngle); 
    redBox.transform.matrix = externalPointMatrix; 

    previousAngle = angleShift; 
    } 
+0

Ссылка на изображение, кажется, сломана – Theo

+0

работает для меня. однако требуется некоторое время для загрузки. это всего лишь 25 кб, поэтому сервер очень занят: http://www.freeimagehosting.net/uploads/0b937c92e6.png – TheDarkIn1978

+0

справедливо предположить, что то, что я пытаюсь сделать, невозможно? – TheDarkIn1978

ответ

2

Я не думаю, что вы указали проблему достаточно хорошо для общего решения. Здесь меняются три вещи: x, y и вращение. Каждый из них рассчитывается в результате точки на прямоугольнике (синий «x» на вашей диаграмме), который изменяется со временем. Это означает, что вам нужно сосредоточиться на . Сначала - это точка на прямоугольнике, которая меняется с течением времени. Затем вам нужно знать, что x и y могут быть вычислены с использованием этой точки вместе с вращением.

Так сложите его в ступеньки.

  1. найти местоположение «х» точки на линии
  2. поворота объекта
  3. Найти местоположение «х» точка WRT в прямоугольник
  4. на основании угла поворота и известное местоположение «х» точка вычислить й и у положения прямоугольника (SOHCAHTOA)

Вот код для иллюстрации:

package 
{ 

import com.greensock.TweenNano; 

import flash.display.Sprite; 
import flash.events.Event; 

[SWF(width='500', height='300', backgroundColor='#ffffff', frameRate='30')] 
public class BoxAnim extends Sprite 
{ 
    private static const LINE_WIDTH:int = 350; 
    private static const RECT_WIDTH:int = 150; 
    private static const RECT_HEIGHT:int = 100; 
    private static const FINAL_ROTATION:Number = Math.PI/2; 

    public var point:Number; 

    private var line:Sprite; 
    private var rect:Sprite; 
    private var cross:Sprite; 

    public function BoxAnim() 
    { 
     addEventListener(Event.ADDED_TO_STAGE, addedToStage); 
    } 

    private function addedToStage(event:Event):void 
    { 
     line = new Sprite(); 
     addChild(line); 
     line.graphics.lineStyle(10, 0x0); 
     line.graphics.lineTo(LINE_WIDTH, 0); 
     line.x = 50; 
     line.y = 175; 

     rect = new Sprite(); 
     addChild(rect); 
     rect.graphics.lineStyle(4, 0xFF0000); 
     rect.graphics.beginFill(0xFF0000, 0.5); 
     rect.graphics.drawRect(0, 0, RECT_WIDTH, RECT_HEIGHT); 
     rect.x = 50; 
     rect.y = 175; 

     cross = new Sprite(); 
     addChild(cross); 
     cross.graphics.lineStyle(5, 0x41a9f4); 
     cross.graphics.moveTo(-5, -5); 
     cross.graphics.lineTo(5, 5); 
     cross.graphics.moveTo(5, -5); 
     cross.graphics.lineTo(-5, 5); 
     cross.x = 50; 
     cross.y = 175; 

     point = 0; 
     TweenNano.to(this, 3, {point: 1, onUpdate: tick}); 
    } 

    private function tick():void 
    { 
     // first calculate where the point should be on the line 
     cross.x = (point * LINE_WIDTH) + line.x; 

     // calculate the angle of rotation 
     var rotationRadians:Number = (point * FINAL_ROTATION); 
     rect.rotation = rotationRadians*180/Math.PI; 

     // calculate where on the rectangle the point would be 
     var rectCrossX:Number = (point * RECT_WIDTH); 
     // use trig to find the x & y points 
     rect.x = cross.x - Math.cos(rotationRadians)*rectCrossX; 
     rect.y = cross.y - Math.sin(rotationRadians)*rectCrossX; 
    } 
} 

} 

Я использую переменную point в процентах от 0 до 1. Затем я масштабирую ее, чтобы найти положение точки «x» на линии. Масштабируйте его снова, чтобы выяснить вращение. Масштабируйте его снова, чтобы найти, где он лежит вдоль верхней части прямоугольника. Затем триггер разрешает расположение угла прямоугольника по точке.

+0

Я слишком долго сражался с этим. ваше решение работает как магия! большое спасибо! – TheDarkIn1978