Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: frog/await/samples/dartcombat/views.dart

Issue 10548047: Remove frog from the repository. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Move test and update apidoc.gyp. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/await/samples/dartcombat/state.dart ('k') | frog/await/samples/mintmaker/mintmaker.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
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.
4
5 /** Base class for all views. */
6 class View {
7 Document doc;
8 View(this.doc) {}
9 }
10
11 /** The view displayed to the player for its own grid. */
12 class PlayerGridView extends View {
13 /** Model associated with the player's state. */
14 PlayerState state;
15
16 /** A div element containing the grid. */
17 Element _rootNode;
18
19 PlayerGridView(
20 PlayerState this.state, Element rootNode)
21 : super(rootNode.document), _rootNode = rootNode {
22 render();
23 }
24
25 /** Create an initial visual representation of this view. */
26 void render() {
27 String cell = "<div class='icons water'></div>";
28 StringBuffer _cells = new StringBuffer();
29 for (int i = 0 ; i < state.localGrid.cells.length; i++) {
30 _cells.add(cell);
31 }
32 String cells = _cells.toString();
33 String row = "<div class='hbox'>${cells}</div>";
34 StringBuffer _rows = new StringBuffer();
35 for (int i = 0 ; i < state.localGrid.cells.length; i++) {
36 _rows.add(row);
37 }
38 String rows = _rows.toString();
39 String table = "<div class='vbox'>${rows}</div>";
40 _rootNode.innerHTML = table;
41
42 // Attaches listeners onto this view.
43 new PlaceBoatView(state, _rootNode).attach();
44 }
45
46 /** Adds to this view the respresentation of a missed shot. */
47 void addMiss(int x, int y) {
48 Element node = ViewUtil.createDiv("icons miss");
49 ViewUtil.placeNodeAt(node, x, y);
50 _rootNode.nodes.add(node);
51 }
52
53 /** Adds to this view the respresentation of a shot that hits our boat. */
54 void addHit(int x, int y) {
55 Element node = ViewUtil.createDiv("icons hit-onboat");
56 ViewUtil.placeNodeAt(node, x, y);
57 _rootNode.nodes.add(node);
58 }
59 }
60
61 /** View used to interactively set a new boat on the board. */
62 class PlaceBoatView extends View {
63 PlayerState state;
64
65 /** root of the grid. */
66 Element _rootNode;
67
68 /** start location where the user first clicked. */
69 int _boatStartX;
70 int _boatStartY;
71
72 /** last known mouse location. */
73 int _boatLastX;
74 int _boatLastY;
75
76 /** HTML element rendering the actual boat. */
77 Element _possibleBoat;
78
79 /** Mouse move-listener to be detached when the boat is placed. */
80 Function _moveListener;
81
82 PlaceBoatView(
83 PlayerState this.state, Element rootNode)
84 : super(rootNode.document), _rootNode = rootNode {}
85
86 void attach() {
87 _rootNode.on.mouseDown.add(handleMouseDown);
88 _rootNode.on.mouseUp.add(handleMouseUp);
89 }
90
91 handleMouseDown(e) {
92 e.preventDefault();
93 List<int> pos = await ViewUtil.positionFromEvent(_rootNode, e);
94 _boatStartX = pos[0];
95 _boatStartY = pos[1];
96 // error case when the mouse was released out of the boat-placing area
97 if (_moveListener != null) {
98 _rootNode.on.mouseMove.remove(_moveListener, false);
99 _possibleBoat.remove();
100 _moveListener = null;
101 }
102 _possibleBoat = ViewUtil.createDiv("icons boat2");
103 ViewUtil.placeNodeAt(_possibleBoat, _boatStartX, _boatStartY);
104 _rootNode.nodes.add(_possibleBoat);
105 _moveListener = handleMouseMove;
106 _rootNode.on.mouseMove.add(_moveListener);
107 }
108
109 handleMouseMove(e) {
110 e.preventDefault();
111 List<int> pos = await ViewUtil.positionFromEvent(_rootNode, e);
112 if (_boatLastX == pos[0] && _boatLastY == pos[1]) {
113 return;
114 }
115 _boatLastX = pos[0];
116 _boatLastY = pos[1];
117 int deltaX = _boatLastX - _boatStartX;
118 int deltaY = _boatLastY - _boatStartY;
119
120 String dir;
121 bool flip = false;
122 int boatSize = 2;
123 if (deltaX.abs() >= deltaY.abs()) {
124 dir = deltaX < 0 ? "right" : "left";
125 boatSize = Math.max(2, Math.min(5, deltaX.abs() + 1));
126 } else {
127 dir = deltaY < 0 ? "up" : "down";
128 boatSize = Math.max(2, Math.min(5, deltaY.abs() + 1));
129 }
130
131 _possibleBoat.attributes["class"] = "icons boat${boatSize} boatdir-${dir}";
132 }
133
134 /** Handle end of positioning of a boat. */
135 handleMouseUp(e) {
136 _rootNode.on.mouseMove.remove(_moveListener, false);
137 _moveListener = null;
138 List<int> pos = await ViewUtil.positionFromEvent(_rootNode, e);
139 int _boatEndX = pos[0];
140 int _boatEndY = pos[1];
141
142 int deltaX = _boatEndX - _boatStartX;
143 int deltaY = _boatEndY - _boatStartY;
144 Boat boat;
145
146 if (deltaX.abs() >= deltaY.abs()) {
147 int boatSize = Math.max(2, Math.min(5, deltaX.abs() + 1));
148 boat = new Boat(deltaX < 0 ? (_boatStartX - boatSize + 1) : _boatStartX,
149 _boatStartY, true, boatSize);
150 } else {
151 int boatSize = Math.max(2, Math.min(5, deltaY.abs() + 1));
152 boat = new Boat(_boatStartX,
153 deltaY < 0 ? (_boatStartY - boatSize + 1) : _boatStartY,
154 false, boatSize);
155 }
156
157 state.addBoat(boat);
158 }
159 }
160
161 /** The view displayed to the player for its enemy's grid. */
162 class EnemyGridView extends View {
163 PlayerState state;
164 bool _enemyReady;
165 Element _rootNode;
166 ShootingStatusView statusBar;
167
168 EnemyGridView(
169 PlayerState this.state, Element rootNode)
170 : super(rootNode.document),
171 _enemyReady = false,
172 _rootNode = rootNode {
173
174 String cell = "<div class='icons water'></div>";
175 StringBuffer _cells = new StringBuffer();
176 for (int i = 0 ; i < state.enemyGrid.cells.length; i++) {
177 _cells.add(cell);
178 }
179 String cells = _cells.toString();
180 String row = "<div class='hbox'>${cells}</div>";
181 StringBuffer _rows = new StringBuffer();
182 for (int i = 0 ; i < state.enemyGrid.cells.length; i++) {
183 _rows.add(row);
184 }
185 String rows = _rows.toString();
186 String table = "<div class='vbox'>${rows}</div>";
187 _rootNode.innerHTML =
188 "${table}<div class='notready'>ENEMY IS NOT READY</div>";
189 statusBar = new ShootingStatusView(state, doc);
190 _rootNode.nodes.add(statusBar._rootNode);
191 _rootNode.on.click.add((Event e) {
192 MouseEvent mouseEvent = e;
193 handleClick(mouseEvent);
194 }, false);
195 }
196
197 /** Interpret clicks as a shooting action. */
198 handleClick(MouseEvent e) {
199 List<int> pos = await ViewUtil.positionFromEvent(_rootNode, e);
200 state.shoot(pos[0], pos[1]);
201 }
202
203 /** Update the view to indicate the enemy is ready. */
204 void setEnemyReady() {
205 if (!_enemyReady) {
206 _enemyReady = true;
207 _rootNode.query(".notready").remove();
208 }
209 }
210
211
212 /** Update the view to indicate a shot that hit an enemy's boat. */
213 void addHit(int x, int y) {
214 Element node = ViewUtil.createDiv("icons hit");
215 ViewUtil.placeNodeAt(node, x, y);
216 _rootNode.nodes.add(node);
217 }
218
219 /** Update the view to indicate a shot that missed an enemy's boat. */
220 void addMiss(int x, int y) {
221 Element node = ViewUtil.createDiv("icons miss");
222 ViewUtil.placeNodeAt(node, x, y);
223 _rootNode.nodes.add(node);
224 }
225
226 /** Update the view to indicate a shot is in progress. */
227 void addMaybeHit(int x, int y) {
228 Element node = ViewUtil.createDiv("icons maybe-hit");
229 ViewUtil.placeNodeAt(node, x, y);
230 _rootNode.nodes.add(node);
231 }
232
233 /**
234 * Remove the icon indicating that a shot is in progress (only called when
235 * shots failed due to network errors).
236 */
237 void removeMaybeHit(int x, int y) {
238 for (Element node in _rootNode.queryAll(".maybe-hit")) {
239 int xoffset = x * 50;
240 int yoffset = y * 50;
241 if (node.style.getPropertyValue("top") == "${yoffset}px"
242 && node.style.getPropertyValue("left") == "${xoffset}px") {
243 node.remove();
244 return;
245 }
246 }
247 }
248 }
249
250 class ShootingStatusView extends View {
251 PlayerState state;
252 Element _rootNode;
253
254 ShootingStatusView(this.state, Document doc)
255 : super(doc) {
256 _rootNode = ViewUtil.createDiv("shooting-status");
257 updateStatus();
258 }
259
260 /** Update the view to indicate we sunk another enemy's boat. */
261 void updateStatus() {
262 final total = state.totalShots;
263 final hit = state.totalHits;
264 final miss = state.totalMisses;
265 final accounted = hit + miss;
266 final sunk = state.boatsSunk;
267 _rootNode.innerHTML =
268 "${total} &lt;= ${accounted} (${hit} + ${miss}); ${sunk}";
269 }
270 }
271
272 /** Utility methods used by the views above. */
273 class ViewUtil {
274
275 /** Extract the position of a mouse event in a containing 500x500 grid. */
276 static Future<List<int>> positionFromEvent(Element gridNode, MouseEvent e) {
277 ElementRect rect = await gridNode.rect;
278 int x = (e.pageX - rect.offset.left) ~/ 50;
279 int y = (e.pageY - rect.offset.top) ~/ 50;
280 return [x, y];
281 }
282
283 /** Given a grid node (square or boat) place it at a grid coordinate. */
284 static void placeNodeAt(Element node, int x, int y) {
285 int xoffset = x * 50;
286 int yoffset = y * 50;
287 node.style.setProperty("top", yoffset.toString() + "px");
288 node.style.setProperty("left", xoffset.toString() + "px");
289 }
290
291 /** Create a div node with a given class name. */
292 static Element createDiv(String className) {
293 Element node = new Element.tag("div");
294 node.attributes["class"] = className;
295 return node;
296 }
297 }
OLDNEW
« no previous file with comments | « frog/await/samples/dartcombat/state.dart ('k') | frog/await/samples/mintmaker/mintmaker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698