Created
June 11, 2011 18:25
-
-
Save noonat/1020812 to your computer and use it in GitHub Desktop.
Tile connectivity example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package { | |
import flash.display.Bitmap; | |
import flash.display.BitmapData; | |
import flash.display.Sprite; | |
import flash.display.StageAlign; | |
import flash.display.StageQuality; | |
import flash.display.StageScaleMode; | |
import flash.geom.Point; | |
import flash.geom.Rectangle; | |
import flash.events.Event; | |
import flash.events.MouseEvent; | |
[SWF(width="640", height="480", backgroundColor="#000000")] | |
public class Main extends Sprite { | |
private var _bitmap:Bitmap; | |
private var _grid:Grid; | |
private var _point:Point = new Point(); | |
private var _rect:Rectangle = new Rectangle(); | |
private var _screen:BitmapData; | |
private var _screenRect:Rectangle; | |
private var _tileWidth:int = 32; | |
private var _tileHeight:int = 32; | |
function Main() { | |
_grid = new Grid(int(640 / _tileWidth), int(480 / _tileHeight)); | |
_grid.randomizeSolid(); | |
_screen = new BitmapData(640, 480, false, 0); | |
_screenRect = _screen.rect; | |
_bitmap = new Bitmap(_screen); | |
addChild(_bitmap); | |
if (stage) { | |
onAddedToStage(); | |
} else { | |
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); | |
} | |
} | |
private function onAddedToStage(event:Event=null):void { | |
stage.align = StageAlign.TOP_LEFT; | |
stage.frameRate = 60; | |
stage.quality = StageQuality.HIGH; | |
stage.scaleMode = StageScaleMode.NO_SCALE; | |
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); | |
addEventListener(Event.ENTER_FRAME, onEnterFrame); | |
} | |
private function onEnterFrame(event:Event=null):void { | |
var color:uint; | |
_screen.fillRect(_screenRect, 0); | |
_rect.width = _tileWidth; | |
_rect.height = _tileHeight; | |
for (var y:int = 0; y < _grid.height; ++y) { | |
for (var x:int = 0; x < _grid.width; ++x) { | |
var tile:Tile = _grid.getTile(x, y); | |
if (tile && tile.solid) { | |
color = tile.connected ? 0xffffff : 0xffff00; | |
_rect.x = x * _tileWidth; | |
_rect.y = y * _tileHeight; | |
_screen.fillRect(_rect, color); | |
} | |
} | |
} | |
} | |
private function onMouseDown(event:MouseEvent):void { | |
var tileX:int = int(stage.mouseX / _tileWidth); | |
var tileY:int = int(stage.mouseY / _tileHeight); | |
_grid.setSolid(tileX, tileY, !_grid.getSolid(tileX, tileY)); | |
} | |
} | |
} | |
class Tile { | |
public var connected:Boolean = false; | |
public var neighbors:Array = []; | |
public var solid:Boolean = false; | |
public var stamp:int = 0; | |
public var x:int; | |
public var y:int; | |
function Tile(x:int, y:int) { | |
this.x = x; | |
this.y = y; | |
} | |
} | |
class Grid { | |
public var tiles:Array; | |
public var stamp:int; | |
public var width:int; | |
public var height:int; | |
function Grid(width:int, height:int) { | |
this.width = width; | |
this.height = height; | |
tiles = []; | |
for (var y:int = 0; y < height; ++y) { | |
for (var x:int = 0; x < width; ++x) { | |
tiles[y * width + x] = new Tile(x, y); | |
} | |
} | |
updateNeighbors(); | |
} | |
public function getTile(x:int, y:int):Tile { | |
return tiles[y * width + x]; | |
} | |
public function getSolid(x:int, y:int):Boolean { | |
var tile:Tile = tiles[y * width + x]; | |
return tile ? tile.solid : false; | |
} | |
public function setSolid(x:int, y:int, solid:Boolean):void { | |
var tile:Tile = tiles[y * width + x]; | |
if (tile) { | |
tile.solid = solid; | |
updateConnected(); | |
} | |
} | |
public function randomizeSolid(percent:Number=0.5):void { | |
for (var i:int = 0; i < tiles.length; ++i) { | |
tiles[i].solid = Math.random() < percent; | |
} | |
updateConnected(); | |
} | |
private function updateConnected():void { | |
++stamp; | |
var tile:Tile; | |
var queue:Array = []; | |
for each (tile in tiles) { | |
if (tile.solid && tile.y == 0) { | |
// Connected tile on the first row, queue it | |
tile.connected = true; | |
tile.stamp = stamp; | |
queue.push(tile); | |
} else { | |
tile.connected = false; | |
} | |
} | |
// Process neighbors until the queue is empty | |
while (queue.length > 0) { | |
tile = queue.shift(); | |
for each (var neighbor:Tile in tile.neighbors) { | |
if (neighbor.solid && neighbor.stamp != stamp) { | |
neighbor.connected = true; | |
neighbor.stamp = stamp; | |
queue.push(neighbor); | |
} | |
} | |
} | |
} | |
private function updateNeighbors():void { | |
for (var y:int = 0; y < height; ++y) { | |
for (var x:int = 0; x < width; ++x) { | |
var i:int = y * width + x; | |
var tile:Tile = tiles[i]; | |
tile.neighbors.length = 0; | |
if (x > 0) tile.neighbors.push(tiles[i - 1]); | |
if (y > 0) tile.neighbors.push(tiles[i - width]); | |
if (x < width - 1) tile.neighbors.push(tiles[i + 1]); | |
if (y < height - 1) tile.neighbors.push(tiles[i + width]); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment