Codesnippets > Code Snippets

simple userdefined controls

(1/3) > >>

kanonet:
I created my own simple "key"-management, for user defined keys. A "key" can be a key from keyboard, mousemovement, mousebutton, joystickmovement or joystickbutton, you dont have to care about what the player use, the key-management will do all on its own. Keyboardlayouts are stored in .ini-files, i created one for us/uk and one for german keyboard, but of cause you can convert/create others for other countries (please share them with us/me!).

Its really simple to use:
1. create a new key:
--- Code: GLBasic ---LOCAL attack AS Tkey
2. let the player define his key:
--- Code: GLBasic ---REPEAT
        PRINT "Define control for attack",0,0
        SHOWSCREEN
UNTIL attack.SET()or autoset it (usefull if you load keysettings from a ini-file):
--- Code: GLBasic ---attack.SET(1, 57)and you can add a secondary/alternativ key:
--- Code: GLBasic ---attack.SET(2) or attack.SET(2, 28)
3. in your mainloop, check whether the player use the key:
--- Code: GLBasic ---IF attack.DOWN() THEN DOSOMETHING()This checks primary and secondary key.


TKey now informs you about keyup/-down event.:
//  0 = not pressed / nicht gedrückt
//  2 = just pressed / gerade runtergedrückt
//  1 = pressed / gedrückt (gehalten)
// -1 = release event / wieder losgelassen
Of cause it only works, if you use DOWN() in your loop...


The ini-files for us and german keyboard are attached, here is the code for the key-management:
--- Code: GLBasic ---// --------------------------------- //
// Project: MyKey
// Autor: kanonet
// Start: Tuesday, February 08, 2011
// Last Update: December 6, 2012

GLOBAL KEY_mouse_sensitivity% = 2       // sensitivity of the mouse
GLOBAL KEY_joystick_sensitivity# = 0.35 // sensitivity of the joystick
GLOBAL KEY_keymap$[]
GLOBAL KEY_joystick_count%      // for intern use, do not change
GLOBAL KEY_ini_file$ = "keymap_us.ini"  // which INI file to read for keyboard layout


