A Flash Developer Resource Site

Results 1 to 13 of 13

Thread: Keyboard Event with multiple functions

  1. #1
    Member
    Join Date
    Jul 2009
    Posts
    69

    Keyboard Event with multiple functions

    Most flash games and interactive animations that use keyboard events are made to respond in different ways to different keys.

    I am working on games for toddlers, who basically just bang on the keyboard indiscriminately. The trouble I'm having is setting up keyboard event listeners (key_up) that each perform different function.

    We're talking games like: when key pressed, ducky dances; when key pressed, doggy dances; when key is pressed, ducky and doggy go to sleep. I've attempted removing the listener before adding the next one:

    stage.addEventListener(KeyboardEvent.KEY_UP, doSomething);

    function doSomething(evt:KeyboardEvent):void
    {make it do something;
    stage.removeEventListener(KeyboardEvent.KEY_UP, doSomething);}

    stage.addEventListener(KeyboardEvent.KEY_UP, doSomethingElse);

    function doSomethingElse(evt:KeyboardEvent):void
    {make it do something else;
    stage.removeEventListener(KeyboardEvent.KEY_UP, doSomethingElse);}


    Figured by removing it, I'd be able to reassign it to something else further down the line. Clearly, this is not how things work and I'm wrecking my brain trying to sort out how it works then. What's the logic of it?

    Some thoughts are:

    1 - maybe if i set the priority of the functions, things will run as desired? Though so far, no luck.

    2 - maybe if I don't set the listener to the stage, but to the mc that will be affected, it would work ... but I thought all keyboard events MUST be set to listen to the stage. If not, then is the process of setting them to a mc the same? And if a mc is part of multiple functions, wouldn't that change that mc throughout?

    How exactly would using keyboard events in this manner work?
    Last edited by Leftyplayer; 09-15-2009 at 10:31 AM.

  2. #2
    Senior Member dudeqwerty's Avatar
    Join Date
    Mar 2005
    Location
    Bosnia
    Posts
    1,626
    I'm not sure I understand.

    do you want:
    • Have each key trigger a different function when pressed
    • Have all keys perform trigger a certain function (which changes after each keypress) when pressed.
    • Have each key trigger a random function when pressed


    ?
    New sig soon

  3. #3
    Flactionscrish Baby Minion's Avatar
    Join Date
    Nov 2005
    Location
    Planet Earth
    Posts
    312
    I don't think you need to remove any listener for the keyboard. What sounds right, is to have that one keyboard listener on the stage, and when a KEY_UP is registered, call an appropriate function that handles which key was pressed and what action to perform.

    PHP Code:
    stage.addEventListener (KeyboardEvent.KEY_UPonKeyUp);
    function 
    onKeyUp (e:KeyboardEvent):void {
       
    handleKeyInput (e.charCode);
    }
    function 
    handleKeyInput (charCode:uint):void {
       var 
    key:String String.fromCharCode(charCode);
       switch (
    key) {
          case 
    "l":
             
    //make dog dance;
          
    break;
          case 
    "g":
             
    //make duck dance;
          
    break;
       }

    This help?
    ktu[k-two]
    he who hesitates is lost; so i guess i'll wander intently

    Are you sure this is real?
    Life is Love, Love is Blind, Blind we go through Life.
    Life isn't hard, dealing with your self is.

    The concept of life in a human brain is weakening day after day. Live every day like its your last. Take the chances, and opportunities, and never let authority push you around for fun.


  4. #4
    Member
    Join Date
    Jul 2009
    Posts
    69
    Have all keys perform trigger a certain function (which changes after each keypress) when pressed.
    This! When keypressed, do x. Next time keypressed, do y. etc. (I thought this would work by removing the keyboardlistener once each function is performed, but nope. Instead, now when key is pressed, it performs all functions connected to keyboard listeners at the same time, resulting in chaos.

    It's a (very simple) game for tiny kids (tots) ... they don't know to press "shift" or "left" or "right", so I have to make possible for them to bang on anything on the keyboard and get a result.

    But I can't find ANYTHING out there that refers to this concept.

  5. #5
    Member
    Join Date
    Jul 2009
    Posts
    69
    BabyMinion: typed above before seeing your reply. The problem with your suggestion (which is much appreciated, btw) is that it would require selection of specific key (i.e, "l" "g" etc) in order to have function perform, which is a skill my audience (babies and tots) just doesn't have yet. With your suggestion, by sheer chance, they may hit upon something happening but 1) it's just by change and 2) they would get functions in different orders than intended if they pressed "g" before "l" for example.

    I'm trying to avoid going frame by frame on this one, and just know one of you AS coding wizards out there has some ideas for me.

  6. #6
    Senior Member dudeqwerty's Avatar
    Join Date
    Mar 2005
    Location
    Bosnia
    Posts
    1,626
    Ok you are over complexifying it.

    You only need to set one key event listener. Best way would be to have an array with all your functions and just loop through them on each key press.

    I'll post some code in a second.
    New sig soon

  7. #7
    Senior Member dudeqwerty's Avatar
    Join Date
    Mar 2005
    Location
    Bosnia
    Posts
    1,626
    Here:
    Code:
    var myFunctions:Array = [firstFunc, secondFunc, thirdFunc];
    var fPointer:int = 0;
    
    stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
    function keyPressed(e:KeyboardEvent):void {
    	myFunctions[fPointer++]();  // call the next function;
    	if(fPointer == myFunctions.length) {
    		fPointer = 0; // loop back to the beinging;
    	}
    }
    
    function firstFunc():void {
    	trace("firstFunc() called!");
    }
    
    function secondFunc():void {
    	trace("secondFunc() called!");
    }
    
    function thirdFunc():void {
    	trace("thirdFunc() called!");
    }
    New sig soon

  8. #8
    Senior Member dudeqwerty's Avatar
    Join Date
    Mar 2005
    Location
    Bosnia
    Posts
    1,626
    Just remembered the "bang on the keyboard indiscriminately."

    The code above might not work how you want it to, as if two keys are pressed at the same time, two key events will be triggered.

    I'll revise the code so that the function being triggered only changes after each "mash" of the keyboard, and not after each keypress.
    New sig soon

  9. #9
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You're mostly on the right track. But you have to keep in mind when code is executed. In the code above, the two lines with stage.addEventListener are executed one immediately after the other. That will result in two simultaneous listeners when key_up is detected. So both your functions will execute once, then remove themselves as listeners.

    What you probably want to do is add the second listener within the function for the first one.

  10. #10
    Senior Member dudeqwerty's Avatar
    Join Date
    Mar 2005
    Location
    Bosnia
    Posts
    1,626
    Here we go!

    Each function will be triggered after each keyboard mash, rather than key press:

    Code:
    var myFunctions:Array = [firstFunc, secondFunc, thirdFunc];
    var fPointer:int = 0;
    var keysPressed:Array = new Array();
    
    stage.addEventListener(KeyboardEvent.KEY_DOWN, collectKey);
    stage.addEventListener(KeyboardEvent.KEY_UP, listenForMash);
    
    function collectKey(e:KeyboardEvent):void {
    	if(keysPressed.indexOf(e.keyCode) == -1) {
    		keysPressed.push(e.keyCode);
    	}
    }
    
    function listenForMash(e:KeyboardEvent):void {
    	var io:int;
    	if((io = keysPressed.indexOf(e.keyCode)) != -1) {
    		keysPressed.splice(io, 1);
    	}
    	if(keysPressed.length == 0) {
    		myFunctions[fPointer++]();  // call the next function;
    		if(fPointer == myFunctions.length) {
    			fPointer = 0; // loop back to the beinging;
    		}
    	}
    }
    
    function firstFunc():void {
    	trace("firstFunc() called!");
    }
    
    function secondFunc():void {
    	trace("secondFunc() called!");
    }
    
    function thirdFunc():void {
    	trace("thirdFunc() called!");
    }
    Hope that's what you want!
    New sig soon

  11. #11
    Member
    Join Date
    Jul 2009
    Posts
    69
    Folks, thank you so much for helping.

    dudeqwerty .... I love you, man. Seriously, I LOVE you. You have no idea how many hours (days!) I've spent trying to figure out how to go about this. Of course, now I have to go bang myself over the head with a pan for not having thought about an array for functions. I seem to be highly skilled at over-complicating things in my head to the point where I can't solve simple problems ... you have yanked me right out of my brain-lock loop LOL. Much, much appreciated.

    Your first solution worked beautifully (though you are correct that if multiple keys are pressed, it performs multiple functions at once). The keymash one works, but I'll have to tinker with it as it's still behaving somewhat erratically. I'm grateful to have the gist of the setup. The rest is a bit of tinkering. THANK YOU.
    Last edited by Leftyplayer; 09-15-2009 at 12:14 PM.

  12. #12
    Senior Member dudeqwerty's Avatar
    Join Date
    Mar 2005
    Location
    Bosnia
    Posts
    1,626
    The key mash code works by pushing the key codes of keys pressed into an array, and removing them from the array when the keys are release. When the array is empty on a key_up, then the function gets triggered.

    The problem with this is that in the middle of a keyboard mash, you might have no keys pressed, which means the function will trigger mid-mash.

    The only way I can see of bettering the code (maybe) without making it too complex would be to make it time based.

    So when a key is pressed, the listener wont trigger the function again on a key press untill x seconds has passed.
    New sig soon

  13. #13
    Member
    Join Date
    Jul 2009
    Posts
    69
    The only way I can see of bettering the code (maybe) without making it too complex would be to make it time based.

    So when a key is pressed, the listener wont trigger the function again on a key press untill x seconds has passed.
    Yes, I'm currently playing with this idea as it does seem the easier solution.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center