Mediamonkey
%Europe/Berlin %737 %2005, 17:41
Dag lui,
Ik ben momenteel eindelijk weer druk bezig met m'n arcade-fly-shooter-game-ding na een beetje aandringen van Dauntless, en ik zat me te ergeren aan het feit dat ik te weinig muisknoppen kon gebruiken om m'n vliegtuigje aan te sturen. Ik wist wel hoe ik de up- & down-events kon faken, en kwam er achter dat de middelste muisknop ook prima te detecteren viel. A plan was born!
Zie hier de class en demo voor het detecteren van de LMB, MMB en RMB. Okee, de LMB was niet nodig geweest, aangezien die al een listener heeft in de Mouse-class, maar ik heb 'm toegevoegd voor het complete plaatje. De RMB is waarschijnlijk ook niet handig vanwege het oppoppende contectmenuutje, maar die MMB is mooi meegenomen! Kun je toch weer mooi een extra actie met je muis uitvoeren :)
Klik hier voor een online demo. (http://www.mediamonkey.nl/flashfiles/MouseDetection.html) | En hier voor de sources. (http://www.mediamonkey.nl/flashfiles/MouseDetection.zip)
Op- en aanmerkingen worden zoals gewoonlijk op prijs gesteld :)
Mediamonkey
** EDIT **
Tadaaa, ik heb een scroll en een doubleclick toegevoegd. Allebij als event te benaderen. Ik heb er niet voor gekozen om per button een apart event af te vuren, maar het buttontype als target (string) mee te geven. Dan mag je mooi in de scrollfunctie die je als listener verbindt die naam uit het argument-object vissen en er iets mee aansturen.
De swf en zip waar de linkjes naar verwijzen zijn ook aangepast.
/** MouseDetection.as
* @Author: Bart "Mediamonkey" Wttewaall
* @Date: 31-10-2005
* @Description:
* A class that tests throug an interval if the left, middle or right mousebutton is up or down.
* It returns an event that can be listened to through the EventDispatcher.
*
* Events LMBup, LMBdown, MMBup, MMBdown, RMBup, RMBdown all return buttonname and isDown boolean
* scroll returns direction as lines(number), doubleclick returns offsettime between clicks
*
*/
import mx.utils.Delegate;
import mx.events.EventDispatcher;
class MouseDetection {
private var intervalID:Number;
private var mouseListener:Object;
// Button states (true = down, false = up)
private var LMB:Boolean;
private var RMB:Boolean;
private var MMB:Boolean;
// stored time between two clicks
private var LMBtime:Number;
private var MMBtime:Number;
private var RMBtime:Number;
// after some tests, the fastests I could click was 30 ms
public var time:Number = 30;
// offset between two mouseclicks to count as a doubleclick
public var doubletime:Number = 250;
// mixin methods from the EventDispatcher
public var addEventListener:Function;
public var removeEventListener:Function;
public var dispatchEvent:Function;
public var dispatchQueue:Function;
function MouseDetection() {
EventDispatcher.initialize(this);
LMB = RMB = MMB = false;
LMBtime = MMBtime = RMBtime = 0;
mouseListener = new Object();
mouseListener.onMouseWheel = Delegate.create(this, mousewheel);
Mouse.addListener(mouseListener);
startTesting();
}
public function startTesting() {
intervalID = setInterval(this, "enterframe", time);
}
public function stopTesting() {
clearInterval(intervalID);
}
// -- the rest are private methods, don't bother with them
private function enterframe() {
LMBsetter = Key.isDown(1);
RMBsetter = Key.isDown(2);
MMBsetter = Key.isDown(4);
// this commented bit of code doesn't seem to work all the time, must be because of ALT
// Keycodes: 18 = ALT, 37 = LEFT, 39 = RIGHT
// backbutton = ALT+LEFT, forwardbutton = ALT+RIGHT
//if (Key.isDown(18) && Key.isDown(37)) trace("backbutton");
//if (Key.isDown(18) && Key.isDown(39)) trace("forwardbutton");
}
// -- LMBsetter property setter, without getter (no need for it).
// This catches the true/false value, checks for double entries (!!!) and dispatches the
// correct event before assigning the value to the LMB boolean, thus saving a few lines.
function set LMBsetter(b:Boolean) {
if (b && !LMB) {
dispatchEvent({type:"LMBdown", target:"LMB", isDown:true});
} else if (!b && LMB) {
dispatchEvent({type:"LMBup", target:"LMB", isDown:false});
// test doubleclick
var diff = getTimer()-LMBtime;
if (diff < doubletime) dispatchEvent({type:"doubleclick", target:"LMB", value:diff});
LMBtime = getTimer();
}
LMB = b;
}
function set MMBsetter(b:Boolean) {
if (b && !MMB) {
dispatchEvent({type:"MMBdown", target:"MMB", isDown:true});
} else if (!b && MMB) {
dispatchEvent({type:"MMBup", target:"MMB", isDown:false});
// test doubleclick
var diff = getTimer()-MMBtime;
if (diff < doubletime) dispatchEvent({type:"doubleclick", target:"MMB", value:diff});
MMBtime = getTimer();
}
MMB = b;
}
function set RMBsetter(b:Boolean) {
if (b && !RMB) {
dispatchEvent({type:"RMBdown", target:"RMB", isDown:true});
} else if (!b && RMB) {
dispatchEvent({type:"RMBup", target:"RMB", isDown:false});
// test doubleclick
var diff = getTimer()-RMBtime;
if (diff < doubletime) dispatchEvent({type:"doubleclick", target:"RMB", value:diff});
RMBtime = getTimer();
}
RMB = b;
}
private function mousewheel(direction:Number) {
if (direction > 0) dispatchEvent({type:"scroll", target:"scrollUp", value:direction});
else dispatchEvent({type:"scroll", target:"scrollDown", value:direction});
}
}
Usage:
import MouseDetection;
import mx.utils.Delegate;
var MD = new MouseDetection();
MD.addEventListener("LMBdown", Delegate.create(this, write));
MD.addEventListener("LMBup", Delegate.create(this, write));
MD.addEventListener("RMBdown", Delegate.create(this, write));
MD.addEventListener("RMBup", Delegate.create(this, write));
MD.addEventListener("MMBdown", Delegate.create(this, write));
MD.addEventListener("MMBup", Delegate.create(this, write));
MD.addEventListener("scroll", Delegate.create(this, scroll));
MD.addEventListener("doubleclick", Delegate.create(this, doubleclick));
function write(evt:Object) {
trace(evt.target+" = "+evt.isDown);
}
function scroll(evt:Object) {
trace(evt.target+" = "+evt.value);
}
function doubleclick(evt:Object) {
trace(evt.target+" doubleclick: "+evt.value+" ms");
}
Ik ben momenteel eindelijk weer druk bezig met m'n arcade-fly-shooter-game-ding na een beetje aandringen van Dauntless, en ik zat me te ergeren aan het feit dat ik te weinig muisknoppen kon gebruiken om m'n vliegtuigje aan te sturen. Ik wist wel hoe ik de up- & down-events kon faken, en kwam er achter dat de middelste muisknop ook prima te detecteren viel. A plan was born!
Zie hier de class en demo voor het detecteren van de LMB, MMB en RMB. Okee, de LMB was niet nodig geweest, aangezien die al een listener heeft in de Mouse-class, maar ik heb 'm toegevoegd voor het complete plaatje. De RMB is waarschijnlijk ook niet handig vanwege het oppoppende contectmenuutje, maar die MMB is mooi meegenomen! Kun je toch weer mooi een extra actie met je muis uitvoeren :)
Klik hier voor een online demo. (http://www.mediamonkey.nl/flashfiles/MouseDetection.html) | En hier voor de sources. (http://www.mediamonkey.nl/flashfiles/MouseDetection.zip)
Op- en aanmerkingen worden zoals gewoonlijk op prijs gesteld :)
Mediamonkey
** EDIT **
Tadaaa, ik heb een scroll en een doubleclick toegevoegd. Allebij als event te benaderen. Ik heb er niet voor gekozen om per button een apart event af te vuren, maar het buttontype als target (string) mee te geven. Dan mag je mooi in de scrollfunctie die je als listener verbindt die naam uit het argument-object vissen en er iets mee aansturen.
De swf en zip waar de linkjes naar verwijzen zijn ook aangepast.
/** MouseDetection.as
* @Author: Bart "Mediamonkey" Wttewaall
* @Date: 31-10-2005
* @Description:
* A class that tests throug an interval if the left, middle or right mousebutton is up or down.
* It returns an event that can be listened to through the EventDispatcher.
*
* Events LMBup, LMBdown, MMBup, MMBdown, RMBup, RMBdown all return buttonname and isDown boolean
* scroll returns direction as lines(number), doubleclick returns offsettime between clicks
*
*/
import mx.utils.Delegate;
import mx.events.EventDispatcher;
class MouseDetection {
private var intervalID:Number;
private var mouseListener:Object;
// Button states (true = down, false = up)
private var LMB:Boolean;
private var RMB:Boolean;
private var MMB:Boolean;
// stored time between two clicks
private var LMBtime:Number;
private var MMBtime:Number;
private var RMBtime:Number;
// after some tests, the fastests I could click was 30 ms
public var time:Number = 30;
// offset between two mouseclicks to count as a doubleclick
public var doubletime:Number = 250;
// mixin methods from the EventDispatcher
public var addEventListener:Function;
public var removeEventListener:Function;
public var dispatchEvent:Function;
public var dispatchQueue:Function;
function MouseDetection() {
EventDispatcher.initialize(this);
LMB = RMB = MMB = false;
LMBtime = MMBtime = RMBtime = 0;
mouseListener = new Object();
mouseListener.onMouseWheel = Delegate.create(this, mousewheel);
Mouse.addListener(mouseListener);
startTesting();
}
public function startTesting() {
intervalID = setInterval(this, "enterframe", time);
}
public function stopTesting() {
clearInterval(intervalID);
}
// -- the rest are private methods, don't bother with them
private function enterframe() {
LMBsetter = Key.isDown(1);
RMBsetter = Key.isDown(2);
MMBsetter = Key.isDown(4);
// this commented bit of code doesn't seem to work all the time, must be because of ALT
// Keycodes: 18 = ALT, 37 = LEFT, 39 = RIGHT
// backbutton = ALT+LEFT, forwardbutton = ALT+RIGHT
//if (Key.isDown(18) && Key.isDown(37)) trace("backbutton");
//if (Key.isDown(18) && Key.isDown(39)) trace("forwardbutton");
}
// -- LMBsetter property setter, without getter (no need for it).
// This catches the true/false value, checks for double entries (!!!) and dispatches the
// correct event before assigning the value to the LMB boolean, thus saving a few lines.
function set LMBsetter(b:Boolean) {
if (b && !LMB) {
dispatchEvent({type:"LMBdown", target:"LMB", isDown:true});
} else if (!b && LMB) {
dispatchEvent({type:"LMBup", target:"LMB", isDown:false});
// test doubleclick
var diff = getTimer()-LMBtime;
if (diff < doubletime) dispatchEvent({type:"doubleclick", target:"LMB", value:diff});
LMBtime = getTimer();
}
LMB = b;
}
function set MMBsetter(b:Boolean) {
if (b && !MMB) {
dispatchEvent({type:"MMBdown", target:"MMB", isDown:true});
} else if (!b && MMB) {
dispatchEvent({type:"MMBup", target:"MMB", isDown:false});
// test doubleclick
var diff = getTimer()-MMBtime;
if (diff < doubletime) dispatchEvent({type:"doubleclick", target:"MMB", value:diff});
MMBtime = getTimer();
}
MMB = b;
}
function set RMBsetter(b:Boolean) {
if (b && !RMB) {
dispatchEvent({type:"RMBdown", target:"RMB", isDown:true});
} else if (!b && RMB) {
dispatchEvent({type:"RMBup", target:"RMB", isDown:false});
// test doubleclick
var diff = getTimer()-RMBtime;
if (diff < doubletime) dispatchEvent({type:"doubleclick", target:"RMB", value:diff});
RMBtime = getTimer();
}
RMB = b;
}
private function mousewheel(direction:Number) {
if (direction > 0) dispatchEvent({type:"scroll", target:"scrollUp", value:direction});
else dispatchEvent({type:"scroll", target:"scrollDown", value:direction});
}
}
Usage:
import MouseDetection;
import mx.utils.Delegate;
var MD = new MouseDetection();
MD.addEventListener("LMBdown", Delegate.create(this, write));
MD.addEventListener("LMBup", Delegate.create(this, write));
MD.addEventListener("RMBdown", Delegate.create(this, write));
MD.addEventListener("RMBup", Delegate.create(this, write));
MD.addEventListener("MMBdown", Delegate.create(this, write));
MD.addEventListener("MMBup", Delegate.create(this, write));
MD.addEventListener("scroll", Delegate.create(this, scroll));
MD.addEventListener("doubleclick", Delegate.create(this, doubleclick));
function write(evt:Object) {
trace(evt.target+" = "+evt.isDown);
}
function scroll(evt:Object) {
trace(evt.target+" = "+evt.value);
}
function doubleclick(evt:Object) {
trace(evt.target+" doubleclick: "+evt.value+" ms");
}