//! Type of a "key". It is possible to set a primary and a secondary "key".
//! "key" can be a key of the keyboard, a mousemovement, a mousebutton, a joystickmovement or a joystickbutton.
//! After a "key" was set with SET(), you can use DOWN() to check whether the player use it.
//? Typ eines "keys". Es ist möglich einen primären und einen sekundären "key" zu festzulegen.
//? "key" kann eine Taste der Tastatur, eine Mausbewegung, ein Mausbutton, eine Joystickbewegung oder ein Joystickbutton sein.
//? Nachdem ein "key" mit SET() gestzt wurde, kann mit DOWN() geprüft werden, ob er benutzt wird.
TYPE Tkey
        code%   // eventcode of the "key" if "key" is on the keyboard, code = scancode of the key
        name$
        code2%
        name2$
        state%

        //! Initialise/sets the "key". Can get used as often as its needed, until played sets a "key".
        //! You can change the "key" as often, as you want. You can define a alternativ "key" also.
        //? Initialisiert/setzt den "key". Kann beliebig oft aufgerufen werden, bis der Spieler einen "key" gesetzt hat.
        //? Ein gesetzter "key" kann beliebig oft geändert werden. Es kann außerdem auch ein alternativer "key" definiert werden.
        // \param num% - Optional, use function call to set the primary (num%=1) or secondary (num%=2) "key". | Optional, mit funltionsaufruf wird der primäre (num%=1) oder der sekundäre (num%=2) "key" festgelegt.
        // \param code% - Optional, only use this if you want to select a "key", not the player!  | code% - Optional, sollte nur genutz werden, wenn man selbst ein "key" setzen und dies nicht den Spieler überlassen will!
        // \return 0 if no "key" was set, otherwise code% of the "key". | 0 wenn kein "key" gesetzt wurde, ansonsten code% des gesetzten "keys".
        FUNCTION SET: num%=1, code%=0

                LOCAL event%, name$
                event=code

                IF NOT code     // only check for userinput if no key was specified

                        // check Keyboard
                        FOR i=1 TO 237
                                IF i=89 THEN i=153
                                IF KEY(i)
                                        event=i; BREAK
                                ENDIF
                        NEXT


                        IF NOT event

                                // check mouse
                                IF MOUSEAXIS(3); event=331
                                ELSEIF MOUSEAXIS(4); event=332
                                ELSEIF MOUSEAXIS(5); event=333
                                ELSEIF MOUSEAXIS(0)<-KEY_mouse_sensitivity; event=301
                                ELSEIF MOUSEAXIS(0)>KEY_mouse_sensitivity; event=302
                                ELSEIF MOUSEAXIS(1)<-KEY_mouse_sensitivity; event=311
                                ELSEIF MOUSEAXIS(1)>KEY_mouse_sensitivity; event=312
                                ELSEIF MOUSEAXIS(2)>0; event=321
                                ELSEIF MOUSEAXIS(2)<0; event=322
                                ELSE
                                        // check joystick
                                        KEY_joystick_count%=GETNUMJOYSTICKS()-1
                                        FOR i=0 TO KEY_joystick_count
                                                IF GETJOYX(i)<-KEY_joystick_sensitivity; event=401+i*100; BREAK
                                                ELSEIF GETJOYX(i)>KEY_joystick_sensitivity; event=402+i*100; BREAK
                                                ELSEIF GETJOYY(i)<-KEY_joystick_sensitivity; event=411+i*100; BREAK
                                                ELSEIF GETJOYY(i)>KEY_joystick_sensitivity; event=412+i*100; BREAK
                                                ELSEIF GETJOYZ(i)<-KEY_joystick_sensitivity; event=421+i*100; BREAK
                                                ELSEIF GETJOYZ(i)>KEY_joystick_sensitivity; event=422+i*100; BREAK
                                                ELSEIF GETJOYRX(i)<-KEY_joystick_sensitivity; event=403+i*100; BREAK
                                                ELSEIF GETJOYRX(i)>KEY_joystick_sensitivity; event=404+i*100; BREAK
                                                ELSEIF GETJOYRY(i)<-KEY_joystick_sensitivity; event=413+i*100; BREAK
                                                ELSEIF GETJOYRY(i)>KEY_joystick_sensitivity; event=414+i*100; BREAK
                                                ELSEIF GETJOYRZ(i)<-KEY_joystick_sensitivity; event=423+i*100; BREAK
                                                ELSEIF GETJOYRZ(i)>KEY_joystick_sensitivity; event=424+i*100; BREAK
                                                ELSEIF GETDIGIX(i)<-KEY_joystick_sensitivity; event=431+i*100; BREAK
                                                ELSEIF GETDIGIX(i)>KEY_joystick_sensitivity; event=432+i*100; BREAK
                                                ELSEIF GETDIGIY(i)<-KEY_joystick_sensitivity; event=441+i*100; BREAK
                                                ELSEIF GETDIGIY(i)>KEY_joystick_sensitivity; event=442+i*100; BREAK
                                                ELSE
                                                        FOR j=0 TO 31
                                                                IF GETJOYBUTTON(i, j); event=451+j+i*100; BREAK; ENDIF
                                                        NEXT
                                                ENDIF
                                        NEXT
                                ENDIF

                        ENDIF

                ENDIF

                // DIM array for the keyboardlayout
                IF KEY_keymap_Str.count <> 324
                        DIM KEY_keymap$[324]
                        LOCAL j=0
                        INIOPEN KEY_ini_file$

                        FOR i%=0 TO 452
                                IF i=238
                                        i=301
                                ELSEIF i=334
                                        i=400
                                ENDIF
                                KEY_keymap$[j]=INIGET$("keymap", i, "")
                                INC j
                        NEXT
                        INIOPEN ""
                ENDIF

                // give readable names
                SELECT event
                        CASE 0 TO 237; name$=KEY_keymap$[event]
                        CASE 301 TO 333; name$=KEY_keymap$[event-63]
                        CASE 401 TO (KEY_joystick_count*100+482)
                                code=MOD(event,100)
                                name$=GETJOYNAME$(event/100-4)
                                IF name$="" THEN name$=KEY_keymap$[271]+FORMAT$(2,0,event/100-3)
                                SELECT code
                                        CASE 1 TO 42; name$=name$+" "+KEY_keymap$[code+271]
                                        CASE 51 TO 82; name$=name$+" "+KEY_keymap$[322]+(code-50)
                                ENDSELECT
                        DEFAULT; name$=KEY_keymap$[323]
                ENDSELECT

                // write the key on specified slot
                IF num=2
                        IF event=self.code
                                event=0
                                name$=KEY_keymap$[0]
                        ENDIF
                        self.code2%=event
                        self.name2$=name$
                ELSE
                        IF event=self.code2
                                event=0
                                name$=KEY_keymap$[0]
                        ENDIF
                        self.code%=event
                        self.name$=name$
                ENDIF
                RETURN event

        ENDFUNCTION

        //! Detect whether a "key" is used by the player or not.
        //? Ermittelt ob ein "key" vom Spieler genutzt wird.
        // \return 0 if "key" is not in use, otherwise >0. (if "key" is mouse or joystick movementspeed will be returned)  | 0 wenn "key" nicht genutzt wird, ansonsten >0. (ist "key" Maus oder Joystick, wird die Bewegungsgeschwindigleit zurück gegeben)
        // \return TKey.state% will tell you, if key was used before: 0=not pressed, 2=just pressed, 1=pressed, -1=release event. | TKey.state% gibt zurück, ob key genutzt wurde: 0=nicht gedrückt, 2=gerade runtergedrückt, 1=gedrückt (gehalten), -1=wieder losgelassen.
        FUNCTION DOWN:

                STATIC joy, event%, KEY_joystick_sensitivity=0.2
                FOR i=0 TO 1
                        IF i=0
                                event=self.code
                        ELSE
                                event=self.code2
                        ENDIF

                        SELECT event
                                CASE 0; joy=0
                                CASE 1 TO 237   // check keyboard
                                        joy=KEY(event)
                                CASE 301 TO 350 // check mouse
                                        SELECT event
                                                CASE 301; joy=MOUSEAXIS(0)/20.; IF joy<0; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 302; joy=MOUSEAXIS(0)/20.; IF joy<0 THEN joy=0
                                                CASE 311; joy=MOUSEAXIS(1)/20.; IF joy<0; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 312; joy=MOUSEAXIS(1)/20.; IF joy<0 THEN joy=0
                                                CASE 321; joy=MOUSEAXIS(2)>0
                                                CASE 322; joy=MOUSEAXIS(2)<0
                                                CASE 331; joy=MOUSEAXIS(3)
                                                CASE 332; joy=MOUSEAXIS(4)
                                                CASE 333; joy=MOUSEAXIS(5)
                                        ENDSELECT
                                CASE 401 TO (KEY_joystick_count*100+482)        // check joytick
                                        joy=MOD(event,100)
                                        event=event/100-4
                                        SELECT joy
                                                CASE 1; joy=GETJOYX(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 2; joy=GETJOYX(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 11; joy=GETJOYY(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 12; joy=GETJOYY(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 21; joy=GETJOYZ(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 22; joy=GETJOYZ(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 3; joy=GETJOYRX(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 4; joy=GETJOYRX(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 13; joy=GETJOYRY(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 14; joy=GETJOYRY(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 23; joy=GETJOYRZ(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 24; joy=GETJOYRZ(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 31; joy=GETDIGIX(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 32; joy=GETDIGIX(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 41; joy=GETDIGIY(event); IF joy<-KEY_joystick_sensitivity; joy=-joy; ELSE; joy=0; ENDIF
                                                CASE 42; joy=GETDIGIY(event); IF joy<KEY_joystick_sensitivity THEN joy=0
                                                CASE 51 TO 82; joy=SGN(GETJOYBUTTON(event, joy-51))
                                                DEFAULT; joy=0
                                        ENDSELECT
                                DEFAULT; joy=0
                        ENDSELECT
                        IF joy THEN BREAK
                NEXT
                // check if key was used before
                IF joy
                        IF self.state
                                self.state=1
                        ELSE
                                self.state=2
                        ENDIF
                ELSE
                        IF self.state>0
                                self.state=-1
                        ELSE
                                self.state=0
                        ENDIF
                ENDIF
                RETURN joy

        ENDFUNCTION

ENDTYPEPlease let me know what you think about this and report bugs. I dont have a real joystick/gamepad (i just used a virtual one) and my keyboard has no numpad/mediakeys, so it would be really nice if someone could test this for me. EDIT: Testing done by Ragaril, thank you!
EDIT2: small Update.
EDIT3: small Update. :P
EDIT4: there was a small typo in last Update. :-[

[attachment deleted by admin]

Wampus:
The numpad works fine. The joystick registers as expected but the gamepad controls work up to a point. One simple gamepad I have works perfectly but I also have a Logitech Dual Rumple Gamepad and all the controls work with that except the second analogue stick cannot be read as up or down. Left and right with RX- and RX+ can be read but not up and down with RY-, RY+, RZ- or RZ+ so that means can't be read at all! This isn't your routine though, its GLBasic. I suppose I should report it as a minor nuisance since the style of Gamepad I have, the type with two analogue sticks and one digital stick, is the most common for the PC.

Wampus:
Oh, I also can't get the buttons to register. I've tried SET(451) upwards SET(460) because my gamepad has 10 buttons and none of them were registering.

kanonet:
Thank you very much for your imput, Ragaril. :good:
There was one line of code missing... no idea how this happend... :'( Buttons should work now.
Too bad that there are problems with gamepads, if this is really 'cuz of GLB please let Kitty know about that. Can you please test if there are problems, if there is more than one joystick/gamepad in use?

----------------------------------


Updated code in first post; bugfix and new feature:
For one "key" you can now set two controls. Sometimes players like to switch between two setups.
You need two calls to define both [SET(1) and SET(2)] but both will get checked with one call of DOWN(). Look at code/comments for details.

Moru:
Very nice work! I'm just missing one thing, be able to detect when user just pressed a key, just relesed the key or keeps pressing a key and return the statuscode in the same way Gernots keyhit code.

//  0 = not pressed / nicht gedrückt
//  2 = just pressed / gerade runtergedrückt
//  1 = pressed / gedrückt (gehalten)
// -1 = release event / wieder losgelassen

See this post about how to do it:
http://www.glbasic.com/forum/index.php?topic=679.0

Navigation

[0] Message Index

[#] Next page

Go to full version