【问题标题】:flash drag and drop one of many sprite instances快速拖放许多精灵实例之一
【发布时间】:2013-07-11 19:18:29
【问题描述】:

我在拖放功能和对象选择方面遇到问题。

我创建了简单的 flash 编曲器(将表格图标添加到舞台 - 房间)。我有创建表格图标新实例的按钮,我可以在舞台上拖放。

问题是我只能拖放最后添加的图标。如果我添加新的实例 od 图标,我将无法获取(拖放)之前创建的任何图标:/

我的代码在这里:主类

import flash.events.MouseEvent;
import flash.events.Event;
import com.adobe.images.JPGEncoder;
import flash.geom.Point;

btn_middleTable.addEventListener(MouseEvent.CLICK, f_middleIco);
btn_bigTable.addEventListener(MouseEvent.CLICK, f_bigIco);
btnSave.addEventListener(MouseEvent.CLICK, f_save);

function f_middleIco(event:MouseEvent):void
{
    var middle:MiddleIco = new MiddleIco();
    middle.x = 20;
    middle.y = 20;
    stage.addChild(middle);
    trace("created");
}

function f_bigIco(event:MouseEvent):void
{
    var big:BigIco = new BigIco();
    big.x = 20;
    big.y = 20;
    stage.addChild(big);
    trace("created");
}

function f_save(event:MouseEvent)
{
    var jpgEncoder:JPGEncoder;
    jpgEncoder = new JPGEncoder(90);

    var bitmapData:BitmapData = new BitmapData(stage.width, stage.height);
    bitmapData.draw(stage, new Matrix());
    var img = jpgEncoder.encode(bitmapData);

    var file:FileReference = new FileReference();
    file.save(img, "filename.png");
}

图标实例包:

package  {

    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.geom.Point;

    public class BigIco extends MovieClip {
            public var active:Boolean;

        public function BigIco() {
            // constructor code
            this.addEventListener(Event.ENTER_FRAME, f_move);
            this.addEventListener(MouseEvent.MOUSE_DOWN,downf);
            this.addEventListener(MouseEvent.MOUSE_UP,upf);
        }

        public function f_move(e:Event)
        {
            if(active==true)
            {
                startDrag();
            }
            else if(active==false)
            {
                stopDrag();
            }
        }

        public function downf(e:MouseEvent)
        {
            active = true;
        }
        public function upf(e:MouseEvent)
        {
            active = false;
        }
}
}

我该怎么做才能选择实际上在鼠标光标上的每个图标(实例)?

【问题讨论】:

  • 请注意,虽然我的回答完全删除了f_move,但在这种方法中,不需要else if(active==false) - 如果active 不是真的,那就是假的,所以else 就足够了。您还可以将if(active==true) 缩短为if (active)
  • 最后一件事:除了相当高级的情况,使用stage.addChild() 将实例添加到主时间线不是一个好主意 - 因为您实际上并没有将它们添加到时间线,而是“在显示层次结构中”(您在 Flash 中看到的主时间线本身就是 stage 的子级)。它在这里可以工作,但在其他情况下可能会导致很难找到错误,而您真正想要的是this.addChild()。参见例如stackoverflow.com/questions/13096993/correct-use-of-addchild

标签: actionscript-3 flash


【解决方案1】:

理论:startDragstopDrag 并不意味着被重复调用 - 但它们会在每一帧,对于您添加的每个剪辑都会调用一次,因为您使用的是 ENTER_FRAME 侦听器。

我尚未对此进行测试,但调用 stopDrag 实际上可能会停止任何拖动 - 包括在其他剪辑上 - 因为你是 only allowed to drag a single Sprite (and hence MovieClip) in the first place

因此,如果该理论成立,您的第一个图标上的startDrag() 将立即被新图标上的f_move() 取消调用stopDrag()

但是无论如何你都不需要ENTER_FRAME 监听器。这应该给出相同的结果(除了它实际上有效) - 只需立即在鼠标侦听器中调用拖动方法:

public class BigIco extends MovieClip {
    public var active:Boolean;

    public function BigIco() {
        // constructor code
        this.addEventListener(MouseEvent.MOUSE_DOWN, downf);
        this.addEventListener(MouseEvent.MOUSE_UP, upf);
    }

    public function downf(e:MouseEvent)
    {
        // Unless you're going to use 'active' for other stuff,
        // you can remove this line:
        active = true; 
        startDrag();
    }
    public function upf(e:MouseEvent)
    {
        // Same here:
        active = false;
        stopDrag();
    }
}

除此之外,我无法在您的代码中发现任何真正的问题。

编辑:“完美”版本,如果指针不在图标上方,也会检测鼠标向上:

public class BigIco extends MovieClip {

    public function BigIco() {
        // Only add mouse down listener here. We'll add up when needed below:
        this.addEventListener(MouseEvent.MOUSE_DOWN,downf);
    }

    public function downf(e:MouseEvent)
    {
        // Add event listener to stage, so as to be triggered even if
        // the pointer isn't over the icon when releasing the button.
        // Note that this will also work even with the mouse *outside*
        // the stage/swf area:
        stage.addEventListener(MouseEvent.MOUSE_UP,upf);
        startDrag();
    }
    public function upf(e:MouseEvent)
    {
        // Remember to remove the event listener after use:
        stage.removeEventListener(MouseEvent.MOUSE_UP, upf);
        stopDrag();
    }
}

【讨论】:

  • 如果我只留下鼠标向下和鼠标向上事件,我不能放下我的图标;/package { import flash.display.MovieClip; import flash.events.MouseEvent; import flash.events.Event; import flash.geom.Point; public class BigIco extends MovieClip { public var active:Boolean; public function BigIco() { this.addEventListener(MouseEvent.MOUSE_DOWN,downf); this.addEventListener(MouseEvent.MOUSE_UP,upf); } public function downf(e:MouseEvent) { startDrag(); } public function upf(e:MouseEvent) { stopDrag(); } } }
  • 对我来说效果很好 - 并且在大约 20-30 个早期项目中使用过。但是,如果您在光标实际上不在剪辑上方时释放鼠标按钮,则不会收到通知。为此,您需要改为在舞台上处理 MOUSE_UP - 以便无论鼠标光标在哪里都会触发它。
  • 会尝试用它做点什么,谢谢。如果我有麻烦,我会写。感谢您的帮助:)。
  • 为了演示,这里是完全相同的文件,带有您的原始时间线代码,以及我上面列出的代码:dl.dropboxusercontent.com/u/14034871/StackOverflow/patio2.zip(临时链接,将在看到时删除它和此评论)。工作方式完全相同 - 没有意大利面条代码。 ;-)
  • 谢谢,我会看的。我制作意大利面条代码是因为我不太了解任何编程语言:/我只知道基本的东西:)。再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多