2D Run-and-gun shooter inspired by One Man's Doomsday, Counter-Strike, and Metal Slug.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. const stringifyData = async value => {
  2. const isString = typeof value === 'string'
  3. const resolve = () => (
  4. isString
  5. ? Promise.resolve(value)
  6. : value.arrayBuffer()
  7. )
  8. const a = await resolve()
  9. if (isString) {
  10. return `String:${a.length}(${a})`
  11. }
  12. const bytes = Array.from(new Uint8Array(a)).map(c => Number(c).toString(16).padStart(2, '0')).join(' ')
  13. return `Binary:${a.byteLength}(${bytes})`
  14. }
  15. function ConnectionForm(el) {
  16. let ws = null
  17. el.addEventListener('submit', e => {
  18. e.preventDefault()
  19. if (!ws) {
  20. const username = el.elements['username'].value
  21. const baseUrl = el.elements['serverUrl'].value
  22. ws = new WebSocket(`${baseUrl}?username=${username}`)
  23. ws.addEventListener('open', () => {
  24. this.messageForm.enable()
  25. this.logsForm.append('Connection opened')
  26. el.elements['serverUrl'].setAttribute('disabled', 'disabled')
  27. el.elements['username'].setAttribute('disabled', 'disabled')
  28. el.elements['connect'].innerText = 'Disconnect'
  29. })
  30. ws.addEventListener('message', evt => {
  31. stringifyData(evt.data).then(value => {
  32. this.logsForm.append(`Recv: ${value}`)
  33. })
  34. })
  35. ws.addEventListener('error', evt => {
  36. console.error(evt)
  37. })
  38. ws.addEventListener('close', event => {
  39. this.messageForm.reset()
  40. this.messageForm.disable()
  41. this.logsForm.append(`Connection closed: wasClean: ${event.wasClean}, evCode: ${event.code}`)
  42. el.elements['serverUrl'].removeAttribute('disabled')
  43. el.elements['username'].removeAttribute('disabled')
  44. el.elements['connect'].innerText = 'Connect'
  45. ws = null
  46. })
  47. return
  48. }
  49. ws.close()
  50. })
  51. this.send = value => {
  52. if (!ws) {
  53. return
  54. }
  55. stringifyData(value).then(v => {
  56. this.logsForm.append(`Send: ${v}`)
  57. ws.send(value)
  58. })
  59. }
  60. }
  61. function MessageForm(el) {
  62. const inputMessage = el.elements['message']
  63. const binary = el.elements['binary']
  64. inputMessage.addEventListener('keydown', e => {
  65. if (e.key !== 'Shift') {
  66. return;
  67. }
  68. binary.checked = true;
  69. });
  70. inputMessage.addEventListener('keyup', e => {
  71. if (e.key !== 'Shift') {
  72. return;
  73. }
  74. binary.checked = false;
  75. });
  76. el.addEventListener('submit', e => {
  77. e.preventDefault()
  78. if (inputMessage.value.length < 1) {
  79. return
  80. }
  81. this.connectionForm.send(
  82. binary.checked
  83. ? new Blob(inputMessage.value.split(''))
  84. : inputMessage.value,
  85. );
  86. inputMessage.value = ''
  87. inputMessage.focus()
  88. })
  89. el.elements['submitBinary'].addEventListener('click', e => {
  90. e.preventDefault()
  91. if (inputMessage.value.length < 1) {
  92. return
  93. }
  94. this.connectionForm.send(new Blob(inputMessage.value.split('')))
  95. inputMessage.value = ''
  96. inputMessage.focus()
  97. })
  98. this.reset = () => {
  99. inputMessage.value = ''
  100. }
  101. this.enable = () => {
  102. el.elements['fieldset'].removeAttribute('disabled')
  103. }
  104. this.disable = () => {
  105. el.elements['fieldset'].setAttribute('disabled', 'disabled')
  106. }
  107. }
  108. function LogsForm(el) {
  109. let logs = el.elements['logs']
  110. el.addEventListener('submit', e => {
  111. e.preventDefault()
  112. logs.value = ''
  113. })
  114. this.append = data => {
  115. logs.value += data + '\n'
  116. logs.scrollTop = logs.scrollHeight
  117. }
  118. }
  119. const logsForm = new LogsForm(window.document.getElementById('formLogs'))
  120. const messageForm = new MessageForm(window.document.getElementById('formMessage'))
  121. const connectionForm = new ConnectionForm(window.document.getElementById('formConnection'))
  122. connectionForm.logsForm = logsForm
  123. connectionForm.messageForm = messageForm
  124. messageForm.connectionForm = connectionForm