# globals $table = null table_height = 0 card_height = 0 state = null server_url = null top_card_z = 0 # css z-index of front-most card show_message = (txt) -> txt # FIXME implement chat box or something # timeout function with args in convenient order timeout = (ms, func) -> setTimeout func, ms unless Array::shuffle? Array::shuffle = -> return if @length is 0 top = @length while --top current = Math.floor(Math.random() * (top + 1)) tmp = @[current] @[current] = @[top] @[top] = tmp return new_button = (text) -> $ $ "
#{text}
" # transform coordinates from client-side coords to server-side coords (or back) # this makes it so p2 view everything upside down (mirrored), but still sends coords rightside up transform_x = (x) -> x transform_y = (y) -> return y unless state.agent is 'p2' return table_height - card_height - y next_card_z = -> return top_card_z += 1 bring_card_to_front = (card) -> card.view.css "z-index": next_card_z() instantiate_card = (card) -> text = card.text if card.owner is state.agent card_class = 'my_card' else card_class = 'your_card' view = $ $ "
#{text}
" button_box = $ $ '
' flip_button = new_button "flip over" mark_button = new_button "mark" flip_button.bind 'click', -> state.flip state.agent, card.number, ! view.hasClass 'flipped' mark_button.bind 'click', -> state.mark state.agent, card.number, ! view.hasClass 'marked' button_box.append flip_button button_box.append mark_button view.append button_box if card.marked view.addClass 'marked' if card.flipped view.addClass 'flipped' $table.append view view.draggable containment: '#table', grid: [20, 20] view.bind 'dragstart', (event, ui) -> view.css 'z-index': card.z = next_card_z() view.bind 'dragstop', (event, ui) -> p = view.position() state.move state.agent, card.number, transform_x(p.left), transform_y(p.top) card.view = view error_lag = 3 outgoing_messages = [] # message should be [agent, method, args...] # don't forget the agent (state.agent) tell_server = (message) -> outgoing_messages.push message send_updates() send_updates = -> return if outgoing_messages.length is 0 messages = outgoing_messages outgoing_messages = [] $.ajax "#{server_url}/set", { cache: false data: { agent: state.agent game: 'test' # FIXME, and it the /get call too messages: JSON.stringify(messages) } type: 'POST' dataType: 'json' error: (xhr, status, error) -> show_message "Network error while sending, you might want to refresh. Trying again in #{error_lag} seconds. (Status: #{status}, Error: #{error})" for message in messages outgoing_messages.unshift message timeout error_lag * 1000, send_updates error_lag *= 2 success: (data, status, xhr) -> show_message "update sent" error_lag = 3 } error_lag = 3 poll_for_updates = -> $.ajax "#{server_url}/get?agent=#{state.agent}&game=test", { cache: false type: 'GET' dataType: 'json' error: (xhr, status, error) -> message "Network error, you might want to refresh. Trying again in #{error_lag} seconds. (Status: #{status}, Error: #{error})" timeout error_lag * 1000, poll_for_updates error_lag *= 2 success: (data, status, xhr) -> state.process_messages data timeout 100, poll_for_updates error_lag = 3 } init = -> if window.location.hash? and window.location.hash.length > 0 me = window.location.hash.substr 1 winloc = "#{window.location}" server_url = winloc.substr 0, winloc.length - window.location.hash.length else me = 'p1' server_url = window.location state = window.game_model.new me state.on 'move', (agent, card, x, y) -> # FIXME add/handle pile argument if agent is me tell_server ['move', agent, card, x, y] else bring_card_to_front state.cards[card] state.cards[card].view.animate { left: "#{transform_x x}px", top: "#{transform_y y}px"}, 800 state.on 'mark', (agent, card, state) -> @cards[card].view.toggleClass 'marked', state if agent is me tell_server ['mark', agent, card, state] state.on 'flip', (agent, card, state) -> @cards[card].view.toggleClass 'flipped', state if agent is me tell_server ['flip', agent, card, state] state.on 'set_cards', (agent, cards) -> # FIXME add agent arg and tell server if it's not us $('.card').remove() for card in cards instantiate_card card if agent is me tell_server ['set_cards', agent, cards] # timeout so browser will stop showing that we're loading timeout 1, poll_for_updates timeout 2, -> # ask for initial state tell_server ['send_state', state.agent] $ -> $table = $ '#table' table_height = $table.height() card_height = $('#loading-card').outerHeight() init()