AS3: установка точки регистрации объекта DisplayObject с помощью ActionScript? - PullRequest
10 голосов
/ 16 марта 2009

Как бы вы установили точку регистрации на Sprite или Shape с помощью ActionScript (я знаю, что это тривиально с использованием Flash, но мне нужно сделать это исключительно в ActionScript)

Ответы [ 5 ]

12 голосов
/ 10 апреля 2009

Flash Player API не раскрывает это. Я полагаю, что это потому, что Flash фактически запекает в точке регистрации данные формы при создании SWF. Таким образом, нет фактической точки регистрации для перемещения (вместо этого вы бы переместили данные формы ... если бы Flash Player позволял вам редактировать данные формы!).

Я всегда решаю эту проблему, просто помещая свой спрайт / форму в другой DisplayObject. Итак, если у меня есть spriteA и я хочу установить его точку регистрации (15, 35), я бы сделал это:


var spriteB:Sprite = new Sprite();
spriteB.addChild(spriteA);
spriteA.x = 15;
spriteA.y = 35;

И затем с тех пор обращайтесь к spriteB везде, где я ранее имел в виду spriteA.

5 голосов
/ 30 декабря 2009

Используя матрицу преобразования, это возможно. Вот хорошая реализация этого на этом сайте .

public function setRegistrationPoint(s:Sprite, regx:Number, regy:Number, showRegistration:Boolean )
{
    //translate movieclip 
    s.transform.matrix = new Matrix(1, 0, 0, 1, -regx, -regy);

    //registration point.
    if (showRegistration)
    {
        var mark:Sprite = new Sprite();
        mark.graphics.lineStyle(1, 0x000000);
        mark.graphics.moveTo(-5, -5);
        mark.graphics.lineTo(5, 5);
        mark.graphics.moveTo(-5, 5);
        mark.graphics.lineTo(5, -5);
        s.parent.addChild(mark);
    }
}
2 голосов
/ 16 марта 2009

Вы имеете в виду индекс?

Следуя комментариям, вы можете сделать быструю реализацию, как показано ниже. Это не совсем то, что вы хотите, так как вы не можете установить различные выравнивания для каждого ребенка. Я просто не хотел делать это слишком сложным, это скорее «рабочий псевдокод», чтобы дать вам идею ...

package  
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;    


    public class SpriteWithRegistration extends Sprite 
    {

        private var _regV:String = "T";
        private var _regH:String = "L";

        private var _width:Number = 0;
        private var _height:Number = 0;


        public function SpriteWithRegistration(width:Number, height:Number, registrationPoint:String = "TL")
        {
            this.width  = height;
            this.height = width;
            this.registrationPoint = registrationPoint;
        }

        public function set registrationPoint(p:String):void
        {
            if(p.length != 2) return;

            var regV:String = p.toUpperCase().substr(0, 1);
            var regH:String = p.toUpperCase().substr(1, 1);

            _regV = (regV == "T" || regV == "C" || regV == "B" ) ? regV : _regV;
            _regH = (regH == "L" || regH == "C" || regH == "R" ) ? regH : _regH;

            alignChildren();
        }

        override public function addChild(child:DisplayObject):DisplayObject
        {
            alignChild(child);
            super.addChild(child);
            return child;
        }

        override public function set width(value:Number):void
        {
            _width = value;
            alignChildren();
        }

        override public function get width():Number
        {
            return _width;
        }

        override public function set height(value:Number):void
        {
            _height = value;
            alignChildren();
        }

        override public function get height():Number
        {
            return _height;
        }

        private function alignChildren():void
        {
            for(var index:int = 0;index < numChildren; index++ )
                alignChild(getChildAt(index));
        }

        private function alignChild(disp:*):void
        {
            switch(_regH)
            {
                case "L":   disp.x = 0;                             break;
                case "C":   disp.x = _width*.5 - disp.width * .5;   break;
                case "R":   disp.x = _width - disp.width;           break;
            }

            switch(_regV)
            {
                case "T":   disp.y = 0;                             break;
                case "C":   disp.y = _height*.5 - disp.height * .5; break;
                case "B":   disp.y = _height - disp.height;         break;
            }
        }
    }
}
1 голос
/ 26 октября 2017

