Ну в общем да, заговор, это
твипсы. Т.е. реально object.x вы знаете с точностью до 0.05 только. Решение - хранить параллельно Point или что-то подобное, где будет более точное значение. Тут пацаны говорят что что-то куда-то возвращать надо, я этого не понял и у меня работает и так %) Я и собсно смещения не видел, если честно %) Но теоретически может быть вполне =) ну вот крутится, чо
Код AS3:
//если этот код кого-то научит плохому, то я не виноват. Нервных также просьба не читать.
public var spr:Sprite;
public function Main():void
{
//if (stage) init();
//else addEventListener(Event.ADDED_TO_STAGE, init);
//var obj:Object = { s:new Sprite(), coords:new Point() };
spr = new Sprite();
spr.graphics.lineStyle(0);
spr.graphics.drawEllipse( -10, -5, 20, 10);
spr.x = 100;
spr.y = 100;
addChild(spr);
addEventListener(Event.ENTER_FRAME, up);
}
public function up(e:Event):void {
pointRotate(spr, new Point(150, 250), 5.12345);
}
public static function pointRotate (object:DisplayObject, center:Point, angle:Number) : void
{
var r:Number = angle * Math.PI / 180;
var s:Number = Math.sin(r);
var c:Number = Math.cos(r);
var dX:Number = object.x - center.x;
var dY:Number = object.y - center.y;
var rotDiff:Number = object.rotation;
object.rotation += angle;
rotDiff = object.rotation - rotDiff;
object.x = center.x + dX * c - dY * s;
object.y = center.y + dX * s + dY * c;
trace(object.x, center.x + dX * c - dY * s);//feel the difference
}
UPD: а, это наверное вечная тема про "смещение точки регистрации". Я бы использовал доп. матрицу, которая задает новую систему координат. Это в некотором роде аналог вставки во внешний контейнер. Ладно, раз влез блин, то вот...
Код AS3:
public var spr:Sprite;
public var mInner:Matrix = new Matrix();//это наши внутренние координаты
public var mOuter:Matrix = new Matrix();//это наши внешние координаты
public function Main():void
{
graphics.lineStyle(0);
graphics.drawCircle(200, 100, 0.5);//чтоб видеть вокруг чего крутимся
spr = new Sprite();
spr.graphics.lineStyle(0);
spr.graphics.drawEllipse( -10, -5, 20, 10);//точка регистрации в центре эллипса
spr.x = 200 - 10;
spr.y = 100 - 5;
addChild(spr);
mOuter = spr.transform.matrix;//изначально mOuter - трансформ обьекта, mInner - единичная
setRegPoint(200, 100);
//updateTransform();
addEventListener(Event.ENTER_FRAME, up);
}
public function setRegPoint(X:Number, Y:Number):void {//эта функция ставит опорку в нужную точку (графика при этом не смещается)
var dx:Number = X - mOuter.tx;
var dy:Number = Y - mOuter.ty;
var p:Point = new Point(dx, dy);
var m:Matrix = mOuter.clone();
m.invert();
m.tx = 0;
m.ty = 0;
p = m.transformPoint(p);
mInner.tx -= p.x;
mInner.ty -= p.y;
mOuter.tx = X;
mOuter.ty = Y;
}
public function updateTransform():void {//когда меняются матрицы надо вызвать эту функцию, чтоб она применила изменения к спрайту или что у вас там
var m:Matrix = mInner.clone();//лучше завести ещё одну постоянную матрицу, чтоб не выделять тут память динамически
m.concat(mOuter);
spr.transform.matrix = m;
}
public function up(e:Event):void {
pointRotate(5.12345);
}
public function pointRotate (angle:Number) : void
{
angle *= Math.PI / 180;
var prevX:Number = mOuter.tx;
var prevY:Number = mOuter.ty;
mOuter.rotate(angle);
mOuter.tx = prevX;
mOuter.ty = prevY;//поворачиваем mOuter на angle не трогая её позицию
updateTransform();
}