我在想这是个简单的任务,但是我错了。
我用了一个精灵来显示图像,而当用户拖动它(MOUSE_DOWN和MOUSE_MOVE),我得到的位置 MOUSE_MOVE
和计算的偏移量:
无功电流:点=新的点(event.localX,event.localY);
sprite.x = current.x - start.x;
sprite.y = current.y - start.y;
它的工作原理,但并不顺利。有没有更好的解决办法?
更新
调试了一天之后,我终于找到了原因。
更大的 FPS 可以让它流畅,但它不是对这个问题的关键所在。
关键是我应该使用期
来听 MOUSE_MOVE
,而不是图像本身。并获得鼠标位置的时候,我应该使用 event.stageX / Y
(或 stage.mouseX / Y
),没有 event.localX / Y
。该 event.localX / Y
从运动图像,既不稳定,也不流畅,导致我的问题。
以下是我的工作code,乐在其中:)
包{
匹配import flash.display.Bitmap;
进口flash.display.Loader;
进口flash.display.Sprite;
进口对象类型:flash.events.Event;
进口flash.events.MouseEvent;
进口flash.geom.Matrix;
进口flash.geom.Point;
进口flash.net.URLRequest;
进口API元素flash.text.TextField;
公共类DragIssue扩展Sprite {
私有静态常量网址:字符串=财产/ m1.jpg;
私人VAR自:DragIssue;
私人VAR精灵:精灵;
私人VAR的startPoint:点;
私人VAR offsetX:数= 0;
私人VAR offsetY:数= 0;
公共职能DragIssue(){
自=这一点;
在里面();
的LoadImage();
}
保护功能的init():无效{
如果(阶段== NULL){
this.addEventListener(Event.ADDED_TO_STAGE,on_addedToStage);
} 其他 {
stage.addEventListener(的MouseEvent.MOUSE_MOVE,的OnMouseMove);
}
功能on_addedToStage(事件:事件):无效{
self.removeEventListener(Event.ADDED_TO_STAGE,on_addedToStage);
stage.addEventListener(的MouseEvent.MOUSE_MOVE,的OnMouseMove);
}
}
公共职能的LoadImage():无效{
VAR装载机:装载机=新的Loader();
loader.contentLoaderInfo.addEventListener(引发Event.COMPLETE,imageLoaded);
loader.load(新的URLRequest(URL));
功能imageLoaded(事件:事件):无效{
VAR位:位图= event.target.content为位图;
self.sprite =新的Sprite();
sprite.addChild(位);
self.addChild(精灵);
sprite.addEventListener(的MouseEvent.MOUSE_DOWN,onmousedown事件);
sprite.addEventListener(侦听MouseEvent.MOUSE_UP,onMouseUp);
}
}
私有函数的OnMouseMove(事件:MouseEvent)方法:无效{
如果(的startPoint){
sprite.x = offsetX + event.stageX - startPoint.x;
sprite.y = offsetY + event.stageY - startPoint.y;
}
}
私有函数onMouseUp(事件:MouseEvent)方法:无效{
的startPoint = NULL;
offsetX = sprite.x;
offsetY = sprite.y;
}
私有函数onmousedown事件(事件:MouseEvent)方法:无效{
的startPoint =新的点(event.stageX,event.stageY);
}
}
}
解决方案
下面,试试这个。这只是一个简单的黑色正方形,但看起来很好,直到你的真正的开始拖拽它。正如所提到的,帧率设置为更高的东西是最理想的。在这种情况下,我决定了帧率在MOUSE_DOWN 60fps的落回至24日在MOUSE_UP内存的原因。可以很明显的改变,请您如何。
进口flash.display使用*。
进口flash.events *。
VAR STARTX:数字;
VAR startY:数字;
VAR形状:雪碧=新的Sprite();
shape.graphics.beginFill(0x000000处);
shape.graphics.drawRect(0,0,50,50);
shape.graphics.endFill();
this.addChild(形状);
shape.addEventListener(的MouseEvent.MOUSE_DOWN,this.mouseDown);
功能MOUSEDOWN(E:的MouseEvent = NULL):无效{
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);
}
功能的mouseMove(E:的MouseEvent = NULL):无效{
shape.x = stage.mouseX - STARTX;
shape.y = stage.mouseY - startY;
}
功能mouseUp事件(E:的MouseEvent = NULL):无效{
shape.removeEventListener(侦听MouseEvent.MOUSE_UP,this.mouseUp);
stage.removeEventListener(的MouseEvent.MOUSE_MOVE,this.mouseMove);
stage.frameRate = 24;
}
请确保您在MOUSE_UP去除MOUSE_MOVE事件。这是关键。否则,你再添加事件上的每个MOUSE_DOWN,最终重复运行相同的code,同时进行。很抱歉,我的语法是不是100%正确的;我在CS5.5扔了一起非常快的,而不是做在Flash Builder中。
I was thinking this is a simple task, but I'm wrong.
I used a sprite to display an image, and when user drag it(MOUSE_DOWN and MOUSE_MOVE), I got the position in MOUSE_MOVE
and calculated the offsets:
var current: Point = new Point(event.localX, event.localY);
sprite.x = current.x - start.x;
sprite.y = current.y - start.y;
It works but not smooth. Is there a better solution?
UPDATE
After a day of debugging, I finally found the reason.
Bigger fps can make it smoother, but it's not the key of this question.
The key is I should use stage
to listen MOUSE_MOVE
, not the image itself. And when getting the mouse position, I should use event.stageX/Y
(or stage.mouseX/Y
), not event.localX/Y
. The event.localX/Y
from the moving image, is neither stable nor smooth, that causes my problem.
Following is my working code, enjoy it :)
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);
}
}
}
解决方案
Here, try this. It's just a simple black square, but it looks fine until you really start dragging it around. As was mentioned, setting the framerate to something higher is ideal. In this case, I decided to up the framerate to 60fps in the MOUSE_DOWN and drop it back to 24 in MOUSE_UP for memory reasons. You can obviously change that how you please.
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;
}
Make sure you are removing the MOUSE_MOVE event on MOUSE_UP. That is key. Otherwise, you re-add the event on every MOUSE_DOWN and end up running the same code repeatedly, simultaneously. Sorry my syntax isn't 100% proper; I threw this together really quick in CS5.5 rather than doing it in Flash Builder.