Вот упрощенный вариант.
На сцене клип mc с двумя кадрами.
По MOUSE_OVER и MOUSE_OUT - прыгает с кадра на кадр.
При перетаскивании - мышь слетает с клипа и он "моргает".
Чтобы этого избежать - отключаю слушатели на время таскания.
При MOUSE_UP возвращаю их на место, но нужно перевести клип в нужный кадр.
И тут использую hitTestPoint, чтобы проверить, над клипом мышь или нет.
Если нет - прыгаю на первый кадр.
Так вот: если резко потащить клип и бросить его - можно отловить ситуацию, когда hitTestPoint вернет true и клип не сбросится в деактивированное состояние. По идее, если MOUSE_UP сработало над клипом, должен был включиться обработчик MOUSE_OUT и сбросить клип, но trace показывает, что событие уже произошло ДО этого.
Минималистический пример:

Код AS3:
import flash.events.MouseEvent;
import flash.geom.Point;
var dltY:Number;
mc.buttonMode = true;
mc.addEventListener(MouseEvent.MOUSE_OVER, mOver);
mc.addEventListener(MouseEvent.MOUSE_OUT, mOut);
mc.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
function mOver(e:MouseEvent){
mc.gotoAndStop(2);
}
function mOut(e:MouseEvent){
mc.gotoAndStop(1);
}
function mDown(e:MouseEvent){
mc.removeEventListener(MouseEvent.MOUSE_OVER, mOver);
mc.removeEventListener(MouseEvent.MOUSE_OUT, mOut);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mMove);
stage.addEventListener(MouseEvent.MOUSE_UP, mUp);
dltY = mouseY - mc.y;
}
function mMove(e:MouseEvent){
mc.y = mouseY - dltY;
e.updateAfterEvent();
}
function mUp(e:MouseEvent){
mc.addEventListener(MouseEvent.MOUSE_OVER, mOver);
mc.addEventListener(MouseEvent.MOUSE_OUT, mOut);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, mUp);
checkHit();
}
function checkHit(){
if(!mc.hitTestPoint(stage.mouseX, stage.mouseY)){
mc.gotoAndStop(1);
}
}