I'm currently working on a project using ActionScript 3 in Flex 4.6. I was having trouble making any key events register in my script (though mouse events were fine), and debugging lead to some very bizarre results.
First of all, this is my test code:
Contents of KET.mxml:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
name="Key Events Test"
backgroundColor="#000000"
horizontalAlign="center"
creationComplete="setup();"
enterFrame="updateFrame();"
paddingLeft="0"
paddingTop="0"
paddingBottom="0"
paddingRight="0"
frameRate="60"
width="960" height="720">
<mx:Script>
<![CDATA[
include "KET.as";
]]>
</mx:Script>
<mx:Canvas id="gamePanel" x="0" y="0" width="100%" height="100%" click="mouseClicked(event)" keyDown="keyDown(event)"/>
</mx:Application>
Contents of KET.as:
import flash.display.*;
import flash.events.*;
import mx.events.*;
import mx.controls.*;
public static const SCREEN_WIDTH:int = 960;
public static const SCREEN_HEIGHT:int = 720;
private var initializationCompleted:Boolean = false;
public var screenBuffer:BitmapData;
private var trigger:int = 0;
public function setup():void {
screenBuffer = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0x00000000);
initializationCompleted = true;
}
private function updateFrame():void {
if (!initializationCompleted) {
return;
}
gamePanel.graphics.clear();
gamePanel.graphics.beginBitmapFill(screenBuffer, null, false, false);
gamePanel.graphics.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
gamePanel.graphics.endFill();
if (trigger == 0) {
screenBuffer.fillRect(new Rectangle(480, 360, 200, 200), 0xFF000000);
} else if (trigger == 1) {
screenBuffer.fillRect(new Rectangle(480, 360, 200, 200), 0xFFFF0000);
} else if (trigger == 2) {
screenBuffer.fillRect(new Rectangle(480, 360, 200, 200), 0xFF0000FF);
}
}
private function mouseClicked(event:MouseEvent):void {
trigger = 1;
}
private function keyDown(event:KeyboardEvent):void {
trigger = 2;
}
The code above, when ran, is supposed to give a black screen at the start, on which a red rectangle appears once the user clicks on it and a blue one once the user presses a key. However, the key press is completely ignored.
While debugging this, I started getting some very strange results. A tutorial I have been loosely following found here shows how to check for keyboard events. Now upon following the same instructions, or even downloading and compiling the code given in the tutorial I get a fully working project, but with no keyboard controls. Now this happens regardless of how I run the resulting SWF, be it in a flash interpreter, through a browser locally or from a server. At first I thought it was due to the SWF given in the tutorial being compiled by some legacy version of Flex, but after downloading the SWF from the website directly I get the same results. The only place where it works is on the original website.
So what am I doing terribly wrong here? Is there a bug in my current solution or am I just taking an incredibly wrong approach?
Thanks in advance!!
I have not tested your project, but if memory serves, a component needs to receive focus to handle keyboard events.
By simply adding gamePanel.setFocus();
at the end of the updateFrame()
function, I think it will work.
Like this:
private function updateFrame():void {
if (!initializationCompleted) {
return;
}
gamePanel.graphics.clear();
gamePanel.graphics.beginBitmapFill(screenBuffer, null, false, false);
gamePanel.graphics.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
gamePanel.graphics.endFill();
if (trigger == 0) {
screenBuffer.fillRect(new Rectangle(480, 360, 200, 200), 0xFF000000);
} else if (trigger == 1) {
screenBuffer.fillRect(new Rectangle(480, 360, 200, 200), 0xFFFF0000);
} else if (trigger == 2) {
screenBuffer.fillRect(new Rectangle(480, 360, 200, 200), 0xFF0000FF);
}
gamePanel.setFocus();
}
Another option could be to add an EventListener
for the whole application (be careful, if you use text fields, this EventListener will be triggered during text input).
public function setup():void {
screenBuffer = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0x00000000);
systemManager.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
initializationCompleted = true;
}
I hope this will help you.