transform double click on Z to double click on mouse - actionscript-3

When I click 2 times on the touch "z" (keycode 90) on my keyboard, my item is removed.
timer=new Timer(500, 1);
stageRef.addEventListener(KeyboardEvent.KEY_UP, removeDraggedItem);
private function removeDraggedItem(e:KeyboardEvent){
if(timer.running==true)
{
if(e.keyCode==90)
{
stageRef.removeEventListener(MouseEvent.MOUSE_MOVE, dragItem);
stageRef.removeEventListener(Event.ENTER_FRAME, itemHitTest);
draggedItem.removeEventListener(MouseEvent.MOUSE_DOWN, itemClick);
stageRef.removeChild(draggedItem);
toolbar.useText.text = "";
if (stageRef.contains(this))
stageRef.removeChild(this);
Mouse.show();
Engine.playerControl = true;
}
}
else if(e.keyCode==90)
{
timer.start();
}
}
I'd like to change it and when we click 2 times with the mouse the item is removed but I can't figure out how to do it... if mouseDown = true ? it does'nt seem to work...
EDIT :
Ok I've tried to change (e.keyCode==90) by (e.buttonDown). No errors but nothings is happening when I double click...any idea why ?

Your code is only listening for a KEY_UP event: stageRef.addEventListener(KeyboardEvent.KEY_UP, removeDraggedItem);. You should add a KEY_DOWN event as well and then use the KEY_DOWN event in conjunction with the KEY_UP event to check for a double click. The code to add a KEY_DOWN event is stageRef.addEventListener(KeyboardEvent.KEY_DOWN, functionName);.
On another note if your trying to use MouseEvent.DOUBLE_CLICK you have to enable double click for the object you wish to double click. Oh and definitely include flash.events.MouseEvent
object.doubleClickEnabled = true;
object.addEventListener(MouseEvent.DOUBLE_CLICK, functionName);
Also I noticed in your removeDraggedItem function, you start a timer if the keycode equals 90. Then the next time a KEY_UP event is thrown you check if the timer is running and if so you remove a lot of event listeners and objects. You never stop the timer or reset the timer or remove the timer, I was just wondering if that was intentional?

Related

keycode for MouseEvent?

So to my understanding, there are keycodes to represent the keystrokes, for example:
public function left(e:KeyboardEvent):void
{
if (e.keycode == 65)
{
leftKey = true;
}
}
I want to do something similar with this logic and apply it for Mouse Events. I've searched on Google but haven't found much results for Flashdevelop AS3. Would there be a keycode to represent Mouse Events?
For example:
stage.addEventListener(MouseEvent.MOUSE_DOWN, down);
stage.addEventListener(MouseEvent.MOUSE_MOVE, move);
stage.addEventListener(MouseEvent.CLICK, click);
public function down(e:MouseEvent):void
{
if (e.keycode == ?)
}
public function move(e:MouseEvent):void
{
if (e.keycode == ?)
}
public function click(e:MouseEvent):void
{
if (e.keycode == ?)
}
Thanks in advance!
When you fire a mouse event that has a listener attached to it, then the function associated with that listener will get called. Period. You don't need to then, again, check to see if the mouse event happened. That's the whole beauty of event listeners. Just to make sure you get it, I'll post an example.
stage.addEventListener(MouseEvent.CLICK,mClick);
Great. We added a listener to the stage. Now, any time you click anywhere on the stage, this listener will cause that mClick function to get called. Now we write the mClick function.
private function mClick(me:MouseEvent):void{
trace("me.target.x",me.target.x);
trace("me.target.y",me.target.y);
}
me is just a variable we chose to represent the event that triggered this function. Event is a class. A MouseEvent is a subclass of Event. So we are saying that me is an Event of sublcass MouseEvent and that this is the expected input for this function. If you were to try to call this function elsewhere in your code it would throw an error saying that this function expected some sort of input.
me.target is the thing that caused the event to get triggered. In this case it is the mouse, so me.target.x will be the x position of the mouse at the time that the mouse was clicked.
That is all there is to it. You have just confused yourself a little bit by trying to apply a specific solution to a different problem, namely, how to register key presses on a keyboard. They are handled slightly fundamentally differently. With a keyboard, we check listen for if the keyboard had a key pressed and then in the event handler, we determine which key was pressed. With mouse events we would have a different listener for mouse move, mouse click, left mouse click and middle mouse click. Since each of those specific events has their own listener, we don't have to evaluate which button was pressed in the handler:
public function left(e:KeyboardEvent):void
{
if (e.keycode == 65)
{
leftKey = true;
}
}
The e is the thing that caused the event. In this case, the Keyboard key. Each key has a keycode. But instead of writing a different listener for every single key on the keyboard, we can just write one listener and one function and then evaluate which key was pressed inside the function. As stated before, with the mouse, the left mouse button gets its own event listener, so no need (or ability) to check that in the event listener. There are properties like ROLL_OVER and MOUSE_UP and MOUSE_DOWN. Look at the documentation for a full list.

