Skip to content

Instantly share code, notes, and snippets.

@noonat
Created June 11, 2011 18:25
Show Gist options
  • Save noonat/1020812 to your computer and use it in GitHub Desktop.
Save noonat/1020812 to your computer and use it in GitHub Desktop.
Tile connectivity example
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