Posts tonen met het label as2 to as3. Alle posts tonen
Posts tonen met het label as2 to as3. Alle posts tonen

donderdag 6 januari 2011

Multiple keys don't work properly in Flash as3

If you press up, left simultaneously, there is no keyDown event when you press SPACE as well.

My output and what happened:
key down38    // I pressed up!
key down37   // I pressed left!
key up37       // I released left!
key up38      // I released up! (so far so good!)
key down32         // I pressed space
key up32             // I released space
key down37       // I press left
key down32      //  I press space
key up32         // I release space
key up37        // I release left, (still good!)
key down38      // I press up
key down32     // I press space
key up32         // I release space
key up38       // I release up (ok, that all works, NOW for the real test!)

key down38   // I press up
key down37 // I press left
                   // I press space: NOTHING HAPPENS, but my computer beeeps!
key up37   // I release left
key up38 // I release up
              // I release space, AGAIN NOTHING HAPPENS

Seems trivial, right, but this means, in my game, when you jump left and want to fire a snowball, you have to let go of only the left key to aim upwards, or let go of both before you press space (and don't aim upwards)
This sucks...

I'm going to make a GameKeys object as a Singleton to attempt to work around this.
When finished, you'll find it here..

I found a great place to start:
http://www.senocular.com/flash/actionscript/?file=ActionScript_3.0/com/senocular/utils/KeyObject.as

It's not a singleton so it will have the same focus problem, I described before. Also I don't like all the proxy stuff, it's unnecessary I feel. So re-writing time:

Here you are, I put it in the container package, I feel handling raw keys is a responsibility of the container, as is maintaining loaded pages and sounds.

package  nl.ludatic.container {

 import flash.display.Stage;
 import flash.events.KeyboardEvent;
 import flash.ui.Keyboard;

 /**
  * Usage:
  *
  * import nl.ludatic.container.GameKeys;
  * private var GameKey:GameKeys=GameKeys.getInstance(stage);  
  * if (GameKey.isDown(Keyboard.LEFT)) { ... }
  * 
  * GameKey.setKeyDownCallback(keyDownHandler);
  * private function keyDownHandler(key:uint):void {
  *   switch (key) {
  *    case Keyboard.LEFT :
  *    ....
  *   break;
  *   }
  * }
  * this keyDownHandler-function will be called with a keycode, the moment a key is pressed, but only once!
  *
  */
 
    public final class GameKeys
    {
  private static var stage:Stage;
  private static var _instance:GameKeys; // set up as a singleton!
  private static var keysDown = new Array();
  private static var cbKeyDown =null;
  
  public function GameKeys(pvt:PrivateClass)
  {
   stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
   stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
  }

        public static function getInstance(stg:Stage):GameKeys {
   GameKeys.stage = stg;
   if(GameKeys._instance == null)
   {
    GameKeys._instance=new GameKeys(new PrivateClass());
   }
            return GameKeys._instance;
        }
  public function setKeyDownCallback(cb)
  {
   cbKeyDown=cb;
  }
  
  public function isDown(keyCode:uint):Boolean 
  {
   if(keysDown[keyCode]) return true;
   // duplicate presses!
   else return false; // also when it's null!
  }
  
  private function keyPressed(evt:KeyboardEvent):void {
   if(keysDown[evt.keyCode]!=true)
   {
    if(cbKeyDown!=null)cbKeyDown(evt.keyCode);
    //trace("key first down"+evt.keyCode);
   }
   keysDown[evt.keyCode] = true;
  }
  
  private function keyReleased(evt:KeyboardEvent):void {
   //trace("key up"+evt.keyCode);
   keysDown[evt.keyCode]=false;
  }

 }
}
class PrivateClass
{
 public function PrivateClass(){
  trace("GameKeys PrivateClasse called");
 }
 
}
In the game I'll add facilities for using different keys from left right etc, like numpad.
This way I have a better chance of making a workaround for this Adobe-bug for my users/players.

zaterdag 1 januari 2011

as2 to as3

I'm a regular flash-guru according to some. I program games, so if there is a problem in Flash, I usually find it. Up until last year I still programmed in as2 and hadn't done much OOP (Object Oriented Programming)
So I figure, I go learn it in 2011, blog about what I find and maybe make some people happy, who knows.

Now I found out one of the first surprising things quite quickly. Don't think you know something, even when it doesn't seem to have changed.

this is (very concise) as2:
mc.localToGlobal(p={x:0,y:0});

after this p.x and p.y hold the coordinates of mc's anchorpoint on the stage..
I use this a lot in game-development in as2.
I was thrilled that the function hadn't changed..
BUT!
in as3 the above always leaves you with the original point, nothing happens!
in as3 the snippet would be:
var p:Point=new Point(0,0);
p=mc.localToGlobal(p);

As you can see, the difference is subtle. In as2, the point that you give is modified. In as3 the point is returned from the function and the original point is left unaltered.
I know the latter is more correct and I understand now why they did it..
But WHY weren't we warned. I found NO reference to this whatsoever.

Bad Adobe!