QB64.org Forum

Active Forums => Programs => Topic started by: SMcNeill on November 29, 2020, 12:37:58 pm

Title: User Customized Input
Post by: SMcNeill on November 29, 2020, 12:37:58 pm
We see a lot of people post little games around here.  We also see a lot of other people post things like "Can you change it so that I can use XXX key for (whatever), rather than what you have set?"

Here's the very simplest set of code I can think of to allow someone to set custom controls for a game:
Code: QB64: [Select]
  1. PRINT "Press the key you want to move UP   :";
  2. Up = SetKey: PRINT Up
  3. PRINT "Press the key you want to move LEFT :";
  4. Left = SetKey: PRINT Left
  5. PRINT "Press the key you want to move DOWN :";
  6. Down = SetKey: PRINT Down
  7. PRINT "Press the key you want to move RIGHT:";
  8. Right = SetKey: PRINT Right
  9.  
  10. HeroX = 20: HeroY = 20
  11.     CLS
  12.     LOCATE HeroY, HeroX: PRINT CHR$(1);
  13.     K = _KEYHIT
  14.     SELECT CASE K
  15.         CASE Up: HeroY = HeroY - 1 - (HeroY <= 1)
  16.         CASE Left: HeroX = HeroX - 1 - (HeroX <= 1)
  17.         CASE Down: HeroY = HeroY + 1 + (HeroY >= 25)
  18.         CASE Right: HeroX = HeroX + 1 + (HeroX >= 80)
  19.     END SELECT
  20.     _LIMIT 30
  21.     _DISPLAY
  22.  
  23.  
  24. FUNCTION SetKey
  25.     STATIC KeysInUse(1 TO 100) AS LONG
  26.     DO
  27.         SetKey = _KEYHIT
  28.         FOR i = 1 TO 100
  29.             IF KeysInUse(i) = SetKey THEN SetKey = 0 'Can't define the same key twice.
  30.             IF KeysInUse(i) = 0 THEN EXIT FOR
  31.         NEXT
  32.         IF i < 101 THEN KeysInUse(i) = SetKey
  33.         _LIMIT 30
  34.     LOOP UNTIL SetKey > 0
  35.  
  36.  

It really can be that simple of a process.  :)
Title: Re: User Customized Input
Post by: STxAxTIC on November 29, 2020, 01:11:52 pm
I like this. Some games, namely Portal 2 and Rage to name a few, ask you to "look up" right off the bat, so whatever your natural reflex is, that's "up" for now on, and so on. This is right in that spirit.
Title: Re: User Customized Input
Post by: SMcNeill on December 03, 2020, 05:21:32 pm
And here's a version which looks more like what my game has going for it:

