Here's the class I've been using. It's designed around java, but it only takes an extra function to get it working the same way in bgt.
(The MyKeyC function just generates the default configuration I like using. No one else seems to like it, though, so feel free to ignore that one.)
// KeyC bridges poll-based and event-based keyboard input,
// And enables custom keyboard configurations.
// Constants:
const int START=128, L=1, R=2, U=4, D=8, A=16, B=32, C=64, none=-1;
// 1:56 PM 4/8/2010: START was originally 0, but since this makes it impossible to determine if start has or hasn't been pressed (and this was causing problems with game controllers), it's been changed to 128.
const int X=256, Y=512, Z=1024; // Added 10:35 AM 5/24/2010.
const int KeyC_START=128, KeyC_L=1, KeyC_R=2, KeyC_U=4, KeyC_D=8, KeyC_A=16, KeyC_B=32, KeyC_C=64, KeyC_none=-1;
// 1:56 PM 4/8/2010: START was originally 0, but since this makes it impossible to determine if start has or hasn't been pressed (and this was causing problems with game controllers), it's been changed to 128.
const int KeyC_X=256, KeyC_Y=512, KeyC_Z=1024; // Added 10:35 AM 5/24/2010.
KeyC@ MyKeyC() {
KeyC ret(); //=new KeyC();
ret.l=KEY_A;
ret.r = KEY_S;
ret.u=KEY_W;
ret.d=KEY_Z;
ret.a=KEY_F;
ret.b=KEY_G;
ret.c=KEY_H;
ret.start=KEY_SPACE;
// X, Y and Z added 10:37 AM 5/24/2010:
ret.x=KEY_R;
ret.y=KEY_T;
ret.z=KEY_Y;
return ret;
}//I use this one a lot...
class KeyC {
// Mapping variables to KeyCodes:
int l;
int r;
int u;
int d;
int a;
int b;
int c;
int start;
int x; int y; int z; // 10:36 AM 5/24/2010.
int flags; // Keyup/keydown bits. Note that this prevents start from being caught.
int lastPressed; //7:13 AM 2/14/2010. To determine if a key being released is the last key that was pressed.
KeyC() {init();}
void init() {
l=KEY_LEFT; r=KEY_RIGHT; d=KEY_DOWN; u=KEY_UP;
a=KEY_NUMPAD1; b=KEY_NUMPAD2; c=KEY_NUMPAD3; start=KEY_RETURN;
x=KEY_NUMPAD4; y=KEY_NUMPAD5; z=KEY_NUMPAD6;
flags=0; // Keyup/keydown bits. Note that this prevents start from being caught.
lastPressed=-1; //7:13 AM 2/14/2010. To determine if a key being released is the last key that was pressed.
}// Initialize.
int getKey(int k) {
if(k==a) return A;
else if(k==b) return B;
else if(k==c) return C;
else if(k==x) return X;
else if(k==y) return Y;
else if(k==z) return Z;
else if(k==start) return START;
else if(k==l) return L;
else if (k==r) return R;
else if(k==u) return U;
else if(k==d) return D;
return none;
}//Key.
bool isKeyPressed(int k) {
if(k<=0) return false;
return (flags&k)!=0;
}
int press(int ke) {
int k=getKey(ke);
if(k<=0) return k;
else if( (flags & k)!=0) return none;
flags|=k;
lastPressed=k;
return k;
}//Assuming we don't know what k is from the start.
int release(int ke) {
int k=getKey(ke);
if(k<=0) return k;
else if( (flags & k)==0) return none;
// I always get confused on turning off a bit.
flags = ~ ( (~flags) |k);
// So that flips flags. We ensure that k is 0, with absolutely no answer for the rest. We flip it back. K turns to 0, everything else is as it was. Is there a quicker way to do that? :P. Maybe &~k?
return k;
}//Releasing an unknown key.
// I can't help but think I'm forgetting something. :P.
} //Heh! This used to be a private class...
A save/load function for it might look like this:
bool save_controls(KeyC@ keys, string filename) {
string text="" + keys.l + "\n" + keys.r + "\n" + keys.u + "\n" + keys.d + "\n" + keys.a + "\n" + keys.b + "\n" + keys.c + "\n" + keys.x + "\n" + keys.y + "\n" + keys.z + "\n" + keys.start;
file fout;
fout.open(filename, "w");
fout.write(text);
fout.close();
return true;
}
KeyC@ load_controls(string filename) {
KeyC ret;
if(!file_exists(filename)) return ret;
file fin;
fin.open(filename, "r");
string text=fin.read(0);
string[] lines=string_split(text, "\n", true);
if(lines.length()<11) return ret; // Otherwise it will crash with a runtime error.
ret.l=string_to_number(lines[0]);
ret.r=string_to_number(lines[1]);
ret.u=string_to_number(lines[2]);
ret.d=string_to_number(lines[3]);
ret.a=string_to_number(lines[4]);
ret.b=string_to_number(lines[5]);
ret.c=string_to_number(lines[6]);
ret.x=string_to_number(lines[7]);
ret.y=string_to_number(lines[8]);
ret.z=string_to_number(lines[9]);
ret.start=string_to_number(lines[10]);
return ret;
}
I haven't tried compiling those two, though. THere might be errors. THe class is fine; I've been using it for like 6 years.
How to use that effectively is a whole other post, though.
看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
George... Don't do that.