Keystroke overlay

Keys overlay for game inputs in TankTrouble

目前为 2024-01-09 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Keystroke overlay
  3. // @author commander
  4. // @description Keys overlay for game inputs in TankTrouble
  5. // @namespace https://github.com/asger-finding/tanktrouble-userscripts
  6. // @version 0.0.3
  7. // @license GPL-3.0
  8. // @match *://*.tanktrouble.com/*
  9. // @exclude *://classic.tanktrouble.com/
  10. // @run-at document-idle
  11. // @grant GM_addStyle
  12. // @noframes
  13. // ==/UserScript==
  14.  
  15. GM_addStyle(`
  16. @import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@700&display=swap&text=%E2%86%91%E2%86%93%E2%86%90%E2%86%92_');
  17. .keystrokes-hold {
  18. transform: skewX(-6deg);
  19. display: grid;
  20. grid-template: "shoot up ." "left down right";
  21. position: fixed;
  22. user-select: none;
  23. column-gap: 0.25rem;
  24. row-gap: 0.25rem;
  25. bottom: 8px;
  26. right: 7px;
  27. z-index: 2147483647;
  28. }
  29. #keystrokes-arrowKeys.keystrokes-hold {
  30. grid-template: ". . up ." "shoot left down right" auto / 120px;
  31. }
  32. .keystrokes-hold .key {
  33. background: #ececec;
  34. color: #6e6e6e;
  35. font-family: 'Source Code Pro', monospace;
  36. font-size: 1.875rem;
  37. font-weight: bold;
  38. border: 1.5px solid #aaaaaa;
  39. border-radius: 5px;
  40. display: flex;
  41. justify-content: center;
  42. min-width: 2.5rem;
  43. min-height: 2.5rem;
  44. }
  45. #keystrokes-arrowKeys.keystrokes-hold .key {
  46. min-height: calc(2.5rem - 5px);
  47. padding-bottom: 5px;
  48. }
  49. .keystrokes-hold .key-up { grid-area: up; }
  50. .keystrokes-hold .key-left { grid-area: left; }
  51. .keystrokes-hold .key-down { grid-area: down; }
  52. .keystrokes-hold .key-right { grid-area: right; }
  53. .keystrokes-hold .key-shoot { grid-area: shoot; }
  54. .keystrokes-hold .key.active {
  55. background-color: #d2d2d2;
  56. color: #232323;
  57. }
  58. `);
  59.  
  60. const keycodes = {};
  61.  
  62. /**
  63. * Create HTML elements for the input overlays
  64. * from all keyboard input entries
  65. */
  66. const createInputOverlays = () => {
  67. const order = ['up', 'down', 'left', 'right', 'shoot'];
  68.  
  69. // Character dictonary for special characters
  70. const characterDict = {
  71. // Arrow up
  72. 38: '↑',
  73.  
  74. // Arrow down
  75. 40: '↓',
  76.  
  77. // Arrow left
  78. 37: '←',
  79.  
  80. // Arrow right
  81. 39: '→',
  82.  
  83. // Space
  84. 32: '_'
  85. };
  86.  
  87. /**
  88. * Create an input overlay element from an input set and append it to body
  89. * @param inputSetId Identifier for the input set
  90. * @param input Input details and keycodes
  91. */
  92. const createKeys = (inputSetId, input) => {
  93. const keysWrapper = $(`<div id="keystrokes-${ inputSetId }" class="keystrokes-hold"></div>`);
  94.  
  95. const keys = Object.values(input.data).map((key, index) => {
  96. let character = String.fromCharCode(key);
  97. if (!/[a-zA-Z]/u.test(character) && key in characterDict) character = characterDict[key];
  98.  
  99. const element = $(`<div class="key key-${ order[index] }">${character}</div>`);
  100.  
  101. keycodes[key] = element;
  102.  
  103. return element;
  104. });
  105. keysWrapper.append(keys);
  106. keysWrapper.hide();
  107.  
  108. $(document.documentElement).append(keysWrapper);
  109. };
  110.  
  111. for (const [inputSetId, input] of Object.entries(Inputs._inputSets)) {
  112. const { type } = input;
  113. if (type === 'keyboard') createKeys(inputSetId, input);
  114. }
  115. };
  116.  
  117. Inputs._inputSetsInUse = new Proxy(Inputs._inputSetsInUse, {
  118. set(target, key, value) {
  119. target[key] = value;
  120.  
  121. $('.keystrokes-hold').hide();
  122. let [priority] = Object.keys(target);
  123. if (priority === 'mouse') [, priority] = Object.keys(target);
  124. if (priority) $(`#keystrokes-${ priority}`).show();
  125. },
  126. deleteProperty(target, key) {
  127. const result = delete target[key];
  128. if (!Object.keys(target).length) $('.keystrokes-hold').hide();
  129.  
  130. return result;
  131. }
  132. });
  133.  
  134. document.addEventListener('keydown', ({ keyCode }) => GameManager.getGame()?.input.enabled && keycodes[keyCode]?.addClass('active'));
  135. document.addEventListener('keyup', ({ keyCode }) => keycodes[keyCode]?.removeClass('active'));
  136.  
  137. createInputOverlays();