JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Piles display and removing cards mostly working
authorJason Woofenden <jason@jasonwoof.com>
Wed, 2 Nov 2011 20:56:47 +0000 (16:56 -0400)
committerJason Woofenden <jason@jasonwoof.com>
Wed, 2 Nov 2011 22:23:35 +0000 (18:23 -0400)
(except that they don't all display in the right place/orientation)

client.coffee
common.coffee
server.coffee

index da53a24..f47f0a1 100644 (file)
@@ -5,10 +5,14 @@ card_height = 0
 state = null
 server_url = null
 top_card_z = 0 # css z-index of front-most card
-$pile_captions = {}
+piles = null
 
-show_message = (txt) -> txt
-       # FIXME implement chat box or something
+window.log = []
+show_message = (txt) ->
+       window.log.push txt
+       if window.log.length > 20
+               window.log.shift()
+       return
 
 # timeout function with args in convenient order
 timeout = (ms, func) -> setTimeout func, ms
@@ -45,23 +49,27 @@ new_blank_card = (x, y) ->
        $table.append view
        return view
 
+uninstantiate_card = (card) ->
+       show_message "uninstantiate card #{card.number}"
+       card.view.remove()
+       delete card.view
+
 instantiate_card = (card) ->
+       show_message "instantiate card #{card.number}"
+       if card.view
+               die.a.horrible.death()
+
        text = card.text
        if card.owner is state.agent
                card_class = 'my_card'
        else
                card_class = 'your_card'
 
-       # initial card state from server has z so that stacks come out with the right layers
-       if card.z?
-               if card.z > top_card_z
-                       top_card_z = card.z
-       else
-               unless card.pile
-                       card.z = next_card_z()
+       if card.z > top_card_z
+               top_card_z = card.z
 
        view = $ $ "<div class=\"card #{card_class}\" style=\"left: #{transform_x(card.x)}px; top: #{transform_y(card.y)}px; z-index: #{card.z}\"><span class=\"cardtext\">#{text}</span></div>"
-       view.data card.number
+       card.view = view
        button_box = $ $ '<div/>'
        flip_button = new_button "flip over"
        mark_button = new_button "mark"
@@ -80,10 +88,13 @@ instantiate_card = (card) ->
        view.draggable containment: '#table', grid: [20, 20]
        view.bind 'dragstart', (event, ui) ->
                view.css 'z-index': card.z = next_card_z()
+               if card.pile?
+                       delete card.pile
+               update_pile_views()
        view.bind 'dragstop', (event, ui) ->
                p = view.position()
-               state.move state.agent, card.number, transform_x(p.left), transform_y(p.top), card.z
-       card.view = view
+               pile = null # FIXME figure out what pile we moved to
+               state.move state.agent, card.number, transform_x(p.left), transform_y(p.top), card.z, pile
 
 error_lag = 3
 
@@ -104,7 +115,7 @@ send_updates = ->
                cache: false
                data: {
                        agent: state.agent
-                       game: 'test' # FIXME, and it the /get call too
+                       game: 'test' # FIXME, and in the /get call too
                        messages: JSON.stringify(messages)
                }
                type: 'POST'
@@ -127,7 +138,7 @@ poll_for_updates = ->
                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})"
+                       show_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) ->
@@ -141,51 +152,60 @@ n_cards = (count) ->
        return "1 card"
 
 initialize_cards = () ->
-       # clear everything
+       show_message 'initialize_cards'
        $('.card').remove()
-       $('.blank_card').remove()
-
+       top_card_z = 0
        # instantiate cards in play
        for card in state.cards
-               instantiate_card card unless card.pile
-
-       # build piles
-       piles = [
-               {key: 'p2_draw', x: transform_x(140), y: transform_y(20), name: "Draw Pile"}
-               {key: 'p2_discard', x: transform_x(20), y: transform_y(20), name: "Discard Pile"}
-               {key: 'p1_draw', x: transform_x(140), y: transform_y(flip_y(20)), name: "Draw Pile"}
-               {key: 'p1_discard', x: transform_x(20), y: transform_y(flip_y(20)), name: "Discard Pile"}
-       ]
-       for pile in piles
-               manage_pile = (pile) ->
+               delete card.view
+               instantiate_card card unless card.pile?
+
+       unless piles?
+               piles = [ # global
+                       {key: 'p2_draw', x: transform_x(140), y: transform_y(20), name: "Draw Pile"}
+                       {key: 'p2_discard', x: transform_x(20), y: transform_y(20), name: "Discard Pile"}
+                       {key: 'p1_draw', x: transform_x(140), y: transform_y(flip_y(20)), name: "Draw Pile"}
+                       {key: 'p1_discard', x: transform_x(20), y: transform_y(flip_y(20)), name: "Discard Pile"}
+               ]
+               for pile in piles
                        pile.$blank = new_blank_card pile.x, pile.y