Why doesn't stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, true) work?

I want to listen to stage for keyboard event, and I want to catch an event directly when it appears (not in bubbling or target). Why can't I do this?
Actually it seems that I can't use useCapture for keyboard events at all.
I want to open my inner console window by pressing tilda button, and change focus to input field. So, I wrote something like this
public function init(stage:Stage):void
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown);
}
private function onStageKeyDown(event:KeyboardEvent):void
{
event.stopImmediatePropagation();
switch(event.keyCode)
{
case Keyboard.BACKQUOTE:
visible = !visible;
stage.focus = visible ? inputField : stage;
break;
}
}
The problem is, it writes "`" character in my input, which I don't want it to do. So, I decided to try to listen to keyboard event in capture phase to stop its propagation. But it seems that stage can't have capture phase, because there is no nodes before it. How can I handle that situation properly?
To simply answer your question, you can listen for keyboard events on the capture phase.
Most likely, the reason you can't, is because nothing has focus. If nothing has focus in your application then the stage will not get a keyboard event. By default, when a swf runs nothing has focus.
Give an item focus when your application starts (anything besides the stage itself), and the event will come.
public function init(stage:Stage):void
{
stage.focus = this; //assuming this is the document class
stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown, true);
}
Now, to follow up with what you are actually trying to accomplish (aside from your actual question) all you need to do is listen for the right event (TEXT_INPUT). Your answer is close, but it can be much simpler without the need for flags or a key down listener:
stage.focus = this; //give something focus, probably not needed if you have to click the text input in order to input text
//listen on the capture phase for text input
stage.addEventListener(TextEvent.TEXT_INPUT, onStageTextInput, true);
function onStageTextInput(event:TextEvent):void
{
switch(event.text)
{
//if the new text was a backquote or # sign, don't let the event trigger it's normal action
case "`":
case "#":
event.preventDefault(); //prevent default is needed
break;
}
}
I finally found a workaround for this problem.
First of all: handling and stopping KeyboardEvent.KEY_DOWN is NOT preventing TextField from getting input. That's sad because in this case it would be useful, but it seems there is some other reasons for not doing this.
So, what I should do is listen for TextEvent.TEXT_INPUT by inputField
inputField.addEventListener(TextEvent.TEXT_INPUT, onTextInput);
and listen to KeyboardEvent.KEY_DOWN by stage
stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown);
in case I may still want to put tilda of backquote signs in my TextField (for example by coping and pasting them) I decided to use a flag
private function onStageKeyDown(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case Keyboard.BACKQUOTE:
...
inAction = true;
break;
}
}
so when TextEvent.TEXT_INPUTevent fires I can see if that was opening window action or not. And if it is, then preventDefault() behaviour, which means NOT inputting received sign in TextField
private function onTextInput(event:TextEvent):void
{
if(inAction)
{
event.preventDefault();
inAction = false;
}
}

Disabling button rollover for certain number of frames Flash actionscript 3.0

