OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** Base class for all views. */ | 5 /** Base class for all views. */ |
6 class View { | 6 class View { |
7 Document doc; | 7 Document doc; |
8 View(this.doc) {} | 8 View(this.doc) {} |
9 } | 9 } |
10 | 10 |
11 /** The view displayed to the player for its own grid. */ | 11 /** The view displayed to the player for its own grid. */ |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 PlayerState this.state, Element rootNode) | 83 PlayerState this.state, Element rootNode) |
84 : super(rootNode.document), _rootNode = rootNode {} | 84 : super(rootNode.document), _rootNode = rootNode {} |
85 | 85 |
86 void attach() { | 86 void attach() { |
87 _rootNode.on.mouseDown.add(handleMouseDown); | 87 _rootNode.on.mouseDown.add(handleMouseDown); |
88 _rootNode.on.mouseUp.add(handleMouseUp); | 88 _rootNode.on.mouseUp.add(handleMouseUp); |
89 } | 89 } |
90 | 90 |
91 void handleMouseDown(e) { | 91 void handleMouseDown(e) { |
92 e.preventDefault(); | 92 e.preventDefault(); |
93 ViewUtil.positionFromEvent(_rootNode, e).then((List<int> pos) { | 93 window.requestMeasurementFrame(() { |
94 final pos = ViewUtil.positionFromEvent(_rootNode, e); | |
94 _boatStartX = pos[0]; | 95 _boatStartX = pos[0]; |
95 _boatStartY = pos[1]; | 96 _boatStartY = pos[1]; |
96 // error case when the mouse was released out of the boat-placing area | 97 return () { |
Siggi Cherem (dart-lang)
2012/01/23 01:16:39
overall feels good to chunk everthing in phases (m
nweiz
2012/01/24 00:23:49
I like the idea of using futures. The syntax witho
| |
97 if (_moveListener != null) { | 98 // error case when the mouse was released out of the boat-placing area |
98 _rootNode.on.mouseMove.remove(_moveListener, false); | 99 if (_moveListener != null) { |
99 _possibleBoat.remove(); | 100 _rootNode.on.mouseMove.remove(_moveListener, false); |
100 _moveListener = null; | 101 _possibleBoat.remove(); |
101 } | 102 _moveListener = null; |
102 _possibleBoat = ViewUtil.createDiv("icons boat2"); | 103 } |
103 ViewUtil.placeNodeAt(_possibleBoat, _boatStartX, _boatStartY); | 104 _possibleBoat = ViewUtil.createDiv("icons boat2"); |
104 _rootNode.nodes.add(_possibleBoat); | 105 ViewUtil.placeNodeAt(_possibleBoat, _boatStartX, _boatStartY); |
105 _moveListener = handleMouseMove; | 106 _rootNode.nodes.add(_possibleBoat); |
106 _rootNode.on.mouseMove.add(_moveListener); | 107 _moveListener = handleMouseMove; |
108 _rootNode.on.mouseMove.add(_moveListener); | |
109 }; | |
107 }); | 110 }); |
108 } | 111 } |
109 | 112 |
110 void handleMouseMove(e) { | 113 void handleMouseMove(e) { |
111 e.preventDefault(); | 114 e.preventDefault(); |
112 ViewUtil.positionFromEvent(_rootNode, e).then((List<int> pos) { | 115 window.requestMeasurementFrame(() { |
116 final pos = ViewUtil.positionFromEvent(_rootNode, e); | |
113 if (_boatLastX == pos[0] && _boatLastY == pos[1]) { | 117 if (_boatLastX == pos[0] && _boatLastY == pos[1]) { |
114 return; | 118 return; |
115 } | 119 } |
116 _boatLastX = pos[0]; | 120 _boatLastX = pos[0]; |
117 _boatLastY = pos[1]; | 121 _boatLastY = pos[1]; |
118 int deltaX = _boatLastX - _boatStartX; | 122 int deltaX = _boatLastX - _boatStartX; |
119 int deltaY = _boatLastY - _boatStartY; | 123 int deltaY = _boatLastY - _boatStartY; |
120 | 124 |
121 String dir; | 125 String dir; |
122 bool flip = false; | 126 bool flip = false; |
123 int boatSize = 2; | 127 int boatSize = 2; |
124 if (deltaX.abs() >= deltaY.abs()) { | 128 if (deltaX.abs() >= deltaY.abs()) { |
125 dir = deltaX < 0 ? "right" : "left"; | 129 dir = deltaX < 0 ? "right" : "left"; |
126 boatSize = Math.max(2, Math.min(5, deltaX.abs() + 1)); | 130 boatSize = Math.max(2, Math.min(5, deltaX.abs() + 1)); |
127 } else { | 131 } else { |
128 dir = deltaY < 0 ? "up" : "down"; | 132 dir = deltaY < 0 ? "up" : "down"; |
129 boatSize = Math.max(2, Math.min(5, deltaY.abs() + 1)); | 133 boatSize = Math.max(2, Math.min(5, deltaY.abs() + 1)); |
130 } | 134 } |
131 | 135 |
132 _possibleBoat.attributes["class"] = "icons boat${boatSize} boatdir-${dir}" ; | 136 return () { |
137 _possibleBoat.attributes["class"] = | |
138 "icons boat${boatSize} boatdir-${dir}"; | |
139 }; | |
133 }); | 140 }); |
134 } | 141 } |
135 | 142 |
136 /** Handle end of positioning of a boat. */ | 143 /** Handle end of positioning of a boat. */ |
137 void handleMouseUp(e) { | 144 void handleMouseUp(e) { |
138 _rootNode.on.mouseMove.remove(_moveListener, false); | 145 _rootNode.on.mouseMove.remove(_moveListener, false); |
139 _moveListener = null; | 146 _moveListener = null; |
140 ViewUtil.positionFromEvent(_rootNode, e).then((List<int> pos) { | 147 window.requestMeasurementFrame(() { |
148 final pos = ViewUtil.positionFromEvent(_rootNode, e); | |
141 int _boatEndX = pos[0]; | 149 int _boatEndX = pos[0]; |
142 int _boatEndY = pos[1]; | 150 int _boatEndY = pos[1]; |
143 | 151 |
144 int deltaX = _boatEndX - _boatStartX; | 152 int deltaX = _boatEndX - _boatStartX; |
145 int deltaY = _boatEndY - _boatStartY; | 153 int deltaY = _boatEndY - _boatStartY; |
146 Boat boat; | 154 return () { |
155 Boat boat; | |
156 if (deltaX.abs() >= deltaY.abs()) { | |
157 int boatSize = Math.max(2, Math.min(5, deltaX.abs() + 1)); | |
158 boat = new Boat(deltaX < 0 ? (_boatStartX - boatSize + 1) : _boatStart X, | |
Siggi Cherem (dart-lang)
2012/01/23 01:16:39
80 col
| |
159 _boatStartY, true, boatSize); | |
160 } else { | |
161 int boatSize = Math.max(2, Math.min(5, deltaY.abs() + 1)); | |
162 boat = new Boat(_boatStartX, | |
163 deltaY < 0 ? (_boatStartY - boatSize + 1) : _boatStartY, | |
164 false, boatSize); | |
165 } | |
147 | 166 |
148 if (deltaX.abs() >= deltaY.abs()) { | 167 state.addBoat(boat); |
149 int boatSize = Math.max(2, Math.min(5, deltaX.abs() + 1)); | 168 }; |
150 boat = new Boat(deltaX < 0 ? (_boatStartX - boatSize + 1) : _boatStartX, | |
151 _boatStartY, true, boatSize); | |
152 } else { | |
153 int boatSize = Math.max(2, Math.min(5, deltaY.abs() + 1)); | |
154 boat = new Boat(_boatStartX, | |
155 deltaY < 0 ? (_boatStartY - boatSize + 1) : _boatStartY, | |
156 false, boatSize); | |
157 } | |
158 | |
159 state.addBoat(boat); | |
160 }); | 169 }); |
161 } | 170 } |
162 } | 171 } |
163 | 172 |
164 /** The view displayed to the player for its enemy's grid. */ | 173 /** The view displayed to the player for its enemy's grid. */ |
165 class EnemyGridView extends View { | 174 class EnemyGridView extends View { |
166 PlayerState state; | 175 PlayerState state; |
167 bool _enemyReady; | 176 bool _enemyReady; |
168 Element _rootNode; | 177 Element _rootNode; |
169 ShootingStatusView statusBar; | 178 ShootingStatusView statusBar; |
(...skipping 22 matching lines...) Expand all Loading... | |
192 statusBar = new ShootingStatusView(state, doc); | 201 statusBar = new ShootingStatusView(state, doc); |
193 _rootNode.nodes.add(statusBar._rootNode); | 202 _rootNode.nodes.add(statusBar._rootNode); |
194 _rootNode.on.click.add((Event e) { | 203 _rootNode.on.click.add((Event e) { |
195 MouseEvent mouseEvent = e; | 204 MouseEvent mouseEvent = e; |
196 handleClick(mouseEvent); | 205 handleClick(mouseEvent); |
197 }, false); | 206 }, false); |
198 } | 207 } |
199 | 208 |
200 /** Interpret clicks as a shooting action. */ | 209 /** Interpret clicks as a shooting action. */ |
201 void handleClick(MouseEvent e) { | 210 void handleClick(MouseEvent e) { |
202 ViewUtil.positionFromEvent(_rootNode, e).then((List<int> pos) { | 211 window.requestMeasurementFrame(() { |
203 state.shoot(pos[0], pos[1]); | 212 final pos = ViewUtil.positionFromEvent(_rootNode, e); |
213 return () { state.shoot(pos[0], pos[1]); }; | |
204 }); | 214 }); |
205 } | 215 } |
206 | 216 |
207 /** Update the view to indicate the enemy is ready. */ | 217 /** Update the view to indicate the enemy is ready. */ |
208 void setEnemyReady() { | 218 void setEnemyReady() { |
209 if (!_enemyReady) { | 219 if (!_enemyReady) { |
210 _enemyReady = true; | 220 _enemyReady = true; |
211 _rootNode.query(".notready").remove(); | 221 _rootNode.query(".notready").remove(); |
212 } | 222 } |
213 } | 223 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 final accounted = hit + miss; | 279 final accounted = hit + miss; |
270 final sunk = state.boatsSunk; | 280 final sunk = state.boatsSunk; |
271 _rootNode.innerHTML = | 281 _rootNode.innerHTML = |
272 "${total} <= ${accounted} (${hit} + ${miss}); ${sunk}"; | 282 "${total} <= ${accounted} (${hit} + ${miss}); ${sunk}"; |
273 } | 283 } |
274 } | 284 } |
275 | 285 |
276 /** Utility methods used by the views above. */ | 286 /** Utility methods used by the views above. */ |
277 class ViewUtil { | 287 class ViewUtil { |
278 | 288 |
279 /** Extract the position of a mouse event in a containing 500x500 grid. */ | 289 /** |
280 static Future<List<int>> positionFromEvent(Element gridNode, MouseEvent e) { | 290 * Extract the position of a mouse event in a containing 500x500 grid. |
281 final completer = new Completer<List<int>>(); | 291 * Must be run from within a measurement frame. |
282 gridNode.rect.then((ElementRect rect) { | 292 */ |
283 int x = (e.pageX - rect.offset.left) ~/ 50; | 293 static List<int> positionFromEvent(Element gridNode, MouseEvent e) { |
284 int y = (e.pageY - rect.offset.top) ~/ 50; | 294 assert(window.inMeasurementFrame); |
285 completer.complete([x, y]); | 295 int x = (e.pageX - gridNode.rect.offset.left) ~/ 50; |
286 }); | 296 int y = (e.pageY - gridNode.rect.offset.top) ~/ 50; |
287 return completer.future; | 297 return [x, y]; |
288 } | 298 } |
289 | 299 |
290 /** Given a grid node (square or boat) place it at a grid coordinate. */ | 300 /** Given a grid node (square or boat) place it at a grid coordinate. */ |
291 static void placeNodeAt(Element node, int x, int y) { | 301 static void placeNodeAt(Element node, int x, int y) { |
292 int xoffset = x * 50; | 302 int xoffset = x * 50; |
293 int yoffset = y * 50; | 303 int yoffset = y * 50; |
294 node.style.setProperty("top", yoffset.toString() + "px"); | 304 node.style.setProperty("top", yoffset.toString() + "px"); |
295 node.style.setProperty("left", xoffset.toString() + "px"); | 305 node.style.setProperty("left", xoffset.toString() + "px"); |
296 } | 306 } |
297 | 307 |
298 /** Create a div node with a given class name. */ | 308 /** Create a div node with a given class name. */ |
299 static Element createDiv(String className) { | 309 static Element createDiv(String className) { |
300 Element node = new Element.tag("div"); | 310 Element node = new Element.tag("div"); |
301 node.attributes["class"] = className; | 311 node.attributes["class"] = className; |
302 return node; | 312 return node; |
303 } | 313 } |
304 } | 314 } |
OLD | NEW |