Flash AS3 making it so whenever a button is clicked on screen is like pressing a specific keyboard key - actionscript-3

Hello I am working on a game in flash, in the mobile version of this app I am trying to make it so in a mousedown event on a button it will be equal to the Left, Right keycodes etc. being active?
Is there a way in AS3 for a keyboard key to be activated by other means such as mouse clicks?
leftButton.addEventListener(MouseEvent.MOUSE_DOWN, leftKeyPress)
function leftKeyPress(e:MouseEvent){
// Left Key is pressed
Keyboard.LEFT;
trace("trace statement");
}
This code doesent seem to work
EDIT: also this is important this class and the class that uses the keyboard(The player) are in two seperate classes, so Im trying to make it so that when this is click it is recognized as a key press on a keyboard

Sorry but It is all wrong. You can't trigger keyboard events like that. That is the way of capturing events. And your function is also a MouseEvent. Should be keyboard event. I Opened Flash after one year. Anyway. AFAI understand you are trying to disable keyboard until mouse click somewhere.
leftButton.addEventListener(MouseEvent.MOUSE_DOWN, leftKeyPress);
var keyEnabled:Boolean = false;
function leftKeyPress(e:MouseEvent){
keyEnabled = true;
}
key.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function keyPressed(e:KeyboardEvent):void{
if(keyPressed){
//do whatever here
}
}

You can manually dispatch a keyboard event; however, is not the best design pattern:
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN,
true,
false,
Keyboard.LEFT,
Keyboard.LEFT));
It would be better to establish two handlers:
addEventListener(KeyboardEvent.KEY_DOWN, moveKeyHandler);
addEventListener(MouseEvent.CLICK, moveMouseHandler);
From each handler, call a function that abstracts movement function from the handlers:
protected function moveKeyHandler(event:KeyboardEvent):void
{
/* switch statement for key */
moveLeft();
}
protected function moveMouseHandler(event:MouseEvent):void
{
/* switch statement for button target */
moveLeft();
}
protected function moveLeft():void
{
}

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;
}
}

How can i capture Keyboard and Mouse events at same time AS3

When i watch some video's about starling i saw a triggered event. That event capture both keyboard and touch events.
I wonder is there any way to capture Mouse and Keyboard Events at the same time ?
You can check this video for an example:
https://vimeo.com/109564325
In my experience, usually, it might be done with implementing some common used InputManager, which can save information about pressed keys/mouse buttons and other classes might get this information through methods, something like:
checkIfKeyPressed(keyCode:int):boolean
{
}
Also, if you need to know about only some specific keys (e.g. alt, ctrl, cmd, shift, etc.), there are some public properties in the MouseEvent objects, which can help you (e.g. altKey, ctrlKey, shiftKey, etc.). See: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/MouseEvent.html
Can't you add listeners for both keyboard and mouse events, and call a shared 'handler' from there on?
...
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(MouseEvent.CLICK, clickHandler);
private function clickHandler(e:MouseEvent):void {
inputHandler(e, 'mouse');
}
private function keyDownHandler(e:KeyboardEvent):void {
inputHandler(e, 'keyboard');
}
private function inputHandler(e:Event, type:String):void {
// Do logic here
}

FULL_SCREEN_INTERACTIVE mode: the "Allow" button click is passed to the application