I'm constructing an area with selectable buttons that transition and appear every 10 frames. During these 10 frame transition periods I don't want the buttons to be selectable and if possible to disable the rollover.
I've tried creating an If statement on the addEventListener so that it only works when currentFrame is 11,21,31 etc but this didn't work. I then also tried the same principal on the function to which the Event Listener relates but still no success.
Does anyone have any ideas?
Add a listener for the ENTER_FRAME event, and put the if in the callback function.
For example
this.addEventListener (Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame (evt:Event):void {
if (currentFrame == 21) {
yourButton.enabled = false;
} else {
yourButton.enabled = true;
}
}
You could do 2 things:
1:
You manually add and remove the listener.
So when you start the transition, the listener is removed,
then when the transition ends, the listener is added.
2:
You make a custom listener which checks for the state of the frame to see whether it should execute its body.
EXAMPLE:
public void listener(event:Event) {
if (event.getSource().stage.getCurrentFrame() == 10) {//This is an example, I don't know whether this specific way will work.
//Run your code here
}
}

Skipping to next game level in AS3

I am in the process of building a game with around 20 levels. Now, as I was thinking of trying to add a "skip" option to the game with the space bar key. I have a little trouble, since holding down the spacebar invokes the KeyboardEvent.KEY_DOWN event multiple times.
The above scenario (Keydown and keyup) works just fine when I'm trying to move my player character on screen.
The one main concern that is lingering in my mind is "Is this going wrong because the KeyboardEvent listeners do get removed and added when changing levels?"
P.S: Adding the skip option as a button works just fine, but I'd really like to use Spacebar for the ease of use.
Listen for KeyboardEvent.KEY_UP as well, and keep a boolean that acts as a switch. If the keyboard is pressed AND the boolean is false, set the boolean to true and proceed. Then, when the key_up event callback is invoked, reset the boolean to false.
Does somethig like this work for you?
private function levelInit () : {
// ...
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
// ...
}
private function keyDownListener (e : KeyboardEvent) : void {
if (e.keyCode == Keyboard.SPACE) {
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
// add stuff to initiate the level skip
}
}
You could also call the stage.addEventListener from a setTimeout to delay adding the listener to protect things more.
Remove the key_down listener in the function and add a key_up listener. Then in the key_up function remove that listener and add back the key_down listener.

Fake mouseclick on hover AS3

This morning I stumbled to this question:
When hovering a button, is it possible to click it automatically after X seconds? So the user doesn't need to click it with his mouse?
How can I let Flash believe my mouse really clicked some button on the stage or brought up with as3?
I have a lot of buttons in my movie. So I prefer to use some code which will cover this function for all existing or coming up buttons in my movie.
I would normally use a code like this but is there some workaround to accomplish this in a different way? I do no want to add code to every button.
this.addEventListener(MouseEvent.OVER, onMouseClickEvent);
public function onMouseClickEvent(event:Event)
{
trace(event);
if(event.buttonDown) // if button goes down normally
trace("MOUSE CLICKED NORMALLY");
else
trace("left button was not down");
}
The easiest way i think, is to subclass Button.
Then you should add mouse over/out listeners, add click listener that looks like that
:public function clickListener(event:MouseEvent = null){...}
When the mouse is hovering, raise a flag that the mouse is on the object, start a timer and when the timer callback function is called, you check the if the flag (you turn the flag down, when the mouse is out) is true and just call clickListener()
Listen for MouseEvent.MOUSE_OVER and start a timer, at the end of which the button will send the MouseEvent.CLICK event. In the mouseover handler, use the SystemManager to add a listener for MouseEvent.MOUSE_OUT which cancels the timer. The timer removes the listener using the SystemManager as well. So does clicking the button.
Finally! Solved!
This did the trick:
public function runOnce(event:TimerEvent):void {
btnSignal.dispatch("KEYBOARD", btnCode);
}
Robusto & Radoslav Georgiev: Thank you for pointing the right direction!
(I'm answering this a little late but would like to give input for future people).
One way to 'skin this cat' is to simply let your hover event trigger a timer (i.e. 3 seconds). In an EnterFrame or other function let a number or Boolean change when 3 seconds is reached.
//Pseudo code
if(timer == 3)
{ numberVar = 1;
//or
BooleanVar = True;
}
else
{
numberVar = 0;
//or
BooleanVar = false;
}
//end
Then just as you connected your methods to a mouseEvent, connect those same methods to fire when numberVar == 1 or BooleanVar == True. That's it.
For super simplicity and readability let your MouseClickEvent just be numberVar = 1 or BooleanVar = True.
These become super simple to implement over time and in my experience are 'very' error proof. Easy to fix also in the case of a typo or something else. No super elusive imports either. Hope that helped.
Great question by the way (+ 1)
:D