-                       count = 0
-                       top = null
-                       if state.piles[pile.key]?.length
-                               count = state.piles[pile.key].length
-                               top = state.piles[pile.key][0]
-                       $caption = $ $ "<div class=\"pile_caption\"><div>#{pile.name}:</div><div class=\"n_cards\">#{n_cards count}</div></div>"
-                       pile.$caption = $caption
-                       if top?
-                               top.x = pile.x
-                               top.y = pile.y
-                               instantiate_card top
-                               view = top.view
-                       else
-                               view = pile.$blank
+                       pile.$caption = $ $ "<div class=\"pile_caption\"><div>#{pile.name}:</div><div class=\"n_cards\">#{n_cards 0}</div></div>"
+
+       update_pile_views()
 
-                       view.append $caption
+update_pile_views = ->
+       ps = {}
+       for card in state.cards
+               if card.pile?
+                       if ps[card.pile]?
+                               ps[card.pile].total += 1
+                               if card.z > ps[card.pile].top_z
+                                       if ps[card.pile].top_card.view?
+                                               uninstantiate_card ps[card.pile].top_card
+                                       ps[card.pile].top_card = card
+                                       ps[card.pile].top_z = card.z
+                       else
+                               ps[card.pile] = { total: 1, top_card: card, top_z: card.z }
 
-                       if top?
-                               pile.drag_handler = view.bind 'dragstart', ->
-                                       pile.$caption.remove()
-                                       delete top.pile
-                                       state.piles[pile.key].shift()
-                                       manage_pile pile
-                                       # FIXME make sure this state change is sent
-                                       # FIXME handle this message coming in
+       for pile in piles
+               # where should the caption be?
+               if ps[pile.key]?
+                       unless ps[pile.key].top_card.view?
+                               ps[pile.key].top_card.x = pile.x
+                               ps[pile.key].top_card.y = pile.y
+                               instantiate_card ps[pile.key].top_card
+                       caption_dest = ps[pile.key].top_card.view
+               else
+                       caption_dest = pile.$blank
+               if caption_dest isnt pile.caption_loc
+                       pile.$caption.detach()
+                       caption_dest.append pile.$caption
+                       pile.caption_loc = caption_dest
 
-               manage_pile pile
+               # update caption to show correct number of cards in the pile
+               card_count = 0
+               card_count = ps[pile.key].total if ps[pile.key]?
+               pile.$caption.children('.n_cards').html n_cards card_count
 
 
 init = ->
@@ -198,10 +218,10 @@ init = ->
                server_url = window.location
 
        state = window.game_model.new me
-       state.on 'move', (agent, card, x, y, z) ->
-               # FIXME add/handle pile argument
+       state.on 'move', (agent, card, x, y, z, pile) ->
+               update_pile_views()
                if agent is me
-                       tell_server ['move', agent, card, x, y, z]
+                       tell_server ['move', agent, card, x, y, z, pile]
                else
                        # FIXME should we use the z from the server? Should p1 use odd numbers and p2 even?
                        bring_card_to_front state.cards[card]
index 3cf6867..d2667ac 100644 (file)
@@ -12,7 +12,6 @@ class GameState
                @agent = agent
                @hooks = {}
                @cards = []
-               @piles = {}
        on: (event, callback) ->
                unless @hooks[event]?
                        @hooks[event] = []
@@ -21,17 +20,19 @@ class GameState
                return unless @hooks[event]?
                for callback in @hooks[event]
                        callback.apply this, args
-       move: (agent, card, x, y, z) -> # FIXME add pile argument
+       move: (agent, card, x, y, z, pile) ->
                # FIXME what to do on error?
-               return unless @cards[card]? #?.pile?
-               #cur_pile = cards[card].pile
-               #if pile isnt cur_pile
+               return unless @cards[card]?
 
                @cards[card].x = x
                @cards[card].y = y
                @cards[card].z = z
+               if pile?
+                       @cards[card].pile = pile
+               else if @cards[card].pile?
+                       delete @cards[card].pile
 
-               @trigger 'move', agent, card, x, y, z # FIXME add pile argument
+               @trigger 'move', agent, card, x, y, z, pile
 
        mark: (agent, card, state) ->
                # FIXME what to do on error?
@@ -49,14 +50,10 @@ class GameState
 
        set_cards: (agent, cards) ->
                @cards = []
-               @piles = {}
                for card in cards
-                       card.number = @cards.length
+                       card.number = @cards.length unless card.number
+                       card.z = @cards.length unless card.z
                        @cards.push card
-                       if card.pile?
-                               unless @piles[card.pile]?
-                                       @piles[card.pile] = []
-                               @piles[card.pile].push card
                @trigger 'set_cards', agent, @cards
 
        send_state: (agent) ->
index 4ae7fe7..089523a 100644 (file)
@@ -182,7 +182,7 @@ new_game = (id) ->
 
 test_init = ->
        test_game = new_game 'test'
-       timeout 4000, ->
+       timeout 2, ->
                test_game.set_cards 'server', [
                        { text: "Wildabeast 2/2", x: 220, y: 200, owner: 'p2'}
                        { text: "Boar 2/2", x: 360, y: 200, owner: 'p2', pile: 'p2_discard'}