Code: QB64: [Select]
  1. TYPE Control_Type
  2.     Label AS STRING
  3.     Value AS LONG
  4.     JoyStick AS LONG
  5. DIM SHARED Control(10) AS Control_Type
  6. Control(0).Label = "UP": Control(0).Value = 18432: Control(0).JoyStick = 1210000
  7. Control(1).Label = "DOWN": Control(1).Value = 20480: Control(1).JoyStick = 1220000
  8. Control(2).Label = "LEFT": Control(2).Value = 19200: Control(2).JoyStick = 1120000
  9. Control(3).Label = "RIGHT": Control(3).Value = 19712: Control(3).JoyStick = 1110000
  10. Control(4).Label = "SELECT": Control(4).Value = 8: Control(4).JoyStick = 1000000
  11. Control(5).Label = "TAB": Control(5).Value = 9: Control(5).JoyStick = 1000001
  12. Control(6).Label = "ENTER": Control(6).Value = 13: Control(6).JoyStick = 1000002
  13. Control(7).Label = "CANCEL": Control(7).Value = 27: Control(7).JoyStick = 1000003
  14.  
  15. SCREEN _NEWIMAGE(800, 600, 32) 'An initial screen for testing
  16. Settings
  17.  
  18. SCREEN _NEWIMAGE(640, 480, 32) 'And a second screen, so we can see that we scale to fit any environment properly
  19. Settings
  20.  
  21.  
  22.  
  23.  
  24.  
  25. SUB Settings
  26.     DIM BGC AS _UNSIGNED LONG, f AS LONG, BT AS LONG, D AS LONG, tempimage AS LONG
  27.     DIM ScaleX AS _FLOAT, ScaleY AS _FLOAT, cx AS _FLOAT
  28.     DIM BackUp(10) AS Control_Type
  29.     FOR i = 0 TO 10: BackUp(i) = Control(i): NEXT
  30.  
  31.     Dev = _DEVICES
  32.     LB = _LASTBUTTON(3): LA = _LASTAXIS(3)
  33.  
  34.  
  35.     f = _LOADFONT("courbd.ttf", 48, "monospace")
  36.     BGC = SkyBlue 'Background color
  37.     BT = _LOADIMAGE("marble.jpg", 32) ' Button Tile
  38.     D = _DEST
  39.     PCOPY D, 1
  40.  
  41.     tempimage = _NEWIMAGE(1280, 720, 32)
  42.     ScaleX = 1280 / _WIDTH(D): ScaleY = 720 / _HEIGHT(D)
  43.     Button = BoxImage(300, 50, 5, BT, Ivory)
  44.     Frame = BoxImage(300, 50, 5, 0, Red)
  45.  
  46.     _DEST tempimage
  47.     COLOR Black, 0
  48.     CLS , BGC
  49.     _FONT f
  50.     CenterLabel 200, 10, 300, 50, "Keyboard"
  51.     CenterLabel 600, 10, 300, 50, "JoyStick"
  52.     FOR i = 0 TO 10
  53.         _PRINTSTRING (190 - _PRINTWIDTH(Control(i).Label), 60 * i + 71), Control(i).Label
  54.         _PUTIMAGE (200, 60 * i + 70), Button
  55.         CenterLabel 200, 60 * i + 71, 300, 50, GetKeyName(Control(i).Value)
  56.         _PUTIMAGE (600, 60 * i + 70), Button
  57.         CenterLabel 600, 60 * i + 71, 300, 50, GetKeyName(Control(i).JoyStick)
  58.     NEXT
  59.  
  60.     Accept = BoxImage(200, 200, 5, Green, Ivory)
  61.     Cancel = BoxImage(200, 200, 5, Red, Ivory)
  62.     _PUTIMAGE (1000, 100), Accept, tempimage
  63.     _PUTIMAGE (1000, 400), Cancel, tempimage
  64.     CenterLabel 1000, 100, 200, 200, "OK"
  65.     CenterLabel 1000, 400, 200, 200, "Cancel"
  66.  
  67.     replace = -1: j = -1: OM = -1
  68.     DO
  69.         _PUTIMAGE , tempimage, D
  70.         k = _KEYHIT
  71.         WHILE _DEVICEINPUT(3): WEND
  72.         WHILE _MOUSEINPUT: WEND
  73.         MB = _MOUSEBUTTON(1)
  74.         IF MB AND NOT OM THEN
  75.             MX = _MOUSEX * ScaleX: MY = _MOUSEY * ScaleY
  76.             IF MX >= 1000 AND MX <= 1200 THEN
  77.                 SELECT CASE MY
  78.                     CASE 100 TO 300 'Accept
  79.                         EXIT DO
  80.                     CASE 400 TO 600 'Cancel
  81.                         FOR i = 0 TO 10: Control(i) = BackUp(i): NEXT
  82.                         EXIT DO
  83.                 END SELECT
  84.             END IF
  85.         END IF
  86.         OM = MB
  87.  
  88.  
  89.         IF k = 0 THEN
  90.             FOR i = 1 TO LB
  91.                 IF _BUTTON(i) THEN k = 999999 + i: EXIT FOR
  92.             NEXT
  93.             IF k = 0 THEN
  94.                 FOR i = 1 TO LA
  95.                     IF ABS(_AXIS(i)) > 0.25 THEN
  96.                         k = 1000000 + i * 100000
  97.                         IF _AXIS(i) > 0 THEN k = k + 10000 ELSE k = k + 20000
  98.                     END IF
  99.                 NEXT
  100.             END IF
  101.         END IF
  102.  
  103.         IF k > 0 AND k < 1000000 THEN
  104.             IF replace = -1 THEN
  105.                 FOR i = 0 TO 10
  106.                     IF Control(i).Value = k THEN
  107.                         replace = i
  108.                         _PUTIMAGE (200, 60 * i + 70), Button, tempimage
  109.                         _PUTIMAGE (200, 60 * i + 70), Frame, tempimage
  110.                         EXIT FOR
  111.                     END IF
  112.                 NEXT
  113.             ELSE
  114.                 FOR i = 0 TO 10
  115.                     IF Control(i).Value = k THEN EXIT FOR
  116.                 NEXT
  117.                 IF i > 10 THEN
  118.                     Control(replace).Value = k
  119.                     _PUTIMAGE (200, 60 * replace + 70), Button, tempimage
  120.                     CenterLabel 200, 60 * replace + 71, 300, 50, GetKeyName(k)
  121.                     replace = -1
  122.                 END IF
  123.             END IF
  124.         ELSEIF k > 999999 THEN
  125.             IF j = -1 THEN
  126.                 FOR i = 0 TO 10
  127.                     IF Control(i).JoyStick = k THEN
  128.                         j = i
  129.                         _PUTIMAGE (600, 60 * i + 70), Button, tempimage
  130.                         _PUTIMAGE (600, 60 * i + 70), Frame, tempimage
  131.                         EXIT FOR
  132.                     END IF
  133.                 NEXT
  134.             ELSEIF j >= 0 AND j <= 10 THEN
  135.                 FOR i = 0 TO 10
  136.                     IF Control(i).JoyStick = k THEN EXIT FOR
  137.                 NEXT
  138.                 IF i > 10 THEN
  139.                     Control(j).JoyStick = k
  140.                     _PUTIMAGE (600, 60 * j + 70), Button, tempimage
  141.                     CenterLabel 600, 60 * j + 71, 300, 50, GetKeyName(k)
  142.                     j = -1
  143.                     _DELAY .25
  144.                 END IF
  145.             END IF
  146.         END IF
  147.         _LIMIT 30
  148.         _DISPLAY
  149.     LOOP
  150.     PCOPY 1, D
  151.     _DEST D
  152.     _FREEIMAGE tempimage
  153.     _FREEIMAGE Accept
  154.     _FREEIMAGE Cancel
  155.     _FREEIMAGE Button
  156.     _FREEIMAGE Frame
  157.  
  158. FUNCTION BoxImage (wide&, tall&, thick&, BGcolor&&, FrameColor&&)
  159.     D = _DEST
  160.     BoxImage = _NEWIMAGE(wide&, tall&, 32)
  161.     _DEST BoxImage
  162.     IF BGcolor&& = -1 THEN BGcolor&& = 0
  163.     IF BGcolor&& < 0 THEN
  164.         _PUTIMAGE , BGcolor&&
  165.     ELSE
  166.         CLS , BGcolor&&
  167.     END IF
  168.     FOR i& = 0 TO thick& - 1
  169.         LINE (i&, i&)-STEP(wide& - i& * 2, tall& - i& * 2), FrameColor&&, B
  170.     NEXT
  171.     _DEST D
  172.  
  173. SUB CenterLabel (left&, top&, wide&, tall&, text$)
  174.     pw = _PRINTWIDTH(text$): fw = _FONTHEIGHT
  175.     bx = (wide& - pw) \ 2: by = (tall& - fw) \ 2
  176.     _PRINTSTRING (left& + bx, top& + by), text$
  177.  
  178.  
  179. FUNCTION GetKeyName$ (code)
  180.     SELECT CASE code
  181.         CASE 8: GetKeyName$ = "BKSP"
  182.         CASE 9: GetKeyName$ = "TAB"
  183.         CASE 13: GetKeyName$ = "ENTER"
  184.         CASE 27: GetKeyName$ = "ESC"
  185.         CASE 32: GetKeyName$ = "SPACE"
  186.         CASE 33 TO 255: GetKeyName$ = CHR$(code)
  187.         CASE 15104: GetKeyName$ = "F1"
  188.         CASE 15360: GetKeyName$ = "F2"
  189.         CASE 15616: GetKeyName$ = "F3"
  190.         CASE 15872: GetKeyName$ = "F4"
  191.         CASE 16128: GetKeyName$ = "F5"
  192.         CASE 16384: GetKeyName$ = "F6"
  193.         CASE 16640: GetKeyName$ = "F7"
  194.         CASE 16896: GetKeyName$ = "F8"
  195.         CASE 17152: GetKeyName$ = "F9"
  196.         CASE 17408: GetKeyName$ = "F10"
  197.         CASE 34048: GetKeyName$ = "F11"
  198.         CASE 34304: GetKeyName$ = "F12"
  199.         CASE 18432: GetKeyName$ = ""
  200.         CASE 19200: GetKeyName$ = ""
  201.         CASE 19712: GetKeyName$ = ""
  202.         CASE 20480: GetKeyName$ = ""
  203.  
  204.         CASE 18176: GetKeyName$ = "HOME"
  205.         CASE 18688: GetKeyName$ = "PG UP"
  206.         CASE 20224: GetKeyName$ = "END"
  207.         CASE 20736: GetKeyName$ = "PG DOWN"
  208.         CASE 20992: GetKeyName$ = "INS"
  209.         CASE 21248: GetKeyName$ = "DEL"
  210.  
  211.         CASE 100019: GetKeyName$ = "PAUSE"
  212.         CASE 100300: GetKeyName$ = "NUM LOCK"
  213.         CASE 100301: GetKeyName$ = "CAPS LOCK"
  214.         CASE 100302: GetKeyName$ = "SCROLL LOCK"
  215.         CASE 100303: GetKeyName$ = "R SHIFT"
  216.         CASE 100304: GetKeyName$ = "L SHIFT"
  217.         CASE 100305: GetKeyName$ = "R CTRL"
  218.         CASE 100306: GetKeyName$ = "L CTRL"
  219.         CASE 100307: GetKeyName$ = "R ALT"
  220.         CASE 100308: GetKeyName$ = "L ALT"
  221.         CASE 100309: GetKeyName$ = "L APPLE"
  222.         CASE 100310: GetKeyName$ = "R APPLE"
  223.         CASE 100311: GetKeyName$ = "R WIN"
  224.         CASE 100312: GetKeyName$ = "L WIN"
  225.         CASE 100316: GetKeyName$ = "SYSTEM"
  226.         CASE 100319: GetKeyName$ = "MENU"
  227.         CASE 1000000 TO 1000100
  228.             GetKeyName$ = "JB #" + _TRIM$(STR$(code - 999999))
  229.         CASE 1110000: GetKeyName$ = "AX 1+"
  230.         CASE 1120000: GetKeyName$ = "AX 1-"
  231.         CASE 1210000: GetKeyName$ = "AX 2+"
  232.         CASE 1220000: GetKeyName$ = "AX 2-"
  233.         CASE 1310000: GetKeyName$ = "AX 3+"
  234.         CASE 1320000: GetKeyName$ = "AX 3-"
  235.         CASE 1410000: GetKeyName$ = "AX 4+"
  236.         CASE 1420000: GetKeyName$ = "AX 4-"
  237.         CASE 1510000: GetKeyName$ = "AX 5+"
  238.         CASE 1520000: GetKeyName$ = "AX 5-"
  239.         CASE 1610000: GetKeyName$ = "AX 6+"
  240.         CASE 1620000: GetKeyName$ = "AX 6-"
  241.         CASE 1710000: GetKeyName$ = "AX 7+"
  242.         CASE 1720000: GetKeyName$ = "AX 7-"
  243.  
  244.     END SELECT

  [ This attachment cannot be displayed inline in 'Print Page' view ]