I have a textbox for which I want the space key to be executed every time a person hits the enter key INSTEAD OF adding an extra line. I am using the following code but to no avail:
txtVerbs.addEventListener(KeyboardEvent.KEY_DOWN, enterkey);
function enterkey(event:KeyboardEvent):void{
if (event.keyCode == 13){event.keyCode == 32}}
Try this:
txtVerbs.addEventListener(KeyboardEvent.KEY_DOWN, enterkey);
function enterkey(event:KeyboardEvent):void{
if (event.keyCode == Keyboard.ENTER){ // you should use the Keyboard constants instead of the hard value
event.preventDefault();
event.stopImmediatePropagation();
txtVerbs.text += ' ';
}
}
stopImmediatePropagation() prevents the event from traveling any further, so it will stop any other KEY_DOWN event further down the line and should (at least from what I remember) stop the KEY_UP from firing as well.
preventDefault() cancels the default behavior of an event, if it is possible to be cancelable. If memory serves, the key being pressed is cancelable. If it isn't, however, you could also do a RegEx replace.
txtVerbs.addEventListener(KeyboardEvent.KEY_UP, enterkey);
function enterkey(event:KeyboardEvent):void{
if (event.keyCode == Keyboard.ENTER){ // you should use the Keyboard constants instead of the hard value
txtVerbs.text = txtVerbs.text.replace(/\r?\n/gm, ' ');
}
}
That should match any newline character (it is \r\n on some systems and just \n on others) and replace it with a space
Related
I'm new in AS3 language. I'd like to ask does KeyboardEvent in as3 used to executed as long as key is pressed?
It gives me problem when performing a double jump for my character.
Here's some of my code:
var dbJump:Boolean=true;
var onGround:Boolean=false;
var Yvel:Number=0;
var keyUp:Boolean=false;
this.addEventListener(Event.ENTER_FRAME,Eframe);
stage.addEventListener(KeyboardEvent.KEY_DOWN,
kDown)
stage.addEventListener(KeyboardEvent.KEY_UP,
kUp)
function kDown(e:KeyboardEvent):void{
var key:uint=e.keyCode;
if(key==32){
keyUp=true;
}
}
function kUp(e:KeyboardEvent):void{
var key:uint=e.keyCode;
if(key==32){
keyUp=false;
}
}
function Eframe(e:Event):void{
Yvel++;
myChar.y+=Yvel;
while(ground.hitTestPoint(myChar.x,myChar.y,true)){
myChar.y--;
Yvel=0;
}
if(ground.hitTestPoint(myChar.x,myChar.y+3,true)){
onGround=true;
//if touching ground then return the dbJump to true;
dbJump=true;
else{
onGround=false;
if(!keyUp){
//if not on ground an not pressed space, dbJump
// still true
dbJump=true;
}
}
if(keyUp && dbJump && onGround){
Yvel=-12;
}
// if space pressed and not on the ground
else if(keyUp && dbJump && !onGround){
Yvel=-12;
//then say doublejump is completed
dbJump=false;
trace(dbJump);
}
}
so the dbJump variable immediately becomes false in the first space key press, not the second time space pressed. I put the trace so i can see how much is key down event repeated.
So the point is the dbJump immediately became false as soon as my character off the ground. i didn't release the key yet. I tried to press and release the space keyboard quickly,and it works(so i'm really sure it is because the repeated statement of 'dbJump=false' .
How to fix that?
Also, i mean if the dbJump property is false it means cant jump again/doublejump have been completed.
If there's too many functions, so It is very hard to "removeEventListener" each one,
Is there any way to disable all keys temporarily?
Thank you.
"Is there any way to disable all keys temporarily?"
Can you not just use .removeEventListener(KeyboardEvent.KEY_DOWN...?
Either your Stage or some MovieClip is listening for key press event, right? eg:
stage.addEventListener(KeyboardEvent.KEY_DOWN, handle_KeyPress);
Where your handle_KeyPress function, which handles all key presses, looks like:
function handle_KeyPress ( evt:KeyboardEvent ) : void
{
//# RIGHT ARROW or numpad 6 (arrow)
if ( evt.keyCode == 39 || evt.keyCode == 54 || evt.keyCode == 102)
{
//do something if Right arrow
}
//# SPACE BAR
if ( evt.keyCode == 32)
{
//do something if Space bar
}
}
PS:
Show an example of code with "too many functions" (eg: give small example how they're spread out it). It's possible you need to re-think / re-structure your code if it's not currently flexible.
If your goal is just to temporarily "pause" the event handlers, you could throw in a simple boolean:
var eventsHandled:Boolean = true;
And inside the event handler functions you would use it as a condition:
function buttonClicked(evt:KeyboardEvent):void{
if(eventsHandled){
//do stuff
This is just a simple bandage. VC.One's answer is probably hinting into your actual problem and in some point you'll have to face it.
I have a "pause function" in my AS3 code, the problem is that i can't figure the logic necessary to give the letter "P" the capacity to pause and unpause and at the same time limit the number of presses to one at a time. My code so far (working ,yes, but without the "one press at a time" limit).
public function PauseDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.P)
{
pause = true;
trace ("apreté pausa");
pausa();
}
}
public function pausa():void
{
trace ("pausa");
if (pause == true && paused == false)
{
paused = true;
backgroundLvL1.removeEventListener(Event.ENTER_FRAME,update);
}
else if(pause == true && paused == true)
{
paused = false;
backgroundLvL1.addEventListener(Event.ENTER_FRAME,update);
}
}
Your 'PauseDown' function should probably be called something else, because it's going to be called whenever ANY key is pressed; Something like 'keyPressed' is probably more descriptive.
If you want to have only ONE key acknowledged as the most recently pressed key, I would set a variable (eg _currentKeyCode) to the event.keyCode in the 'keyPressed' function. Then, in your game loop function you can check the value of _currentKeyCode and have the game respond accordingly.
In the 'keyPressed' function you could also still include your test to see if 'P' has been pressed.
Note that you should also have a 'keyReleased' function, triggered on a KeyBoardEvent.KEY_UP event. This could check if _currentKeyCode == the event.keyCode and, if so, set _currentKeyCode to -1. Then, in your game loop, -1 would signify no key presses.
One last, slightly irrelevant, thing: In the 'pausa' function you don't need to check if 'pause == true' because the pausa function is only called when pause == true.
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.
I have an input TextField and have a KeyboardEvent.KEY_DOWN even listener on the stage to listen for the Keyboard.ENTER event. The event listener adds the entered text to an array or whatever, and then clears the TextField. The problem is that when the Enter key event fires and the TextField value is set to "", it leaves a carriage return in the TextField and the cursor positioned on the second line. WTF? I've been coding AS2 and AS3 for a LONG time and have never ran into this before. Am I losing my mind? Please help, people! :-)
Example:
var myTextArray:Array = new Array();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
function onKeyDown(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.ENTER){
if(_inputText.text != null){
myTextArray.push(_inputText.text);
}
_inputText.text = "";
}
}
Simply replace KEY_DOWN with KEY_UP. It fixes the problem (for me at least)
Use KEY_DOWN -> Your code -> KEY_UP -> empty Field
An example (nasty code):
Message.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.ENTER)
{
// Your code...
}
});
Message.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.ENTER)
{
Message.text = "";
}
});
If you are able to enter a carriage return, it means the TextField is multiline, isn't?
Have you tried to empty your input text in a KeyboardEvent.KEY_UP event listener callback function?
Are you hitting enter with text field in focus? In that case, it might be that onKeyDown is called before the text field's value is updated by the keyboard action. You set the textfield to empty string in the onKeyDown, and then flash adds a new line to it.
Add a text input event listener to the text field and add trace statements to both event handlers to know the order of events.
If you are in Flash authoring mode (in the IDE), you need to uncheck Control -> Disable Keyboard Shortcuts while testing. Also try making a "cleanup" handler for KEY_UP.
inputfield.addEventListener(Event.CHANGE, onChange);
private function onChange(e:Event):void {
if ( inputfield.text.charCodeAt(inputfield.text.length - 1) == 13 ) {
inputfield.text = inputfield.text.substr(0, inputfield.text.length - 1);
}
}
I know it is a very old question, still thought of sharing my solution. I disabled multiline feature of textbox in fla file. After that I don't get any carriage return in textbox.
This does seem to be some kind of bug - I get it too. If you just set textField.text = "" in your constructor (or where-ever) it seems to resolve the problem.