game.coffee 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. URL = 'ws://localhost:8099'
  2. PLAYER_COLORS = ['blue', 'green', 'red', 'yellow']
  3. WALL_NONE = 0
  4. WALL_TOP = 1
  5. WALL_RIGHT = 2
  6. WALL_BOTTOM = 4
  7. WALL_LEFT = 8
  8. WALL_ALL = WALL_TOP | WALL_RIGHT | WALL_BOTTOM | WALL_LEFT
  9. div = (cls) ->
  10. elem = document.createElement 'div'
  11. elem.className = cls
  12. elem
  13. divin = (parent, cls) ->
  14. elem = div cls
  15. parent.appendChild elem
  16. elem
  17. class Board
  18. constructor: (@w, @h, elem) ->
  19. @render elem if elem
  20. get_wall: (x, y, direction) ->
  21. x *= 2
  22. y *= 2
  23. if direction == WALL_TOP
  24. x += 1
  25. else if direction == WALL_RIGHT
  26. x += 2
  27. y += 1
  28. else if direction == WALL_BOTTOM
  29. x += 1
  30. y += 2
  31. else if direction == WALL_LEFT
  32. y += 1
  33. @board.children[y].children[x]
  34. click_wall: (x, y, direction) ->
  35. wall = @get_wall x, y, direction
  36. wall.className += ' clicked'
  37. get_room: (x, y) ->
  38. @board.children[y * 2 + 1].children[x * 2 + 1]
  39. occupy: (x, y, player) ->
  40. room = @get_room x, y
  41. room.style.backgroundColor = PLAYER_COLORS[player]
  42. render: (elem) ->
  43. @board = div 'board'
  44. elem.appendChild @board
  45. row = divin @board, 'row'
  46. for x in [1..@w]
  47. divin row, 'dot'
  48. divin row, 'wall-h clicked'
  49. divin row, 'dot'
  50. for y in [1..@h]
  51. row = divin @board, 'row'
  52. for x in [1..@w]
  53. clicked = if x == 1 then ' clicked' else ''
  54. divin row, "wall-v#{clicked}"
  55. divin row, 'room'
  56. divin row, 'wall-v clicked'
  57. row = divin @board, 'row'
  58. clicked = if y == @h then ' clicked' else ''
  59. for x in [1..@w]
  60. divin row, 'dot'
  61. divin row, "wall-h#{clicked}"
  62. divin row, 'dot'
  63. destroy: ->
  64. @board.parentNode.removeChild @board
  65. show_error = alert
  66. set_this_player = (id) ->
  67. add_other_player = (id) ->
  68. remove_other_player = (id) ->
  69. set_turn_player = (id) ->
  70. finish = (scores) ->
  71. console.log 'scores:', scores
  72. ws = new WebSocket URL
  73. ws.send_msg = (mtype, args...) ->
  74. @send [mtype].concat(args).join ';'
  75. ws.onopen = ->
  76. console.debug 'open'
  77. if location.hash
  78. @send_msg 'join', location.hash.substr 1
  79. else
  80. @send_msg 'newgame', 5, 6
  81. ws.onclose = ->
  82. console.debug 'close'
  83. @board?.destroy()
  84. ws.onerror = (e) ->
  85. console.debug 'error', e
  86. ws.onmessage = (msg) ->
  87. [mtype, args...] = msg.data.split ';'
  88. args = ((if s.match /^\d+$/ then parseInt s else s) for s in args)
  89. console.debug 'msg:', mtype, args
  90. switch mtype
  91. when 'newgame'
  92. [@sid, w, h, player] = args
  93. @board = new Board w, h
  94. @board.render document.getElementById 'board'
  95. location.hash = @sid
  96. set_this_player player
  97. when 'join'
  98. add_other_player args[0]
  99. when 'leave'
  100. remove_other_player args[0]
  101. when 'clickwall'
  102. [x, y, direction] = args
  103. @board.click_wall x, y, direction
  104. when 'occupy'
  105. [x, y, player] = args
  106. @board.occupy x, y, player
  107. when 'turn'
  108. set_turn_player args[0]
  109. when 'finish'
  110. finish (s.split(':').map parseInt for s in args)
  111. when 'error'
  112. error = args[0]
  113. if error == 'no such session'
  114. @send_msg 'newgame', 5, 6
  115. else
  116. show_error error
  117. else
  118. show_error 'received invalid message from server'