簡體   English   中英

AS3:使用 actionscript 設置 DisplayObject 的注冊點?

[英]AS3: setting registration point of a DisplayObject with actionscript?

您將如何通過 actionscript 在 Sprite 或 Shape 上設置注冊點(我知道使用 Flash 很簡單,但我需要純粹在 actionscript 中完成)

Flash 播放器 API 沒有公開這一點。 我相信這是因為 Flash 在創建 SWF 時實際上將注冊點烘焙到形狀數據中。 因此,沒有實際的注冊點可移動(相反,您將移動形狀數據......如果 Flash 播放器允許您編輯形狀數據。)。

我總是通過簡單地將我的精靈/形狀設置為另一個 DisplayObject 來解決這個問題。 所以,如果我有 spriteA 並想將其注冊點設置為 (15, 35),我會這樣做:


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

然后從那時起,在我之前提到 spriteA 的任何地方都引用 spriteB。

使用變換矩陣這是可能的。 這是在此站點上找到的一個很好的實現。

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);
    }
}

你的意思是索引?

跟進評論,您可以像下面這樣快速實施。 這並不是您想要的,因為您無法為每個孩子設置不同的對齊方式。 我只是不想讓它太復雜,它更像是'工作偽代碼'來給你一個想法......

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;
            }
        }
    }
}

我希望這會對某人有所幫助。 Starling 框架有一個很棒的方法,叫做“alignPivot()”。 我采用了他們的概念並將其改編為 Flash DisplayList。 您實際上是告訴精靈將其注冊更改為左、右、中心、頂部和底部。 此代碼將您的精靈放置到容器精靈中並適當地定位自己。 它返回容器精靈,其中包含原始精靈。

代碼存儲在一個單獨的名為“Position”的地方。

    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";

根據您需要它的原因,它可能會通過使用 DisplayObject 來解決。 變換 matrix ,它返回一個矩陣object。

例如,如果你想改變旋轉點,那么你可以使用變換的矩陣來做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM