In the KeyboardEvent object I get on key-down events, is there a way to know if the event is the first key-down, or a repeat when the key is held down?
I want to toggle a setting when a key is pressed; I could listen to key-up but I'd prefer the action is taken as soon as the key is pushed... as long as I can stop it toggling back and forth as the key-down repeat events are generated.
Tested and works
import flash.events.KeyboardEvent;
stage.addEventListener(KeyboardEvent.KEY_DOWN, onDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onUp);
var keys:Object = {};
function onDown(e:KeyboardEvent):void {
if( ! Boolean(e.keyCode in keys)) {
trace("First Time");
keys[e.keyCode] = true;
}
}
function onUp(e:KeyboardEvent):void {
delete keys[e.keyCode];
}
The idea of storing key codes in an object and the use of delete on key up originally came from Senoculars library. See http://www.senocular.com/flash/actionscript/
The easiest thing is to remove or disable the KEY_DOWN listener with a flag inside the KEY_DOWN listener, and then add or enable it in the KEY_UP.
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
private function onKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.SPACE)
{
stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
}
private function onKeyUp(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.SPACE)
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.removeEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
}
Related
I need an Event Listener for press Delete button from keyboard.
I try with this code:
stage.addEventListener(KeyboardEvent.KEY_UP, deleteItem);
function deleteItem(e:KeyboardEvent) {
if(e.charCode == 46){
trace('1');
}
}
but don't work. Please help me!
stage.addEventListener(KeyboardEvent.KEY_UP, keyboardEventUPHandler, false, 0, true);
function keyboardEventUPHandler(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.DELETE)
{
//Keyboard.DELETE = 46
//do something
}
}
stage.addEventListener(KeyboardEvent.KEY_UP, deleteItem);
should be
stage.addEventListener(KeyboardEvent.KEY_DOWN, deleteItem);
Does anyone know how to move a movie clip by clicking a button on the stage. I can get it to move in increments, but I want it to move constantly. Currently I have this:
down.addEventListener(MouseEvent.MOUSE_DOWN, arrowDown);
function arrowDown(event:MouseEvent):void
{
bottomArrow.y += 1;
}
First, you should listen for KeyboardEvents instead of MouseEvent. Then I think you should listen for those events being dispatched by the stage.
Here is an example using the Event.ENTER_FRAME event. If you'd like to control better the speed of you sprite moves you might want to user a timer instead.
This example works when the down arrow is pressed but you can change Keyboard.DOWN with any key you want.
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
function onKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.DOWN)
{
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
function onKeyUp(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.DOWN)
{
stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
function onEnterFrame(event:Event):void
{
bottomArrow.y += 1;
}
Hey is there a way to have certain keys do one thing on one page and then different on another, as i use
But then on next frame i cant use space bar again to do another task?
Any help would be appreciated
stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDownn);
function myKeyDownn(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.SPACE){
gotoAndPlay("welcome");
}
}
just remove the listener before you leave the frame.
stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDownn);
function myKeyDownn(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.SPACE){
stage.removeEventListener(KeyboardEvent.KEY_DOWN, myKeyDownn);
gotoAndPlay("welcome");
}
}
in the frame "welcome" add the same code again and just change the gotoAndPlay() part.
stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDownn);
function myKeyDownn(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.SPACE){
stage.removeEventListener(KeyboardEvent.KEY_DOWN, myKeyDownn);
gotoAndPlay("a different frame");
}
}
now I'm trying to make the keyboard events to stop repeating.
My idea was to have a true and false condition for when the key is pressed so that it wont repeat if the key is down already.
//Mouse Event Over
keyCButton.addEventListener(MouseEvent.MOUSE_OVER, function(){gotoAndStop(2)});
//Variable
var Qkey:uint = 81;
//Key Down Event
stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown);
var soundplayed = false;
function keydown(event:KeyboardEvent){
if (event.keyCode==Qkey) {
this.soundplayed=true;
}
}
if (this.soundplayed==false){
gotoAndPlay(3);
}
//Key Up Event
stage.addEventListener(KeyboardEvent.KEY_UP, keyup);
function keyup(event:KeyboardEvent){
this.soundplayed=false;
gotoAndStop(1);
}
doing this makes the key loop over and over without a keyboard event
I think i need to add a "&& keyDown..." to "if (this.soundplayed==true)" but i dont know how to do it without getting errors
here is the keyboard player i'm trying to fix http://soulseekrecords.org/psysci/animation/piano.html
Just another (perhaps a bit more general) way to write what Kishi already suggested:
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUp);
var downKeys:Dictionary = new Dictionary();
function keyDown(e:KeyboardEvent):void {
if(!downKeys[e.keyCode]) {
downKeys[e.keyCode] = true;
processKeyDown(e);
}
}
function keyUp(e:KeyboardEvent):void {
delete downKeys[e.keyCode];
}
function processKeyDown(e:KeyboardEvent):void {
trace(e.keyCode);
}
The processKeyDown function will be called as if keydown repeating was disabled. If you need to do something when the key is up, put that code in the keyUp function, or maybe call a processKeyUp function defined like processKeyDown.
I'm not sure what you are doing on these frames..
Is that the complete code?
Anyway, you should try something like this:
// Mouse Events
this.keyCButton.addEventListener(MouseEvent.MOUSE_OVER, function():void{ gotoAndStop(2) });
// Variables
var Qkey:uint = 81;
var soundplayed = false;
// Keyboard events
this.stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown);
this.stage.addEventListener(KeyboardEvent.KEY_UP, keyup);
// Event listeners
function keydown(event:KeyboardEvent){
if (event.keyCode == Qkey && !this.soundplayed) {
this.soundplayed = true;
this.gotoAndPlay(3);
}
}
function keyup(event:KeyboardEvent){
this.soundplayed = false;
this.gotoAndStop(1);
}
Notice that the keydown event listener will now execute once -- I mean.. at least the if branch -- as the soundplayed variable is used as a locking mechanism.
It'll only execute again after keyup's been executed (this.soundplayed = false).
I am a beginner in Flash Actionscript 3.0 programming. I am trying to create smooth keyboard controls for player movement in a game.
I'm currently using addEventListener(KeyboardEvent.KEY_DOWN) listening for a keyboard key press and then within the handler function moving a graphic by adding a number to its .x or .y property.
This creates a slow, sluggish jerk at the beginning. I know there's a smoother, more responsive way to do this but have no idea where to begin. Any help would be appreciated!
For smooth keys I would suggest using either a Timer or onEnterFrame to poll for keys often enough to get smooth controls. It will get the job done, but at a certain expense. If you've got the rest of the logic all fine, this should fit in ok:
var key:int = NaN;
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress,false,0,true);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease,false,0,true);
this.addEventListener(Event.ENTER_FRAME,update,false,0,true);
function onKeyPress(event:KeyboardEvent):void {
key = event.keyCode;
event.stopPropagation();
}
function onKeyRelease(event:KeyboardEvent):void {
key = NaN;
event.stopPropagation();
}
function update(event:Event):void{
if(key) trace(key);
}
I make sure the event doesn't bubble by stopping it's propagation, and it's set on the stage which should be the topmost level, event wise. Also I'm using the key only the key is down, otherwise I ignore it in the enterFrame handler.
HTH,
George
Where are you placing the listener? Is it in the application, or in the sprite that is supposed to move? Does the sprite have the focus when you are pressing the key?
Also, in adding the event listener, are you using capture? That is, are you setting the 3rd argument to true, as in
addEventListener(KeyboardEvent.KEY_DOWN, yourHandler, true)
If you use capture, which is how you have to do it if the App itself is listening for the event, then you will get a certain amount of latency, and this latency will be greater the more complex the interface is. If those events have to work their way up a vast hierarchy, this could be noticeable. If there are many sprites, this can exacerbate the problem.
What you can do is have the sprite that has the focus dispatch a custom event which a controller class listens to for each sprite. The controller class will have a handler that moves the event.currentTarget however you plan to have it done.
Also read up about custom events and how to use the SystemManager to add and remove listeners dynamically: http://livedocs.adobe.com/flex/3/langref/index.html.
the most simplest example to this would be this.
here you have a controllable Ship class(Ship.as).
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
public class Ship extends MovieClip {
private var speedX;
private var speedY;
public function Ship() {
//constructor
stage.addEventListener(KeyboardEvent.KEY_DOWN ,keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP ,keyUp);
stage.addEventListener(Event.ENTER_FRAME, update);
}
public function keyDown(e:KeyboardEvent) {
if(e.keyCode == 37) {
speedX = -5;
}
if(e.keyCode == 38) {
speedY = -5;
}
if(e.keyCode == 39) {
speedX = 5;
}
if(e.keyCode == 40) {
speedY = 5;
}
}
public function keyUp(e:KeyboardEvent) {
if(e.keyCode == 37 || e.keyCode == 39) {
speedX = 0;
}
if(e.keyCode == 38 || e.keyCode == 40) {
speedY = 0;
}
}
public function update(e:Event) {
x += speedX;
y += speedY;
}
}