Volledige versie bekijken : Op ieder moment op keyCode checken
Baukereg
%Europe/Berlin %923 %2007, 22:09
Met as2 kon ik met Key.isDown() op ieder moment checken of een key ingedrukt was, bijvoorbeeld in een onEnterFrame event.
In as3 is deze methode echter niet meer aanwezig. Natuurlijk kan ik gebruik maken van stage.addEventListener(KeyboardEvent.keyDown) om te checken of er een toets ingedrukt is, maar dit heeft zijn beperkingen. Zeker voor het ontwikkelen van bepaalde games is het soms noodzakelijk om snel te checken of een key ingedrukt is of niet, zonder hierbij eerst een eventListener te moeten instellen. Ook is het makkelijk wanneer je bijv. wilt kijken of twee keys tegelijk ingedrukt zijn. Ik hebt het nu gefixed met twee booleans die aangeven of ze ingedrukt zijn en die worden veranderd bij KEY_DOWN en KEY_UP, maar dit is heel omslachtig.
Is er een manier om dat met as3 te fixen?
Edit:
Ik ben zojuist deze blogpost (http://www.agstrout.com/?p=6) tegen gekomen van iemand met hetzelfde probleem als mij. Hij heeft er een class voor geschreven om om keys makkelijk op te vangen. Ik vind de class niet helemaal netjes en optimaal, dus een leuk projectje om zelf mee bezig te gaan de komende dagen! :)
.. to be continued
TheDutch
%Europe/Berlin %356 %2007, 08:33
Grappig, ik ben daar net zelf ook mee bezig (in mijn vrije tijd), alleen niet specifiek voor games dan :).
Ben erg benieuwd naar jouw oplossing wanneer deze klaar is!
B-Mantis
%Europe/Berlin %415 %2007, 09:58
wat ik zelf altijd doe is events listeners toevoegen aan de stage:
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyD own);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUp) ;
met de volgende functies:
private function keyDown(e:KeyboardEvent):void {
Input.curKey = e.keyCode;
switch (e.keyCode) {
case 37 :
case 65 :
Input.KEY_LEFT = true;
break;
case 38 :
case 87 :
Input.KEY_UP = true;
break;
case 39 :
case 68 :
Input.KEY_RIGHT = true;
break;
case 40 :
case 83 :
Input.KEY_DOWN = true;
break;
case 32 :
Input.SPACE = true;
break;
case 13 :
Input.ENTER = true;
break;
}
}
private function keyUp(e:KeyboardEvent):void {
Input.curKey = 0;
switch (e.keyCode) {
case 37 :
case 65 :
Input.KEY_LEFT = false;
break;
case 38 :
case 87 :
Input.KEY_UP = false;
break;
case 39 :
case 68 :
Input.KEY_RIGHT = false;
break;
case 40 :
case 83 :
Input.KEY_DOWN = false;
break;
case 32 :
Input.SPACE = false;
break;
case 13 :
Input.ENTER = false;
break;
}
}
zoals je ziet worden alle waarden opgeslagen in de Input class. Dit zijn allemaal statische waarden dus elke andere class hoeft alleen maar de Input class the importen en heeft dan toegang. Je kunt ook een functie als getKey() maken op die manier.
Ik ben benieuwd of je een betere manier kan vinden want volgens mij kent flash geen andere manier om erachter te komen of keys worden ingedrukt dan KeyboardEvent.keyCode.
Baukereg
%Europe/Berlin %466 %2007, 11:11
Beter... wat is beter? Iedereen zijn eigen manier van werken. Wat ik minder vind aan jou manier is dat je eerst in de stage een hele switch moet definieren, terwijl ik direct toegang wil hebben tot alle keys.
Ik heb de volgende class geschreven, graag hoor ik jullie commentaar. Het enige 'nadeel' van mijn class is dat je 'm eenmalig moet aanmaken met een referentie naar de Stage als paramater. Hier een voorbeeld van hoe het werkt (in de 1e frame van stage in dit geval):
import flash.events.Event;
import nl.regnerusmedia.keys.Key;
new Key(this.stage);
Key.assignLink("BOOST", 38);
addEventListener(Event.ENTER_FRAME, enter_frame);
function enter_frame(e:Event) {
if (Key.isDown(37)) {
trace("we're going left");
} else if (Key.linkDown("RIGHT")) {
trace("No, we're going right");
}
if (Key.linkDown("BOOST")) {
trace("Boosting... speed up!");
}
}
Zoals je ziet kun je gebruik maken van twee static methoden om een key te lezen, namelijk het oude en vetrouwde isDown(code:Number), en linkDown(link:String). De laatste methode doet hetzelfde als de eerste, maar dan via een string die gekoppeld is aan een code. De welbekende LEFT, RIGHT, SPACE enz. worden automatisch aangemaakt, dus die kun je zo gebruiken. Daarnaast kun je ook zelf een link aanmaken, met de functie assignLink(link:String, code:Number). In het voorbeeld heb ik dat gedaan voor BOOST die gekoppeld wordt aan code 38 (is pijltje omhoog). Een link is weer te verwijderen d.m.v. removeLink(link:String).
Edit:
en hier nog ff de class code zodat jullie snel kunnen kijken:
package nl.regnerusmedia.keys {
import flash.display.Stage;
import flash.events.KeyboardEvent;
public class Key {
//__________________________________________________ ____________________ properties
// static
static private var _instance :Key;
// non-static
private var _stage :Stage;
private var _keys :Array;
private var _keyLinks :Array;
//__________________________________________________ ____________________ constructor
public function Key(stage:Stage) {
// check for instance
if (Key.checkInstance() == true) {
throw new Error("A Key instance can be created only once, use static interface to communicate");
}
// initialize new instance
Key._instance = this;
_stage = stage;
_keys = new Array();
for (var i:int = 0; i < 256; i ++) {
_keys[i] = false;
}
_keyLinks = new Array();
assignLink("BACKSPACE", 8);
assignLink("TAB", 9);
assignLink("ENTER", 13);
assignLink("SHIFT", 16);
assignLink("CONTROL", 17);
assignLink("CAPSLOCK", 20);
assignLink("ESC", 27);
assignLink("SPACE", 32);
assignLink("PGUP", 33);
assignLink("PGDN", 34);
assignLink("END", 35);
assignLink("HOME", 36);
assignLink("LEFT", 37);
assignLink("UP", 38);
assignLink("RIGHT", 39);
assignLink("DOWN", 40);
assignLink("INSERT", 45);
assignLink("DELETEKEY", 46);
_stage.addEventListener(KeyboardEvent.KEY_DOWN, list_keyDown);
_stage.addEventListener(KeyboardEvent.KEY_UP, list_keyUp);
}
//__________________________________________________ ____________________ static interface
static public function isDown(code:Number):Boolean {
return _instance._keys[code];
}
static public function linkDown(link:String) {
var code = _instance._keyLinks[link];
if (code == undefined) {
throw new Error("Trying to read a non-assigned keylink");
} else {
return isDown(code);
}
}
static public function assignLink(link:String, code:Number) {
_instance._keyLinks[link] = code;
}
static public function removeLink(link:String) {
delete _instance._keyLinks[link];
}
//__________________________________________________ ____________________ static methodes
static private function checkInstance():Boolean {
if (Key._instance != null) {
return true;
} else {
return false;
}
}
//__________________________________________________ ____________________ instance methodes
private function list_keyDown(e:KeyboardEvent) {
_keys[e.keyCode] = true;
}
private function list_keyUp(e:KeyboardEvent) {
_keys[e.keyCode] = false;
}
}
}
B-Mantis
%Europe/Berlin %524 %2007, 12:34
het kan aan mij liggen.. maar hoe verwerkt flash dit? :
_instance._keyLinks[link] = code;
waar _keyLinks een Array is, link een String en code een int?
voor de rest trouwens interresante manier om key events te laten gebeuren.. Ik zal hier zeker aan terugdenken in de toekomst!
Baukereg
%Europe/Berlin %655 %2007, 15:43
Klopt, behalve dat code en Number is.
vBulletin® v3.8.1, Copyright ©2000-2012, Jelsoft Enterprises Ltd.