In an AS3 game (using Flex 4.10.0) I would like to allow players to chat, even when they are in fullscreen mode.
So I am using the following ActionScript code (the _fullBox checkbox triggers fullscreen mode in my web application):
public function init():void {
if (stage.allowsFullScreenInteractive)
stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen, false, 0, true);
}
private function toggleFullScreen(event:MouseEvent):void {
stage.displayState =
stage.displayState == StageDisplayState.NORMAL ?
StageDisplayState.FULL_SCREEN_INTERACTIVE :
StageDisplayState.NORMAL;
}
private function handleFullScreen(event:FullScreenEvent):void {
_fullBox.selected = event.fullScreen;
}
<s:CheckBox id="_fullBox" click="toggleFullScreen(event)" label="Full Screen" />
This works in the sense that the fullscreen mode is entered successfully and users can use the keyboard to chat too.
Unfortunately, the click at the "Allow" button in the dialog (displaying "Allow full screen with keyboard controls?") is being passed down to the web application.
And in my case it resuls in the click at a playing table in the lobby as you can see in the screenshot and thus (unwanted) joining a game:
This (bug?) has been seen with Windows 7 / 64 bit and Flash Player 11,8,800,115.
Can anybody please share a good workaround for this?
I was thinking of adding a transparent Sprite or UIComponent above my web application, but the question is when (i.e. in which methods) to display/hide it?
UPDATE:
Calling event.stopPropagation() from handleFullScreen() doesn't help anything.
UPDATE 2:
I've submitted Bug #3623333 at Adobe.
UPDATE 3: A note to myself - stage.allowsFullScreenInteractive is useless, because only set when allready in fullscreen mode.
As you mentioned, you need to create transparent layer to avoid undesired click events. you can hide this layer when screen returned to normal state or user accepted fullscreen state (FULL_SCREEN_INTERACTIVE_ACCEPTED event will fired).
Demo (flashplayer 11.3 required)
var transparentLayer:Sprite=new Sprite();
var timer:Timer = new Timer(50, 1);
init();
function init():void {
transparentLayer.graphics.beginFill(0,0.1);
transparentLayer.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
transparentLayer.graphics.endFill();
transparentLayer.visible=false;
addChild(transparentLayer);
timer.addEventListener(TimerEvent.TIMER_COMPLETE,handleTimerComplete);
stage.addEventListener(FullScreenEvent.FULL_SCREEN_INTERACTIVE_ACCEPTED,handleFSIA);
_fullBox.addEventListener(MouseEvent.CLICK,toggleFullScreen);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, handleFullScreen);
}
function toggleFullScreen(e:MouseEvent):void {
if(stage.displayState == StageDisplayState.NORMAL){
stage.displayState=StageDisplayState.FULL_SCREEN_INTERACTIVE;
transparentLayer.visible=ExternalInterface.available;
}else
stage.displayState=StageDisplayState.NORMAL;
}
function handleFullScreen(e:FullScreenEvent):void {
_fullBox.selected = e.fullScreen;
if(stage.displayState == StageDisplayState.NORMAL)
transparentLayer.visible=false;
}
function handleFSIA(e:FullScreenEvent):void{
timer.reset();
timer.start();
}
function handleTimerComplete(e:TimerEvent):void{
transparentLayer.visible=false;
}
Found one workaround.
Allow and Cancel buttons are not the parts of the application, so when you hover one of those buttons you receive rollOut event for application.
<s:Application
rollOut="application_rollOutHandler(event)"
rollOver="application_rollOverHandler(event)">
Inside event handler you can disable mouse events for child objects. Don't disable for application as you won't get rollOver event after that.
private function application_rollOutHandler(event:MouseEvent):void
{
this.mouseChildren = false;
}
private function application_rollOverHandler(event:MouseEvent):void
{
this.mouseChildren = true;
}

Is it possible to remove an eventListener temporarily (i.e. until a function has been executed)

I am doing actionscript 3 at the moment and was wondering if it was possible to remove and eventListner temporarily. I know of removeEventListener, however, that removes the eventListener completely and i cannot click the button again.
If you want some more details, here the exact problem. I have function that when a button is pressed, an object appears. In the function which makes this object there is an eventListener which leads to a function which allows the user to press that object. When you press that object it disappear and the button will animate. However, since the original eventListener still exists, you can press the object while in motion and create a new object. So to the point: What i want to do is disable the eventListener while the button is moving, and reactivate it when it stops.
The best way is to simply use a flag which tells the function if the animation is complete or not. Here's an example of what I'm talking about using TweenLite as tween library:
public class CreateButton extends Sprite{
private var animating:Boolean = false;
public function CreateButton(){
this.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
}
private function onClick(event:MouseEvent):void{
if(this.animating == false){
// Trigger creation functionality
TweenLite.to(this, 0.5, {/* Parameters for the actual animation */ onComplete:animationComplete});
this.animating = true;
}
}
private function animationComplete():void{
this.animating = false;
}
}
It is best practice to remove the listener if it's functionality is to be disabled. You could however set the .mouseEnabled to false if you want to disable it's click functionality without removing the listener.