1 require 'observer_utils'
3 require 'board/pool_animator'
10 def initialize(scene, elements, game, history)
12 @board = elements[:board]
13 @pools = elements[:pools]
17 @animator = @game.animator.new(@board)
18 @field = AnimationField.new(20)
19 @board.reset(history.state.board)
22 @board.observe(:click) {|p| c.on_board_click(p) }
23 @board.observe(:drag) {|data| c.on_board_drag(data) }
24 @board.observe(:drop) {|data| c.on_board_drop(data) }
25 @pools.each do |color, pool|
26 pool.observe(:drag) {|data| c.on_pool_drag(color, data) }
27 pool.observe(:drop) {|data| c.on_pool_drop(color, data) }
32 state = @history.state
34 move = @game.policy.new_move(state, @board.selection, p)
35 validate = @game.validator.new(state)
40 @board.selection = nil
41 elsif @game.policy.movable?(state, p) and movable?(p)
46 def perform!(move, opts = {})
47 state = @history.state.dup
49 @history.add_move(state, move)
50 animate(:forward, state, move, opts)
51 @board.highlight(move)
55 state, move = @history.back
56 animate(:back, state, move)
57 @board.highlight(@history.move)
58 rescue History::OutOfBound
59 puts "error: first move"
63 state, move = @history.forward
64 animate(:forward, state, move)
65 @board.highlight(move)
66 rescue History::OutOfBound
67 puts "error: last move"
70 def animate(direction, state, move, opts = {})
71 anim = @animator.send(direction, state, move, opts)
78 @pools.each do |color, pool|
79 anim = pool.animator.warp(@history.state.pool(color))
84 def on_board_drop(data)
88 if data[:src] == data[:dst]
89 @board.selection = data[:src]
92 move = @game.policy.new_move(@history.state, data[:src], data[:dst])
93 validate = @game.validator.new(@history.state)
97 if move and move.valid?
98 @board.add_to_group data[:item]
99 @board.lower data[:item]
100 perform! move, :adjust => true
104 elsif data[:index] and data[:dst]
106 move = @game.policy.new_move(@history.state, nil,
107 data[:dst], :dropped => data[:item].name)
108 validate = @game.validator.new(@history.state)
110 @board.add_to_group data[:item]
111 @board.lower data[:item]
112 perform! move, :dropped => data[:item]
119 def on_board_drag(data)
120 if @game.policy.movable?(@history.state, data[:src]) and
122 @board.raise data[:item]
123 @board.remove_from_group data[:item]
124 @board.selection = nil
129 def on_pool_drag(color, data)
130 if @game.policy.droppable?(@history.state, color, data[:index]) and
131 droppable?(color, data[:index])
133 # replace item with a correctly sized one
134 item = @board.create_piece(data[:item].name)
136 @board.remove_from_group item
137 anim = @pools[color].animator.remove_piece(data[:index])
139 data[:size] = @board.unit
140 data[:pool_color] = color
148 def on_pool_drop(color, data)
152 def cancel_drop(data)
153 anim = if data[:index]
154 # remove dragged item
156 # make original item reappear in its place
157 @pools[data[:pool_color]].animator.insert_piece(
161 @board.add_to_group data[:item]
162 @board.lower data[:item]
163 @animator.movement(data[:item], nil, data[:src], Path::Linear)
166 @field.run(anim) if anim
173 def droppable?(color, index)