| 303 | | destroyTile(Tile(tiles.shift())); |
|---|
| 304 | | Reactor.callLater(0, destroyTiles, tiles); |
|---|
| 305 | | } |
|---|
| 306 | | } |
|---|
| 307 | | |
|---|
| 308 | | /* |
|---|
| 309 | | * Reposition tiles and schedule a recursive call for the next frame. |
|---|
| 310 | | */ |
|---|
| 311 | | protected function onWellDrag(previousPosition:Point):void |
|---|
| 312 | | { |
|---|
| 313 | | if(positionTiles()) |
|---|
| 314 | | updateMarkers(); |
|---|
| 315 | | |
|---|
| 316 | | if(previousPosition.x != _well.x || previousPosition.y != _well.y) |
|---|
| 317 | | _map.onPanned(new Point(_well.x - _startingWellPosition.x, _well.y - _startingWellPosition.y)); |
|---|
| 318 | | |
|---|
| 319 | | _wellDragTask = Reactor.callNextFrame(onWellDrag, new Point(_well.x, _well.y)); |
|---|
| 320 | | } |
|---|
| 321 | | |
|---|
| 322 | | /* |
|---|
| 323 | | * Return the point position of a tile with the given coordinate in the |
|---|
| 324 | | * context of the given movie clip. |
|---|
| 325 | | * |
|---|
| 326 | | * Respect infinite rows or columns, to bind movement on one (or no) axis. |
|---|
| 327 | | */ |
|---|
| 328 | | public function coordinatePoint(coord:Coordinate, context:Sprite, fearBigNumbers:Boolean=false):Point |
|---|
| 329 | | { |
|---|
| 330 | | // pick a reference tile, an arbitrary choice |
|---|
| 331 | | // but known to exist regardless of grid size. |
|---|
| 332 | | var tile:Tile = activeTiles()[0]; |
|---|
| 333 | | |
|---|
| 334 | | // get the position of the reference tile. |
|---|
| 335 | | var point:Point = new Point(tile.x, tile.y); |
|---|
| 336 | | |
|---|
| 337 | | // make sure coord is using the same zoom level |
|---|
| 338 | | coord = coord.zoomTo(tile.coord.zoom); |
|---|
| 339 | | |
|---|
| 340 | | // store the infinite |
|---|
| 341 | | var force:Point = new Point(0, 0); |
|---|
| 342 | | |
|---|
| 343 | | if(coord.column == Number.POSITIVE_INFINITY || coord.column == Number.NEGATIVE_INFINITY) { |
|---|
| 344 | | force.x = coord.column; |
|---|
| 345 | | } else { |
|---|
| 346 | | point.x += TILE_WIDTH * (coord.column - tile.coord.column); |
|---|
| 347 | | } |
|---|
| 348 | | |
|---|
| 349 | | if(coord.row == Number.POSITIVE_INFINITY || coord.row == Number.NEGATIVE_INFINITY) { |
|---|
| 350 | | force.y = coord.row; |
|---|
| 351 | | } else { |
|---|
| 352 | | point.y += TILE_HEIGHT * (coord.row - tile.coord.row); |
|---|
| 353 | | } |
|---|
| 354 | | |
|---|
| 355 | | if(fearBigNumbers) { |
|---|
| 356 | | if(point.x < -1e6) { |
|---|
| 357 | | force.x = Number.NEGATIVE_INFINITY; |
|---|
| 358 | | } |
|---|
| 359 | | if(point.x > 1e6) { |
|---|
| 360 | | force.x = Number.POSITIVE_INFINITY; |
|---|
| 361 | | } |
|---|
| 362 | | if(point.y < -1e6) { |
|---|
| 363 | | force.y = Number.NEGATIVE_INFINITY; |
|---|
| 364 | | } |
|---|
| 365 | | if(point.y > 1e6) { |
|---|
| 366 | | force.y = Number.POSITIVE_INFINITY; |
|---|
| 367 | | } |
|---|
| 368 | | } |
|---|
| 369 | | |
|---|
| 370 | | point = _well.localToGlobal(point); |
|---|
| 371 | | point = context.globalToLocal(point); |
|---|
| 372 | | |
|---|
| 373 | | if(force.x) { |
|---|
| 374 | | point.x = force.x; |
|---|
| 375 | | } |
|---|
| 376 | | if(force.y) { |
|---|
| 377 | | point.y = force.y; |
|---|
| 378 | | } |
|---|
| 379 | | return point; |
|---|
| 380 | | } |
|---|
| 381 | | |
|---|
| 382 | | public function pointCoordinate(point:Point, context:Sprite=null):Coordinate |
|---|
| 383 | | { |
|---|
| 384 | | var tile:Tile; |
|---|
| 385 | | var tileCoord:Coordinate; |
|---|
| 386 | | var pointCoord:Coordinate; |
|---|
| 387 | | |
|---|
| 388 | | if (null == context) context = this; |
|---|
| 389 | | // point is assumed to be in tile grid local coordinates |
|---|
| 390 | | point = context.localToGlobal(point); |
|---|
| 391 | | point = _well.globalToLocal(point); |
|---|
| 392 | | |
|---|
| 393 | | // an arbitrary reference tile, zoomed to the maximum |
|---|
| 394 | | tile = activeTiles()[0]; |
|---|
| 395 | | tileCoord = tile.coord.zoomTo(Coordinate.MAX_ZOOM); |
|---|
| 396 | | |
|---|
| 397 | | // distance in tile widths from reference tile to point |
|---|
| 398 | | var xTiles:Number = (point.x - tile.x) / TILE_WIDTH; |
|---|
| 399 | | var yTiles:Number = (point.y - tile.y) / TILE_HEIGHT; |
|---|
| 400 | | |
|---|
| 401 | | // distance in rows & columns at maximum zoom |
|---|
| 402 | | var xDistance:Number = xTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); |
|---|
| 403 | | var yDistance:Number = yTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); |
|---|
| 404 | | |
|---|
| 405 | | // new point coordinate reflecting that distance |
|---|
| 406 | | pointCoord = new Coordinate(Math.round(tileCoord.row + yDistance), |
|---|
| 407 | | Math.round(tileCoord.column + xDistance), |
|---|
| 408 | | tileCoord.zoom); |
|---|
| 409 | | |
|---|
| 410 | | return pointCoord.zoomTo(tile.coord.zoom); |
|---|
| 411 | | } |
|---|
| 412 | | |
|---|
| 413 | | public function topLeftCoordinate():Coordinate |
|---|
| 414 | | { |
|---|
| 415 | | var point:Point = new Point(0, 0); |
|---|
| 416 | | return pointCoordinate(point); |
|---|
| 417 | | } |
|---|
| 418 | | |
|---|
| 419 | | public function centerCoordinate():Coordinate |
|---|
| 420 | | { |
|---|
| 421 | | var point:Point = new Point(_width/2, _height/2); |
|---|
| 422 | | return pointCoordinate(point); |
|---|
| 423 | | } |
|---|
| 424 | | |
|---|
| 425 | | public function bottomRightCoordinate():Coordinate |
|---|
| 426 | | { |
|---|
| 427 | | var point:Point = new Point(_width, _height); |
|---|
| 428 | | return pointCoordinate(point); |
|---|
| 429 | | } |
|---|
| 430 | | |
|---|
| 431 | | /* |
|---|
| 432 | | * Start dragging the well with the mouse. |
|---|
| 433 | | * Calls onWellDrag(). |
|---|
| 434 | | */ |
|---|
| 435 | | protected function getWellBounds(fearBigNumbers:Boolean):Bounds |
|---|
| 436 | | { |
|---|
| 437 | | var min:Point, max:Point; |
|---|
| 438 | | |
|---|
| 439 | | // "min" = furthest well position left & up, |
|---|
| 440 | | // use the location of the bottom-right limit |
|---|
| 441 | | min = coordinatePoint(bottomRightInLimit, this, fearBigNumbers); |
|---|
| 442 | | min.x = _well.x - min.x + _width; |
|---|
| 443 | | min.y = _well.y - min.y + _height; |
|---|
| 444 | | |
|---|
| 445 | | // "max" = furthest well position right & down, |
|---|
| 446 | | // use the location of the top-left limit |
|---|
| 447 | | max = coordinatePoint(topLeftOutLimit, this, fearBigNumbers); |
|---|
| 448 | | max.x = _well.x - max.x; |
|---|
| 449 | | max.y = _well.y - max.y; |
|---|
| 450 | | |
|---|
| | 303 | destroyTile(Tile(tiles.shift())); |
|---|
| | 304 | Reactor.callLater(0, destroyTiles, tiles); |
|---|
| | 305 | } |
|---|
| | 306 | } |
|---|
| | 307 | |
|---|
| | 308 | /* |
|---|
| | 309 | * Reposition tiles and schedule a recursive call for the next frame. |
|---|
| | 310 | */ |
|---|
| | 311 | protected function onWellDrag(previousPosition:Point):void |
|---|
| | 312 | { |
|---|
| | 313 | if(positionTiles()) |
|---|
| | 314 | updateMarkers(); |
|---|
| | 315 | |
|---|
| | 316 | if(previousPosition.x != _well.x || previousPosition.y != _well.y) |
|---|
| | 317 | _map.onPanned(new Point(_well.x - _startingWellPosition.x, _well.y - _startingWellPosition.y)); |
|---|
| | 318 | |
|---|
| | 319 | _wellDragTask = Reactor.callNextFrame(onWellDrag, new Point(_well.x, _well.y)); |
|---|
| | 320 | } |
|---|
| | 321 | |
|---|
| | 322 | /* |
|---|
| | 323 | * Return the point position of a tile with the given coordinate in the |
|---|
| | 324 | * context of the given movie clip. |
|---|
| | 325 | * |
|---|
| | 326 | * Respect infinite rows or columns, to bind movement on one (or no) axis. |
|---|
| | 327 | */ |
|---|
| | 328 | public function coordinatePoint(coord:Coordinate, context:Sprite, fearBigNumbers:Boolean=false):Point |
|---|
| | 329 | { |
|---|
| | 330 | // pick a reference tile, an arbitrary choice |
|---|
| | 331 | // but known to exist regardless of grid size. |
|---|
| | 332 | var tile:Tile = activeTiles()[0]; |
|---|
| | 333 | |
|---|
| | 334 | // get the position of the reference tile. |
|---|
| | 335 | var point:Point = new Point(tile.x, tile.y); |
|---|
| | 336 | |
|---|
| | 337 | // make sure coord is using the same zoom level |
|---|
| | 338 | coord = coord.zoomTo(tile.coord.zoom); |
|---|
| | 339 | |
|---|
| | 340 | // store the infinite |
|---|
| | 341 | var force:Point = new Point(0, 0); |
|---|
| | 342 | |
|---|
| | 343 | if(coord.column == Number.POSITIVE_INFINITY || coord.column == Number.NEGATIVE_INFINITY) { |
|---|
| | 344 | force.x = coord.column; |
|---|
| | 345 | } else { |
|---|
| | 346 | point.x += TILE_WIDTH * (coord.column - tile.coord.column); |
|---|
| | 347 | } |
|---|
| | 348 | |
|---|
| | 349 | if(coord.row == Number.POSITIVE_INFINITY || coord.row == Number.NEGATIVE_INFINITY) { |
|---|
| | 350 | force.y = coord.row; |
|---|
| | 351 | } else { |
|---|
| | 352 | point.y += TILE_HEIGHT * (coord.row - tile.coord.row); |
|---|
| | 353 | } |
|---|
| | 354 | |
|---|
| | 355 | if(fearBigNumbers) { |
|---|
| | 356 | if(point.x < -1e6) { |
|---|
| | 357 | force.x = Number.NEGATIVE_INFINITY; |
|---|
| | 358 | } |
|---|
| | 359 | if(point.x > 1e6) { |
|---|
| | 360 | force.x = Number.POSITIVE_INFINITY; |
|---|
| | 361 | } |
|---|
| | 362 | if(point.y < -1e6) { |
|---|
| | 363 | force.y = Number.NEGATIVE_INFINITY; |
|---|
| | 364 | } |
|---|
| | 365 | if(point.y > 1e6) { |
|---|
| | 366 | force.y = Number.POSITIVE_INFINITY; |
|---|
| | 367 | } |
|---|
| | 368 | } |
|---|
| | 369 | |
|---|
| | 370 | point = _well.localToGlobal(point); |
|---|
| | 371 | point = context.globalToLocal(point); |
|---|
| | 372 | |
|---|
| | 373 | if(force.x) { |
|---|
| | 374 | point.x = force.x; |
|---|
| | 375 | } |
|---|
| | 376 | if(force.y) { |
|---|
| | 377 | point.y = force.y; |
|---|
| | 378 | } |
|---|
| | 379 | return point; |
|---|
| | 380 | } |
|---|
| | 381 | |
|---|
| | 382 | public function pointCoordinate(point:Point, context:Sprite=null):Coordinate |
|---|
| | 383 | { |
|---|
| | 384 | var tile:Tile; |
|---|
| | 385 | var tileCoord:Coordinate; |
|---|
| | 386 | var pointCoord:Coordinate; |
|---|
| | 387 | |
|---|
| | 388 | if (null == context) context = this; |
|---|
| | 389 | // point is assumed to be in tile grid local coordinates |
|---|
| | 390 | point = context.localToGlobal(point); |
|---|
| | 391 | point = _well.globalToLocal(point); |
|---|
| | 392 | |
|---|
| | 393 | // an arbitrary reference tile, zoomed to the maximum |
|---|
| | 394 | tile = activeTiles()[0]; |
|---|
| | 395 | tileCoord = tile.coord.zoomTo(Coordinate.MAX_ZOOM); |
|---|
| | 396 | |
|---|
| | 397 | // distance in tile widths from reference tile to point |
|---|
| | 398 | var xTiles:Number = (point.x - tile.x) / TILE_WIDTH; |
|---|
| | 399 | var yTiles:Number = (point.y - tile.y) / TILE_HEIGHT; |
|---|
| | 400 | |
|---|
| | 401 | // distance in rows & columns at maximum zoom |
|---|
| | 402 | var xDistance:Number = xTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); |
|---|
| | 403 | var yDistance:Number = yTiles * Math.pow(2, (Coordinate.MAX_ZOOM - tile.coord.zoom)); |
|---|
| | 404 | |
|---|
| | 405 | // new point coordinate reflecting that distance |
|---|
| | 406 | pointCoord = new Coordinate(Math.round(tileCoord.row + yDistance), |
|---|
| | 407 | Math.round(tileCoord.column + xDistance), |
|---|
| | 408 | tileCoord.zoom); |
|---|
| | 409 | |
|---|
| | 410 | return pointCoord.zoomTo(tile.coord.zoom); |
|---|
| | 411 | } |
|---|
| | 412 | |
|---|
| | 413 | public function topLeftCoordinate():Coordinate |
|---|
| | 414 | { |
|---|
| | 415 | var point:Point = new Point(0, 0); |
|---|
| | 416 | return pointCoordinate(point); |
|---|
| | 417 | } |
|---|
| | 418 | |
|---|
| | 419 | public function centerCoordinate():Coordinate |
|---|
| | 420 | { |
|---|
| | 421 | var point:Point = new Point(_width/2, _height/2); |
|---|
| | 422 | return pointCoordinate(point); |
|---|
| | 423 | } |
|---|
| | 424 | |
|---|
| | 425 | public function bottomRightCoordinate():Coordinate |
|---|
| | 426 | { |
|---|
| | 427 | var point:Point = new Point(_width, _height); |
|---|
| | 428 | return pointCoordinate(point); |
|---|
| | 429 | } |
|---|
| | 430 | |
|---|
| | 431 | /* |
|---|
| | 432 | * Start dragging the well with the mouse. |
|---|
| | 433 | * Calls onWellDrag(). |
|---|
| | 434 | */ |
|---|
| | 435 | protected function getWellBounds(fearBigNumbers:Boolean):Bounds |
|---|
| | 436 | { |
|---|
| | 437 | var min:Point, max:Point; |
|---|
| | 438 | |
|---|
| | 439 | // "min" = furthest well position left & up, |
|---|
| | 440 | // use the location of the bottom-right limit |
|---|
| | 441 | min = coordinatePoint(bottomRightInLimit, this, fearBigNumbers); |
|---|
| | 442 | min.x = _well.x - min.x + _width; |
|---|
| | 443 | min.y = _well.y - min.y + _height; |
|---|
| | 444 | |
|---|
| | 445 | // "max" = furthest well position right & down, |
|---|
| | 446 | // use the location of the top-left limit |
|---|
| | 447 | max = coordinatePoint(topLeftOutLimit, this, fearBigNumbers); |
|---|
| | 448 | max.x = _well.x - max.x; |
|---|
| | 449 | max.y = _well.y - max.y; |
|---|
| | 450 | |
|---|
| 452 | | |
|---|
| 453 | | // weird negative edge conditions, limit all movement on an axis |
|---|
| 454 | | if(min.x > max.x) |
|---|
| 455 | | min.x = max.x = _well.x; |
|---|
| 456 | | |
|---|
| 457 | | if(min.y > max.y) |
|---|
| 458 | | min.y = max.y = _well.y; |
|---|
| 459 | | |
|---|
| 460 | | return new Bounds(min, max); |
|---|
| 461 | | } |
|---|
| 462 | | |
|---|
| 463 | | /* |
|---|
| 464 | | * Start dragging the well with the mouse. |
|---|
| 465 | | * Calls onWellDrag(). |
|---|
| 466 | | */ |
|---|
| 467 | | public function startWellDrag(event:MouseEvent):void |
|---|
| 468 | | { |
|---|
| 469 | | stage.addEventListener(MouseEvent.MOUSE_UP, stopWellDrag); |
|---|
| 470 | | stage.addEventListener(MouseEvent.MOUSE_OUT, stopWellDrag); |
|---|
| 471 | | |
|---|
| 472 | | var bounds:Bounds = getWellBounds(true); |
|---|
| 473 | | |
|---|
| 474 | | // startDrag seems to hate the infinities, |
|---|
| 475 | | // so we'll fudge it with some implausibly large numbers. |
|---|
| 476 | | |
|---|
| 477 | | var xMin:Number = (bounds.min.x == Number.POSITIVE_INFINITY) |
|---|
| 478 | | ? 100000 |
|---|
| 479 | | : ((bounds.min.x == Number.NEGATIVE_INFINITY) |
|---|
| 480 | | ? -100000 |
|---|
| 481 | | : bounds.min.x); |
|---|
| 482 | | |
|---|
| 483 | | var yMin:Number = (bounds.min.y == Number.POSITIVE_INFINITY) |
|---|
| 484 | | ? 100000 |
|---|
| 485 | | : ((bounds.min.y == Number.NEGATIVE_INFINITY) |
|---|
| 486 | | ? -100000 |
|---|
| 487 | | : bounds.min.y); |
|---|
| 488 | | |
|---|
| 489 | | var xMax:Number = (bounds.max.x == Number.POSITIVE_INFINITY) |
|---|
| 490 | | ? 100000 |
|---|
| 491 | | : ((bounds.max.x == Number.NEGATIVE_INFINITY) |
|---|
| 492 | | ? -100000 |
|---|
| 493 | | : bounds.max.x); |
|---|
| 494 | | |
|---|
| 495 | | var yMax:Number = (bounds.max.y == Number.POSITIVE_INFINITY) |
|---|
| 496 | | ? 100000 |
|---|
| 497 | | : ((bounds.max.y == Number.NEGATIVE_INFINITY) |
|---|
| 498 | | ? -100000 |
|---|
| 499 | | : bounds.max.y); |
|---|
| 500 | | |
|---|
| | 452 | |
|---|
| | 453 | // weird negative edge conditions, limit all movement on an axis |
|---|
| | 454 | if(min.x > max.x) |
|---|
| | 455 | min.x = max.x = _well.x; |
|---|
| | 456 | |
|---|
| | 457 | if(min.y > max.y) |
|---|
| | 458 | min.y = max.y = _well.y; |
|---|
| | 459 | |
|---|
| | 460 | return new Bounds(min, max); |
|---|
| | 461 | } |
|---|
| | 462 | |
|---|
| | 463 | /* |
|---|
| | 464 | * Start dragging the well with the mouse. |
|---|
| | 465 | * Calls onWellDrag(). |
|---|
| | 466 | */ |
|---|
| | 467 | public function startWellDrag(event:MouseEvent):void |
|---|
| | 468 | { |
|---|
| | 469 | stage.addEventListener(MouseEvent.MOUSE_UP, stopWellDrag); |
|---|
| | 470 | stage.addEventListener(MouseEvent.MOUSE_OUT, stopWellDrag); |
|---|
| | 471 | |
|---|
| | 472 | var bounds:Bounds = getWellBounds(true); |
|---|
| | 473 | |
|---|
| | 474 | // startDrag seems to hate the infinities, |
|---|
| | 475 | // so we'll fudge it with some implausibly large numbers. |
|---|
| | 476 | |
|---|
| | 477 | var xMin:Number = (bounds.min.x == Number.POSITIVE_INFINITY) |
|---|
| | 478 | ? 100000 |
|---|
| | 479 | : ((bounds.min.x == Number.NEGATIVE_INFINITY) |
|---|
| | 480 | ? -100000 |
|---|
| | 481 | : bounds.min.x); |
|---|
| | 482 | |
|---|
| | 483 | var yMin:Number = (bounds.min.y == Number.POSITIVE_INFINITY) |
|---|
| | 484 | ? 100000 |
|---|
| | 485 | : ((bounds.min.y == Number.NEGATIVE_INFINITY) |
|---|
| | 486 | ? -100000 |
|---|
| | 487 | : bounds.min.y); |
|---|
| | 488 | |
|---|
| | 489 | var xMax:Number = (bounds.max.x == Number.POSITIVE_INFINITY) |
|---|
| | 490 | ? 100000 |
|---|
| | 491 | : ((bounds.max.x == Number.NEGATIVE_INFINITY) |
|---|
| | 492 | ? -100000 |
|---|
| | 493 | : bounds.max.x); |
|---|
| | 494 | |
|---|
| | 495 | var yMax:Number = (bounds.max.y == Number.POSITIVE_INFINITY) |
|---|
| | 496 | ? 100000 |
|---|
| | 497 | : ((bounds.max.y == Number.NEGATIVE_INFINITY) |
|---|
| | 498 | ? -100000 |
|---|
| | 499 | : bounds.max.y); |
|---|
| | 500 | |
|---|