I am a new new person who learn action script 3.
i have problem when i convert keyboard event to mouse event when i moving a walking character.
when use the keyboard event i have no problem. this is my code
import flash.ui.Keyboard;
var speed:Number=2;
stage.addEventListener(KeyboardEvent.KEY_DOWN, stikman);
function stikman(e:KeyboardEvent)
{
if (e.keyCode==Keyboard.LEFT)
{
stik.x-=speed;
stik.scaleX=-1;
stik.stik2.play();
}
else if (e.keyCode==Keyboard.RIGHT)
{
stik.x+=speed;
stik.scaleX=1;
stik.stik2.play();
}
}
and then i try to change keyboard event to mouse event when moving character with button it should press click, click and click. i want to hold the click when moving the character and when mouse up the character stop. but i still don't know how. this my code when i try to change to mouse event
var speed:Number=2;
mundur.addEventListener(MouseEvent.MOUSE_DOWN, stikman);
function stikman(e:MouseEvent)
{
stik.x-=speed;
stik.scaleX=-1;
stik.stik2.play();
}
maju.addEventListener(MouseEvent.CLICK, stikman2);
function stikman2(e:MouseEvent)
{
stik.x+=speed;
stik.scaleX=1;
stik.stik2.play();
}
Because keyboard produces KeyboardEvent.KEY_DOWN event repeatedly as long as key is pressed, while MouseEvent.CLICK as well as MouseEvent.MOUSE_DOWN are dispatched only once per user action.
With mouse you need to change the logic.
// Subscribe both buttons.
ButtonRight.addEventListener(MouseEvent.MOUSE_DOWN, onButton);
ButtonLeft.addEventListener(MouseEvent.MOUSE_DOWN, onButton);
var currentSpeed:Number = 0;
var isPlaying:Boolean = false;
function onButton(e:MouseEvent):void
{
// Set up the directions and start the animation.
switch (e.currentTarget)
{
case ButtonLeft:
currentSpeed = -speed;
stik.stik2.play();
stik.scaleX = -1;
break;
case ButtonRight:
currentSpeed = speed;
stik.stik2.play();
stik.scaleX = 1;
break;
}
isPlaying = true;
// Call repeatedly to move character.
addEventListener(Event.ENTER_FRAME, onFrame);
// Hook the MOUSE_UP even even if it is outside the button or even stage.
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onFrame(e:Even):void
{
// Move character by the designated offset each frame.
stik.x += currentSpeed;
if (!isPlaying)
{
// Stop at last frame.
// if (stik.stik2.currentFrame == stik.stik2.totalFrames)
// Stop at frame 1.
if (stik.stik2.currentFrame == 1)
{
// Stop the animation.
stik.stik2.stop();
// Stop moving.
removeEventListener(Event.ENTER_FRAME, onFrame);
}
}
}
function onUp(e:MouseEvent):void
{
// Indicate to stop when the animation ends.
isPlaying = false;
// Unhook the MOUSE_UP event.
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
}
Related
I was just curious if I add an a EventListener such as addEventListener(MouseEvent.CLICK, onClick);
Inside an ENTER_FRAME event function will it add an instance of that MouseEvent Listener every frame?
Here is my code now just wondering if this is bad practice:
addEventListener(Event.ENTER_FRAME, engineLogic);
inside my engineLogic function:
//Max objects for rock throwers on left
if (aXPositionArray.length == 0)
{
//Remove listener to add more and make button turn grey etc
rockThrowerSpawnScreen.left.removeEventListener(MouseEvent.CLICK, chooseSpawnSideRockThrowers);
rockThrowerSpawnScreen.left.visible = false;
}else
if (aXPositionArray.length != 0)
{
rockThrowerSpawnScreen.left.addEventListener(MouseEvent.CLICK, chooseSpawnSideRockThrowers);
rockThrowerSpawnScreen.left.visible = true;
trace("LISTENER");
}
or does it only add it once and checks the function every frame?
I am doing a game for my computer science class and I am working on inventory, dragging an item into it. I do not know how to set the item as whatever the user clicked to drag.
At the moment I hard coded it to the item they are dragging, but in the future I want more items, so a variable set to the item they are dragging would make it work perfectly, but I don't know what it's called to do that.
Here is my code for inventory item dragging
function dragItem (event:MouseEvent):void
{
knife_loot.startDrag();
}
function dropItem (event:MouseEvent):void
{
knife_loot.stopDrag();
if ((knife_loot.hitTestObject(inv_game)) && (inv_game.visible == true))
{
trace("Item dropped in inventory")
trace("")
knife_loot.x = 80
knife_loot.y = 120
}
}
// end of dragging and dropping items
You can start with:
// List the items you want to drag.
var aList:Array = [knife_loot, spoon_loot, fork_loot];
// InteractiveObject is superclass for SimpleButton, Sprite and MovieClip.
// If you're sure what they all are then just use their class instead.
for each (var anItem:InteractiveObject in aList)
{
// Subscribe them all for dragging.
anItem.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
}
public var draggedItem:InteractiveObject;
function onDrag(e:MouseEvent):void
{
// Use e.currentTarget because original MouseEvent e.target
// could be something from deep inside of top object e.currentTarget.
draggedItem = e.currentTarget as InteractiveObject;
draggedItem.startDrag();
// Let's hook drop events.
stage.addEventListener(Event.MOUSE_LEAVE, onDrop);
stage.addEventListener(MouseEvent.MOUSE_UP, onDrop);
}
function onDrop(e:Event):void
{
// Unhook drop events.
stage.removeEventListener(Event.MOUSE_LEAVE, onDrop);
stage.removeEventListener(MouseEvent.MOUSE_UP, onDrop);
// Drop the item.
draggedItem.stopDrag();
if ((draggedItem.hitTestObject(inv_game)) && (inv_game.visible == true))
{
trace("Item", draggedItem.name, "was dropped to inventory.");
trace("");
draggedItem.x = 80;
draggedItem.y = 120;
}
// Forget the item.
draggedItem = null;
}
I am trying to make a simple project when you click a button a draggable MovieClip is added to the stag and when you click it releases the MovieClip to the X/Y where you clicked, you can then pickup the MovieClip and drag it into a bin (MovieClip) where it destroys itself. The code is working great I can make multiple Movieclips with the button and they are all destroyed when I drag them in the bin however I don't like having "Error Codes".
import flash.events.MouseEvent;
var rubbish:my_mc = new my_mc();
btntest.addEventListener(MouseEvent.CLICK, makeRubbish);
function makeRubbish (event:MouseEvent):void {
addChild(rubbish);
rubbish.x = mouseX - 10;
rubbish.y = mouseY - 10;
rubbish.width = 50;
this.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
rubbish.buttonMode = true;
}
function stopDragging (event:MouseEvent):void {
rubbish.stopDrag()
event.target.addEventListener(MouseEvent.CLICK, startDragging);
rubbish.buttonMode = true;
if (event.target.hitTestObject(bin))
{
trace("hit");
event.target.name = "rubbish";
removeChild(getChildByName("rubbish"));
}
}
function startDragging (event:MouseEvent):void {
event.target.startDrag();
this.addEventListener(MouseEvent.CLICK, stopDragging);
}
Some Pointers:
The target property of an Event is not always what it seems. It actually refers to the current phase in the event bubbling process. Try using the currentTarget property.
I would also recommend tying the stopDragging method to the stage, as sometimes your mouse won't be over the drag as you're clicking.
I would use the MOUSE_UP event as opposed to a CLICK for standard dragging behaviour.
When dragging, keep a global reference to the drag in order to call the stopDrag method on the correct object.
Try This:
import flash.events.MouseEvent;
var rubbish:my_mc = new my_mc();
var dragging:my_mc;
btntest.addEventListener(MouseEvent.CLICK, makeRubbish);
function makeRubbish (event:MouseEvent):void {
addChild(rubbish);
rubbish.x = mouseX - 10;
rubbish.y = mouseY - 10;
rubbish.width = 50;
rubbish.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
rubbish.buttonMode = true;
}
function stopDragging (event:MouseEvent):void {
this.stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragging);
if(dragging !== null){
dragging.stopDrag();
if (event.currentTarget.hitTestObject(bin)){
removeChild(dragging);
}
dragging = null;
}
}
function startDragging (event:MouseEvent):void {
dragging = event.currentTarget as my_mc;
dragging.startDrag();
this.stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
Is there any way to detect if the user click outside a MovieClip?
For instance, I need to detect it to close a previously opened menu (like Menu bar style: File, Edition, Tools, Help, etc).
How can I detect this kind of event? Thanks!
Add a listener to stage and check if stage is the target of the event.
Example of code here:
http://wonderfl.net/c/eFao
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
public class FlashTest extends Sprite
{
private var _menu : Sprite;
public function FlashTest()
{
_menu = new Sprite();
_menu.x = 100;
_menu.y = 100;
_menu.alpha = 0.5;
with(_menu.graphics)
{
beginFill(0xFF0000, 1);
drawRect(0, 0, 300, 300);
endFill();
}
addChild(_menu);
_menu.addEventListener(MouseEvent.CLICK, onClickHandler);
stage.addEventListener(MouseEvent.CLICK, onClickHandler);
}
private function onClickHandler(event : MouseEvent) : void
{
switch(event.target)
{
case _menu:
_menu.alpha = 0.5;
break;
case stage:
_menu.alpha = 1;
break;
}
}
}
}
You can add a listener to the click event of the root element:
MovieClip(root).addEventListener(MouseEvent.CLICK, clickObject);
then in the function clickObject, you can check to see what you are clicking.
function clickObject(e:Event):void
{
var hoverArray:Array = MovieClip(root).getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
var hoverOverObject:* = hoverArray[hoverArray.length - 1];
}
hoverOverObject references the element that you are clicking on. Often this will be the shape within the movie clip, so you'll need to look at it's parent then compare it to your movie clip. If the click wasn't on the drop down movie clip, trigger the close.
var container:MovieClip = new MovieClip();
var mc:MovieClip = new MovieClip();
with(mc.graphics){
beginFill(0xff0000,1);
drawCircle(0,0,30);
endFill();
}
mc.name = "my_mc";
container.addChild(mc);
addChild(container);
stage.addEventListener(MouseEvent.CLICK, action);
function action (e:MouseEvent):void
{
if(e.target.name != "my_mc"){
if(container.numChildren != 0)
{
container.removeChild(container.getChildByName("my_mc"));
}
}
}
Use capture phase:
button.addEventListener(MouseEvent.CLICK, button_mouseClickHandler);
button.stage.addEventListener(MouseEvent.CLICK, stage_mouseClickHandler, true);
//...
private function button_mouseClickHandler(event:MouseEvent):void
{
trace("Button CLICK");
}
private function stage_mouseClickHandler(event:MouseEvent):void
{
if (event.target == button)
return;
trace("Button CLICK_OUTSIDE");
}
Note that using stopPropagation() is good for one object, but failed for several. This approach works good for me.
Use a stage and a sprite (menu) click listener with the sprite listener executing first and apply the stopPropagation() method to the click handler of the sprite. Like this:
menu.addEventListener(MouseEvent.CLICK, handleMenuClick);
stage.addEventListener(MouseEvent.CLICK, handleStageClick);
private function handleMenuClick(e:MouseEvent):void{
// stop the event from propagating up to the stage
// so handleStageClick is never executed.
e.stopPropagation();
// note that stopPropagation() still allows the event
// to propagate to all children so if there are children
// within the menu overlay that need to respond to click
// events that still works.
}
private function handleStageClick(e:MouseEvent):void{
// put hide or destroy code here
}
The idea is that a mouse click anywhere creates a single MouseEvent.CLICK event that bubbles from the stage, down through all children to the target, then back up through the parents of the target to the stage. Here we interrupt this cycle when the target is the menu overlay by not allowing the event to propagate back up to the parent stage, ensuring that the handleStageClick() method is never invoked. The nice thing about this approach is that it is completely general. The stage can have many children underneath the overlay and the overlay can have its own children that can respond to clicks and it all works.
I have buttons that have mouse_over, mouse_out and CLICK events. But when I click the button it takes me to another frame and the mouse_out event tried to fire. How do I stop that happening?
act1_btn.addEventListener(MouseEvent.CLICK, act1Pressed);
act1_btn.addEventListener(MouseEvent.MOUSE_OVER, act1Over);
act1_btn.addEventListener(MouseEvent.MOUSE_OUT, act1Out);
act1_btn.addEventListener(Event.ENTER_FRAME, act1EnterFrame);
function act1Over(e:MouseEvent):void
{
trace("over");
act1Animating = true;
logo_1.visible = true;
bubble.visible = true;
txt1.visible = true;
}
function act1Out(e:MouseEvent):void
{
act1Animating = false;
logo_1.visible = false;
bubble.visible = false;
txt1.visible = false;
}
function act1EnterFrame(e:Event):void
{
if (act1Animating && e.target.scaleY < 1.1)
{
e.target.scaleY += 0.02;
e.target.scaleX += 0.02;
}
if (!act1Animating && e.target.scaleY > 1)
{
e.target.scaleY -= 0.02;
e.target.scaleX -= 0.02;
}
}
function act1Pressed(e:MouseEvent):void
{
trace("clicked");
act1Animating = false;
logo_1.visible = false;
bubble.visible = false;
txt1.visible = false;
gotoAndStop(2);
}
Here are two ways to handle this:
1) Only assign the MOUSE_OUT listener in the MOUSE_OVER handler, then remove it after the MOUSE_OUT handler is done. I.e.,
function act1Over(e:MouseEvent):void {
/* your code */
act1_btn.addEventListener(MouseEvent.MOUSE_OUT, act1Out);
}
function act1Out(e:MouseEvent):void {
/* your code */
act1_btn.removeEventListener(MouseEvent.MOUSE_OUT, act1Out);
}
2) Use stopPropagation() in your CLICK handler:
function act1Pressed(e:MouseEvent):void {
/* your code */
e.stopPropagation();
}
Also, in the future, please use code tags to mark up your code!
It might not be a bad idea to give ROLL_OVER and ROLL_OUT MouseEvent a shot instead. These just fire once when someone rolls over the object, or rolls out, instead of firing continuously.
When you click a button , you will trigger a MouseOver & a MouseOut event , if you don't wish to trigger the MouseOut event after the Click event , then you should remove the MouseOut event listener in the Click event listener.
This means that in order to be sure that you have a MouseOut listener when you MouseOver , you should add your MouseOut listener in the MouseOver listener.
Finally, you should remove the MouseOut event listener within the MouseOut listener.