如何在动作脚本

时间:2015-09-30 02:10:51

标签: actionscript-3 flash actionscript drag-and-drop mouseevent

首先,我的问题基本上与这个问题相同:

How to drag an image to move it smoothly on screen, with ActionScript?

我希望我拖动的Sprites能够在屏幕上顺利地跟上鼠标,而且不会落后。

我注意到在旧版的ActionScript 3 Cookbook中,他们使用了与上述链接中使用的DraggableSprite类似的解决方案。即,使用舞台实例侦听MouseMove事件,然后从event.stageX和stageY属性中读取。

我已经做到了。

但是我的Sprite仍然没有用鼠标光标锁定。它落后了。我觉得我必须遗漏一些东西。但是,如果上面发布的解决方案(即监听舞台的MouseMove并使用event.stageX / Y)仍然是最新的,我所描述的问题不应该发生,请同时告诉我。即使它不应该工作,我已经尝试了event.updateAfterEvent(),它似乎也没有任何积极的影响。

非常感谢任何帮助或建议。

这是我编写处理程序的一个简单示例。如果粘贴到新项目中,它应该按原样运行。

我还应该补充一点,我正在使用Adobe AIR将其编译为桌面应用程序。运行时间是一个因素???

package {
  import flash.display.Sprite;
  import flash.events.MouseEvent;

  [SWF(width="1280", height="720", frameRate="30")]
  public class test_drag extends Sprite {

    private var testDragSprite:TestDragSprite;

    public function test_drag() {
      super();

      graphics.clear();
      graphics.beginFill(0x0000FF);
      graphics.drawRect(0, 0, 1280, 720);
      graphics.endFill();

      testDragSprite = new TestDragSprite();
      addChild(testDragSprite);

      testDragSprite.addEventListener(MouseEvent.MOUSE_DOWN, testDragSprite_mouseHandler);
      testDragSprite.addEventListener(MouseEvent.MOUSE_UP, testDragSprite_mouseHandler);
    }

    private function testDragSprite_mouseHandler(e:MouseEvent):void {
      switch (e.type) {
        case MouseEvent.MOUSE_DOWN: {
          stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
          break;
        }
        case MouseEvent.MOUSE_UP: {
          stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
          break;
        }
      }
    }

    private function mouseMoveHandler(e:MouseEvent):void {
      //-20 to keep the sprite centered on the mouse
      testDragSprite.x = e.stageX - 20;
      testDragSprite.y = e.stageY - 20;
      //e.updateAfterEvent(); //strange effect, but doesn't solve the problem.
    }
  }
}
import flash.display.Sprite;
internal class TestDragSprite extends Sprite {
  public function TestDragSprite() {
    super();
    graphics.lineStyle(1, 0xDDDDDD);
    graphics.beginFill(0xFF0000);
    graphics.drawRoundRect(0, 0, 40, 40, 12);
    graphics.endFill();
  }      
}

3 个答案:

答案 0 :(得分:2)

总会有一点滞后,但是:

前两条建议会对您的代码/效果做出最明显的改变。

  • 启用硬件图形加速;编辑AIR应用程序 描述符文件(xml)并将renderMode设置为Direct(或GPU)。请教 Adobe Air帮助了解详情。

    <!-- The render mode for the app (either auto, cpu, gpu, or direct). Optional. Default auto -->
    <renderMode>direct</renderMode>
    
  • 使用startDrag和endDrag绕过mouseMoveHandler中的手动分配。

替换:

testDragSprite.addEventListener(MouseEvent.MOUSE_DOWN, testDragSprite_mouseHandler);
testDragSprite.addEventListener(MouseEvent.MOUSE_UP, testDragSprite_mouseHandler);

使用:

testDragSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
testDragSprite.addEventListener(MouseEvent.MOUSE_UP, mouseUp);

添加新处理程序:

private function mouseDown(e:MouseEvent):void {
    testDragSprite.startDrag();
}
private function mouseUp(e:MouseEvent):void {
    testDragSprite.stopDrag();
}
  • 提高你的帧速率,但是当你的应用程序/游戏变得更复杂时,请注意你的CPU使用率,因为你可能需要降低它以允许你的游戏逻辑足够的时间在帧之间完成(否则你最终得到的是称为长帧,您可以使用免费的Adobe Scout分析工具来监视这些以及许多其他内容。

  • 在显示器上添加帧率HUD,以便监控实际帧率低于请求的帧率(这是用于调试)

  • 如果您的游戏是基于2d的,请考虑使用开源Starling framework,因为所有内容都是由GPU与Flash的标准显示列表对象直接呈现的。

答案 1 :(得分:0)

试试成员函数startDrag。

答案 2 :(得分:0)

Feathers UI库包含一个拖放模块。上面的答案都使用了旧的&#39;显示列表,不支持移动设备。如果您希望您的代码跨平台工作,您需要一个GPU框架(最受欢迎的是Feathers所基于的Starling,以及大多数Adobe AIR游戏和应用程序)。