Надеюсь, это кому-нибудь поможет. У инфраструктуры Starling есть фантастический метод, называемый «alignPivot ()». Я взял их концепцию и адаптировал ее к Flash DisplayList. Вы по сути говорите спрайту изменить его регистрацию на левую, правую, центральную, верхнюю и нижнюю. Этот код помещает ваш спрайт в контейнерный спрайт и позиционирует себя соответствующим образом. Возвращает спрайт контейнера с оригинальным спрайтом, содержащимся внутри.

Код хранится в отдельном названном, называемом «Позиция».

    public static function alignPivot(s:DisplayObject, horizontalAlign: String = "center", verticalAlign: String = "center", showRegistration: Boolean = false, _color: uint = 0x000000): Sprite {

        //create a container sprite to house the sprite you'd like to move
        var _container: Sprite = new Sprite();
        //add your sprite to the continer sprite (the container sprite is what will be returned)
        _container.addChild(s);
        //using getBounds(), find the x,y,width,and height of your sprite within the continer.
        var bounds:Rectangle = _container.getBounds(s);
        //create variables for x and y cooridnates
        var xVal: Number;
        var yVal: Number;

        //I have a separate class called Align which contains public static constants for positiong.
        //Check the values passed above and get the correct x value;
        if (horizontalAlign == Align.LEFT) xVal = -bounds.x;
        else if (horizontalAlign == Align.CENTER) xVal = -bounds.x - bounds.width * .5;
        else if (horizontalAlign == Align.RIGHT) xVal = -bounds.x - bounds.width;
        else throw new ArgumentError("Invalid horizontal alignment: " + horizontalAlign);

        //Check the values passed above and get the correct y value;
        if (verticalAlign == Align.TOP) yVal = -bounds.y;
        else if (verticalAlign == Align.CENTER) yVal = -bounds.y - bounds.height * .5;
        else if (verticalAlign == Align.BOTTOM) yVal = -bounds.y - bounds.height;
        else throw new ArgumentError("Invalid vertical alignment: " + verticalAlign);

        //apply the new x and y cooridnates to your sprite (the one moving within the container we created above)
        s.x = xVal;
        s.y = yVal;

        //optional - this will create a small X at the 0,0 position of the container.
        //This is helpful if you want to see where your registration points are
        if (showRegistration) {
            var mark: Sprite = new Sprite();
            mark.graphics.lineStyle(1, _color);
            mark.graphics.moveTo(-5, -5);
            mark.graphics.lineTo(5, 5);
            mark.graphics.moveTo(-5, 5);
            mark.graphics.lineTo(5, -5);
            _container.addChild(mark);
        }
        //return your contianer sprite
        //This will replace the sprite that you passed in the first parameter.
        //That sprite is inside the container, so you won't notice
        return _container;


    }

Реализация:

//Create your sprite
        var _holder: Sprite = new Sprite();
    //Create a shape to put in your sprite
        var my_shape: Shape = new Shape();
        my_shape.graphics.beginFill(0x000000);
        my_shape.graphics.drawRect(0, 0, 200, 100);
        my_shape.graphics.endFill();
    //Add the shape to your sprite
        _holder.addChild(my_shape);
    //Align the holder (must be done AFTER all children have been added)
    //This will put the registration point at the top-center of the sprite. 
    //_holder is replaced by a sprite (container) that contains _holder.
    //The _holder inside the container is positioned appropriately.
    _holder = Position.alignPivot(_holder,Align.CENTER, Align.TOP);
    //Add the new sprite to your stage.
    this.addChild(_holder);

Список констант, поэтому вам не нужно писать их самостоятельно:

    public static const CENTER:String = "center";
    public static const LEFT:String = "left";
    public static const RIGHT:String = "right";
    public static const TOP:String = "top";
    public static const BOTTOM:String = "bottom";
0 голосов
/ 16 марта 2009

В зависимости от того, зачем вам это нужно, это можно решить с помощью DisplayObject. transform . matrix , которая возвращает объект Matrix .

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...