I have a movie clip where I've placed start drag and stop drag actions, and I'd like to activate a button action (run a movie clip named person_mo) with the ReleaseToDrop function. However, I cannot code it correctly. Here is the AS I have for the drag:
stop();
/* Drag and Drop
Makes the specified symbol instance moveable with drag and drop.
*/
SCOPE2.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
SCOPE2.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
SCOPE2.stopDrag();
}
How can I play the person_mo movie clip and stop the drag?
After I tested your code, your stopDrag function is working well. You just need to fire your event/function/ command when you fire the ReleaseToDrop function.
stop();
/* Drag and Drop
Makes the specified symbol instance moveable with drag and drop.
*/
SCOPE2.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
SCOPE2.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
SCOPE2.stopDrag();
person_mo.play(); // if you want to run the movie clip
yourFunction(); //or else if you want a function to fire, simply add yourFunction which fires the button action.
}
I hope this helps.
Related
I'am drag game scene in Flash project (mouse down - start drag, mouse up - stop drag). If I mouse up outside stage, click on any object (buttons) don't work once. After one click other click works fine. What's wrong?
update: Trace logs shown that there event as mouseOver, mouseDown, mouseUp, mouseOut are dispatches, but not CLICK.
update: There is silencer of first click after drag in the project. It's necessary to eliminate situation of end drag on some game object (dispath click). Sorry. Thank you all for answers.
You might be losing focus when leaving the stage. Try using (Event.MOUSE_LEAVE) to 'force' a mouse_up.
something like this:
private var _draggedItem:Sprite;
myDisplayObject.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
private function mouseDownHandler(event:MouseEvent):void {
_draggedItem = event.currentTarget as Sprite;
_draggedItem.startDrag();
_draggedItem.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
stage.addEventListener(Event.MOUSE_LEAVE, stageMouseOutHandler);
}
private function stopDragCurrentItem():void {
if (_draggedItem) {
_draggedItem.stopDrag();
_draggedItem.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
if (stage) {
stage.removeEventListener(Event.MOUSE_LEAVE, stageMouseOutHandler);
}
_draggedItem = null;
}
}
private function mouseUpHandler(event:MouseEvent):void {
stopDragCurrentItem();
}
private function stageMouseOutHandler(event:Event):void {
trace("stage out!")
stopDragCurrentItem();
}
update:
And concerning the lost focus, you cold do the following in html where you embed your flash:
<object classid="..." codebase="...." width=550 height=400
name="myMovie" onmouseover="window.document.myMovie.focus();">
though i haven't tested it.
I'm running into some problems with making the movie clip so I can drag it about the stage. The scenario: the user clicks a button that spawns the movie clip to the stage, from there they can move the item around the stage - it's a draggable object. I can make it so the movieClip spawns, I can make it so it drags... but i can't make it do both, once I try to attach the drag function. Any pointers please? I'm new to as3! :-)
spawner_btn.addEventListener(MouseEvent.CLICK, spawnspinkjewel);
function spawnspinkjewel(event:MouseEvent):void
{
var myChild:pink_jewel= new pink_jewel();
stage.addChild(myChild)
myChild.x=300;
myChild.y=150;
}
pink_jewel.addEventListener(MouseEvent.MOUSE_DOWN, pickupblack_pink_jewel);
pink_jewel.addEventListener(MouseEvent.MOUSE_UP, dropblack_pink_jewel);
function pickupblack_pink_jewel(event:MouseEvent):void {
event.target.startDrag(true);
}
function dropblack_pink_jewel(event:MouseEvent):void {
event.target.stopDrag();
}
You added the listeners to the incorrect object.
Change this:
pink_jewel.addEventListener(MouseEvent.MOUSE_DOWN, pickupblack_pink_jewel);
pink_jewel.addEventListener(MouseEvent.MOUSE_UP, dropblack_pink_jewel);
To this:
myChild.addEventListener(MouseEvent.MOUSE_DOWN, pickupblack_pink_jewel);
myChild.addEventListener(MouseEvent.MOUSE_UP, dropblack_pink_jewel);
I have a project where I have a scrolling list. I would like for my user to be able to "long touch" an item on the list so that they can delete it.
I am developing in Air for iOS using Flash CS6 so I don't really know much about the appropriate MultiTouch gestures for iOS deployment.
In my mind, the animation steps I would like to go like so..
Previously invisible button called btn_delete inside the Item movieclip will appear when Long Touch starts + timer begins
Intermediate step: btn_delete will rotate 90 degrees using TweenMax Rotate (I have this covered)
Final step: when timer reaches it's conclusion, a dialog box / confirmation box will pop up and ask the user if they are sure if they want to delete the item.
So here is some generic code I've written quickly to give you an idea of my structure so far (I've omitted the interlinking listener functions):
function exampleFunction {
_item.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
}
//-- Long Press Listener Functions--//
function onTouchBegin(eBegin:TouchEvent) {
trace("start");
}
function onTouchRotate(eEnd:TouchEvent) {
trace("rotation of image");
}
function onTouchEnd(eEnd:TouchEvent) {
trace("end");
}
If anyone has a piece of code they've already written that roughly matches my criteria then please post it!
I would just use MouseEvent for this.
var timer:Timer = new Timer( 500 ); //ms
timer.addEventListener( TimerEvent.TIMER_COMPLETE, timerCompleteHandler );
listItem.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
function mouseDownHandler( e:MouseEvent ):void {
timer.start();
stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
}
function mouseUpHandler( e:MouseEvent ):void {
//just some clean up to reset the timer and remove the mouse up event listener from the stage
timer.reset();
stage.removeEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
}
function timerCompleteHandler( e:TimerEvent ):void {
timer.reset();
stage.removeEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
//do delete actions here
}
So on mouse down, you start your timer and listen for a mouse up event (on the stage and not the component. That is important. If you want to know why, try it on the component and experiment). On mouse up, you reset the timer so the next time you mouse down, it starts at 0 (reset() has the added benefit of stopping the timer). On timer complete, you do the same as in mouse up in addition to your delete code.
I'm using a MouseEvent here just because it behaves identical to TouchEvent (for the most part) in this instance and it could be used on the desktop (meaning you can test in the emulator and you could add this to other projects if you wanted)
UPDATE:
Just reread your question and realized I missed the rotate. For this, just add another timer with a separate complete handler that and in that function, ONLY do the rotation and reset that timer.
On stage, I have a MovieClip named "mc" with a simple rectangle drawn inside. mc also has a Button child named "btn" which is another simple rectangle ( smaller than mc's rectangle obviously). Then I have this code on stage.
function mcDown( _e:MouseEvent):void{
trace( "mc" );
}
function btnClick( _e:MouseEvent):void{
trace( "btn" );
}
mc.addEventListener( MouseEvent.MOUSE_DOWN, mcDown );
mc.btn.addEventListener( MouseEvent.CLICK, btnClick );
The problem I am having is when click the button, mcDown event is also triggered and traces both "mc" and "btn".
How can I make it so that when I click the button, it triggers only btnClick and not mcDown along? I tried MOUSE_UP instead of CLICK, same problem. And mcDown event has to remain MOUSE_DOWN.
There is no way to prevent bubbling except setting the bubbles parameter as false in the dispatchEvent.
dispatchEvent(EVENT_TYPE, BUBBLES,....);
However, you can avoid the bubbling by doing a check. Just have the below line as first line of your listener function it avoids the events dispatched from all objects other then targets.
if(e.eventPhase != EventPhase.AT_TARGET) return;
So, for your sample code, when you click on the button both the events dispatches but in the mcDown function it won't execute after the above said line.
If you add button in a MC, and you click on the button, you also click on the MC, because the part of the MC that is under the button is still there and it runes the function for the whole of the MC, you can't remove it.
So it's good idea to make a function that will check if the button is pressed, otherwise it will run the function for the whole of the MC.
This one should do it.
//add this in you constructor
mc.addEventListener(MouseEvent.MOUSE_DOWN, myReleaseFunc);
function myReleaseFunc(e:MouseEvent):void {
if(e.currentTarget.name == Btn1) //Btn1 is instance name for a button
{
Btn_func1();
}
else if(e.currentTarget.name == Btn2) //Btn2 is another button.
{
Btn_func2();
//For every button you'll need to add another function and if statement to check if that button was clicked.
}
else
{
Mc_func();
}
}
// this outside the main class
function Mc_func():void{
//you code here
}
function Btn_func1():void{
//you code here
}
function Btn_func2():void{
//you code here
}
I think that this way is much more effiecient and it will works better and faster and you'll have a lot smaller chance of overloading the system.
Are there any circumstances under which a Flash application could receive two MouseEvent.MOUSE_DOWN without a MouseEvent.MOUSE_UP in between?
In my ActionScript 3 application, I want to track the user dragging a sprite. My plan is to listen for a MouseEvent.MOUSE_DOWN, start an indefinitely repeating timer that records the mouse position, and stop the timer on MouseEvent.MOUSE_UP. Is that a good plan?
Click but do not release the button.
While keeping the button down move the cursor outside.
Release the button outside.
Come back inside and click again.
You will get two down event without an up event.
A better solution to drag-and-drop might be to listen MOUSE_MOVE event and in the event handler check buttonDown property. If the button is down while moving, this will be true, otherwise false.
EDIT: For stage even if you release the button outside the flash window then up event is fired. So for stage this can work, but still instead of timer using MOUSE_MOVE with buttonDown looks better to me. You can check yourself with the following code:
public class StageEventTest extends Sprite
{
public function StageEventTest()
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
}
private function onDown(evt:MouseEvent):void {
trace("down");
}
private function onUp(evt:MouseEvent):void {
trace("up");
}
private function onMove(evt:MouseEvent):void {
trace("move", evt.buttonDown);
}
}
it will miss the mouse up event if the mouse is outside of the stage and continue it's mouse tracking when mousing over the stage since the mouse up event was never called. this likely problem can be mitigated by using Event.MOUSE_LEAVE - forward the mouse leave event to the mouse up event handler so that if the user mouses away from the stage the mouse up event will be called.
Yes, but unless you are listening to the stage, I think you can miss the mouseup event if the mouse has gone outside the Flash movie. Nothing beats an experiment though.
Below you can find the code I always use for custom dragging. Normally, it should work fine. I listen to the MOUSE_MOVE-event for repositioning and tracking the sprite, but you can just as well use the Event.ENTER_FRAME-event or use a timer instead.
ObjectToDrag.addEventListener(MouseEvent.MOUSE_DOWN, startCustomDrag);
public function startCustomDrag(e:MouseEvent):void
{
_prevX= e.stageX;
_prevY= e.stageY;
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragObject); //REPLACE BY TIMER OR Event.ENTER_FRAME
stage.addEventListener(MouseEvent.MOUSE_UP, stopCustomDrag);
}
private function dragObject(e:MouseEvent):void
{
ObjectToDrag.x += _prevX - e.stageX; //OR ANY OTHER CALCULATION
ObjectToDrag.y += _prevY - e.stageY; //OR ANY OTHER CALCULATION
_prevX= e.stageX;
_prevY= e.stageY;
}
public function stopCustomDrag(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragObject); //REPLACE BY TIMER OR Event.ENTER_FRAME
stage.removeEventListener(MouseEvent.MOUSE_UP, stopCustomDrag);
}