3

これは簡単な作業だと思っていましたが、間違っています。

スプライトを使用して画像を表示し、ユーザーがそれをドラッグすると(MOUSE_DOWNおよびMOUSE_MOVE)、位置を取得しMOUSE_MOVEてオフセットを計算しました。

 var current: Point = new Point(event.localX, event.localY);
 sprite.x = current.x - start.x;
 sprite.y = current.y - start.y;

動作しますが、スムーズではありません。より良い解決策はありますか?


アップデート

デバッグの1日後、私はついに理由を見つけました。

fpsを大きくするとスムーズになりますが、この質問の鍵ではありません。

重要なのは、画像自体ではなく、stage聞くために使用する必要があるということです。MOUSE_MOVEまた、マウスの位置を取得するときは、ではなくevent.stageX/Y(またはstage.mouseX/Y)を使用する必要がありevent.localX/Yます。動画からのevent.localX/Y画像は安定しておらず、滑らかでもないので問題が発生します。

以下は私の作業コードです、楽しんでください:)

package {
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.net.URLRequest;
    import flash.text.TextField;

    public class DragIssue extends Sprite {

        private static const URL: String = "assets/m1.jpg";

        private var self: DragIssue;

        private var sprite: Sprite;

        private var startPoint: Point;

        private var offsetX: Number = 0;
        private var offsetY: Number = 0;

        public function DragIssue() {
            self = this;
            init();
            loadImage();
        }

        protected function init(): void {
            if (stage == null) {
                this.addEventListener(Event.ADDED_TO_STAGE, on_addedToStage);
            } else {
                stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            }

            function on_addedToStage(event: Event): void {
                self.removeEventListener(Event.ADDED_TO_STAGE, on_addedToStage);
                stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            }
        }

        public function loadImage(): void {
            var loader: Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
            loader.load(new URLRequest(URL));

            function imageLoaded(event: Event): void {
                var bitmap: Bitmap = event.target.content as Bitmap;

                self.sprite = new Sprite();
                sprite.addChild(bitmap);

                self.addChild(sprite);

                sprite.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
                sprite.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            }
        }

        private function onMouseMove(event: MouseEvent): void {
            if (startPoint) {
                sprite.x = offsetX + event.stageX - startPoint.x;
                sprite.y = offsetY + event.stageY - startPoint.y;
            }
        }

        private function onMouseUp(event: MouseEvent): void {
            startPoint = null;
            offsetX = sprite.x;
            offsetY = sprite.y;
        }

        private function onMouseDown(event: MouseEvent): void {
            startPoint = new Point(event.stageX, event.stageY);
        }

    }
}
4

4 に答える 4

2

ここで、これを試してください。単純な黒い四角ですが、実際にドラッグし始めるまでは問題ないように見えます。前述のように、フレームレートをより高い値に設定するのが理想的です。この場合、メモリ上の理由から、MOUSE_DOWNでフレームレートを60 fpsに上げ、MOUSE_UPで24に戻すことにしました。あなたは明らかにあなたが好きなようにそれを変えることができます。

import flash.display.*;
import flash.events.*;


var startX:Number;
var startY:Number;
var shape:Sprite = new Sprite();
shape.graphics.beginFill(0x000000);
shape.graphics.drawRect(0,0,50,50);
shape.graphics.endFill();
this.addChild(shape);

shape.addEventListener(MouseEvent.MOUSE_DOWN,this.mouseDown);

function mouseDown(e:MouseEvent = null):void{
    stage.frameRate = 60;
    startX = stage.mouseX - shape.x;
    startY = stage.mouseY - shape.y;
    stage.addEventListener(MouseEvent.MOUSE_MOVE,this.mouseMove);
    shape.addEventListener(MouseEvent.MOUSE_UP,this.mouseUp);
}

function mouseMove(e:MouseEvent = null):void{
    shape.x = stage.mouseX - startX;
    shape.y = stage.mouseY - startY;
}

function mouseUp(e:MouseEvent = null):void{
    shape.removeEventListener(MouseEvent.MOUSE_UP,this.mouseUp);
    stage.removeEventListener(MouseEvent.MOUSE_MOVE,this.mouseMove);
    stage.frameRate = 24;
}

MOUSE_UPのMOUSE_MOVEイベントを削除していることを確認してください。それが鍵です。それ以外の場合は、すべてのMOUSE_DOWNでイベントを再度追加し、同じコードを同時に繰り返し実行することになります。申し訳ありませんが、私の構文は100%適切ではありません。私はこれをFlashBuilderで行うのではなく、CS5.5で非常にすばやくまとめました。

于 2012-09-07T21:29:45.317 に答える
1

スムーズなドラッグエクスペリエンスをお探しの場合は、次の方法を使用できます(ドラッグしているものは「ドラジェ」と呼ばれ、このコードはドラジェの親のスコープ内にあるとしましょう)。

function startDragging():void {
    dragee.addEventListener(Event.ENTER_FRAME,dragUpdate);
}

function stopDragging():void {
    dragee.removeEventListener(Event.ENTER_FRAME,dragUpdate);
}

var decay:Number = .25; //1 is no decay, .1 would be cazy slow

function dragUpdate(e:Event):void {
    dragee.x += decay * (mouseX - dragee.x);
    dragee.y += decay * (mouseY - dragee.y);
}
于 2012-09-07T17:04:51.373 に答える
1

スムーズな動きを得るには、高いフレームレートを使用する必要があります。ほとんどのLCDモニターのデフォルトであるため、最適なフレームレートは60fpsです。

私は自分の手にコードを持っていないので、ここにコードを置きます(テストされていません)

yourClip.addeventListenner(MouseEvent.MOUSE_DOWN, startDrag);

function startDrag(e:MouseEvent = null):void{
    // record positon of the mouse relative to the clip
    deltaX=stage.mouseX-yourClip.x;
    deltaY=stage.mouseY-yourClip.y;
    // attach on mouse move event
    yourClip.addeventListenner(MouseEvent.MOUSE_MOVE, updateDrag);
    // attach stop event (on Stage)
    Stage.addeventListenner(MouseEvent.MOUSE_UP, stopDrag);
    }
function updateDrag(e:MouseEvent = null):void{
    yourClip.x=stage.mouseX-deltaX
    yourClip.y=stage.mouseY-deltaY
}

function stopDrag(e:MouseEvent = null):void{
   yourClip.removeEventListenner(MouseEvent.MOUSE_MOVE, updateDrag);
   stage.removeEventListenner(MouseEvent.MOUSE_UP, stopDrag);
}
于 2012-09-07T16:13:42.463 に答える
0

event.updateAfterEvent()ドラッグハンドラーを呼び出してみてください。この関数は、次のフレームまで待つのではなく、ステージをすぐに再描画するようにFlashに指示します。

于 2012-09-08T00:30:35.677 に答える