/**
* Copyright dredlockz ( http://wonderfl.net/user/dredlockz )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zkIR
*/
package {
import de.polygonal.ds.Array2;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import net.hires.debug.Stats;
/**
* Brute-Force texture editor
* @author "Alessandro Ituarte"
* This is a test at a map-editor from games, that calculate the correct transitions from one texture to another
* To see it working with actual meaningful textures instead of just random bitmap data check it out here:
* http://alessandroituarte.com/blag/2009/10/10/62
*/
[SWF(frameRate='30',backgroundColor='0xCCCCCC',width='480',height='480')]
public class BackgroundTest extends Sprite {
private const WIDTH :int = 480;
private const HEIGHT :int = 480;
private const UNIT_SIZE :int = 20;
private const ROWS :int = 24;
private const COLUMNS :int = 24;
//value constants
private const GRASS :int = 0;
private const DIRT :int = 1;
private const TRANS :int = 2;
private const IDLE :int = 3;
//These should be actual images, I'll work on loading them later, since they were originally embeded
public var dirt:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x0000FF));
public var dirt_b:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x333300));
public var dirt_bl:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x444400));
public var dirt_br:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x555500));
public var dirt_t:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x666600));
public var dirt_tl:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x777700));
public var dirt_tr:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x888800));
public var dirt_l:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x999900));
public var dirt_r:Bitmap = new Bitmap(new BitmapData(20,20,false, 0xAAAA00));
public var dirt_cbl:Bitmap = new Bitmap(new BitmapData(20,20,false, 0xBBBB00));
public var dirt_cbr:Bitmap = new Bitmap(new BitmapData(20,20,false, 0xCCCC00));
public var dirt_ctl:Bitmap = new Bitmap(new BitmapData(20,20,false, 0xDDDD00));
public var dirt_ctr:Bitmap= new Bitmap(new BitmapData(20,20,false, 0xEEEE00));
public var dirt_cc2:Bitmap= new Bitmap(new BitmapData(20,20,false, 0xFFFF00));
public var dirt_cc:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x222200));
public var grass1:Bitmap= new Bitmap(new BitmapData(20,20,false, 0x005500));
public var grass2:Bitmap = new Bitmap(new BitmapData(20,20,false, 0x006600));
public var grass3:Bitmap= new Bitmap(new BitmapData(20,20,false, 0x007700));
private var grasses:Vector.<Bitmap> = new Vector.<Bitmap>();
private var grid:Array2;
private var mouseDown:Boolean = false;
private var conflicts:Boolean = false;
private var currentType:int = IDLE;
private var screen:BitmapData;
private var output:Bitmap;
private var midCells:int;
private var corCells:int;
public function BackgroundTest() {
super();
grasses.push(grass1);
grasses.push(grass2);
grasses.push(grass3);
screen = new BitmapData(WIDTH, HEIGHT, false, 0xFF0000);
output = new Bitmap(screen);
stage.addChild(output);
var st:Stats = stage.addChild(new Stats()) as Stats;
initDataArray();
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseIsDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseIsUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseIsMoving);
fillScreen();
}
public function tryCell(cellX:int, cellY:int):void{
if (currentType == IDLE || !isType(cellX, cellY)){
setCurrentType(cellX, cellY);
toggleCell(cellX, cellY);
balanceCheck();
paint();
}
}
public function setCurrentType(cellX:int, cellY:int):void {
switch(int(grid.get(cellX, cellY))){
case GRASS:
case TRANS:
currentType = DIRT;
break;
case DIRT:
currentType = GRASS;
break;
}
}
public function isType(cellX:int, cellY:int):Boolean{
var type:int = int(grid.get(cellX, cellY));
return (currentType == DIRT && type == DIRT) || (currentType == GRASS && (type == GRASS || type == TRANS));
}
public function toggleCell(cellX:int, cellY:int):void {
switch(currentType){
case DIRT:
grid.set(cellX, cellY, DIRT);
break;
case GRASS:
toggleGrass(cellX, cellY);
break;
}
}
public function toggleGrass(cellX:int, cellY:int):void {
for (var i:int = -1; i < 2;i++){
for (var j:int = -1; j < 2; j++){
if (cellX+i >=0 && cellX+i < COLUMNS && cellY+j >=0 && cellY+j < ROWS){
grid.set(cellX+i, cellY+j, GRASS);
}
}
}
}
public function checkForTransition(cellX:int, cellY:int):void {
if (cellX >=0 && cellX < COLUMNS && cellY >=0 && cellY < ROWS && int(grid.get(cellX, cellY)) == GRASS){
grid.set(cellX, cellY, TRANS);
}
}
public function transitionSweep(cellX:int, cellY:int):void {
if (int(grid.get(cellX, cellY)) == DIRT){
for (var i:int = -1; i < 2;i++){
for (var j:int = -1; j < 2; j++){
checkForTransition(cellX+i, cellY+j);
}
}
}
}
public function balanceSweep(cellX:int, cellY:int):void {
if (int(grid.get(cellX, cellY)) == TRANS && opposedCheck(cellX, cellY)){
conflicts = true;
grid.set(cellX, cellY, DIRT);
//transitionSweep(cellX, cellY);
}
}
public function balanceCheck():void {
do {
conflicts = false;
//CLEAN SWEEP
for (var i:int = 0; i < COLUMNS;i++){
for (var j:int = 0; j < ROWS;j++){
if (int(grid.get(i, j)) == TRANS){
grid.set(i, j, GRASS);
}
}
}
//TRANSITION SWEEP
for (i = 0; i < COLUMNS;i++){
for (j = 0; j < ROWS;j++){
transitionSweep(i,j);
}
}
//BALANCE SWEEP
for (i = 0; i < COLUMNS;i++){
for (j = 0; j < ROWS;j++){
balanceSweep(i,j);
}
}
}while (conflicts);
}
public function paint():void {
var tempBit:Bitmap;
//trace("-------------------------");
for (var i:int = 0; i < COLUMNS;i++){
for (var j:int = 0; j < ROWS;j++){
switch(int(grid.get(i,j))){
case GRASS:
tempBit = randomGrass();
break;
case DIRT:
tempBit = dirt;
break;
case TRANS:
tempBit = getTransitionBitmap(i,j);
break;
}
screen.copyPixels(tempBit.bitmapData, new Rectangle(0,0, UNIT_SIZE, UNIT_SIZE),new Point(UNIT_SIZE*i, UNIT_SIZE*j));
}
}
}
public function getTransitionBitmap(cellX:int, cellY:int):Bitmap {
//Count middle and corner cells
countCellTypes(cellX, cellY);
if (midCells > 1){
//in corner
return getInCornerBitmap(cellX, cellY);
}else if (midCells == 1){
var bitmap:Bitmap = getInCornerBitmap(cellX, cellY);
if (bitmap != null){
return bitmap;
}else {
return getStraightBitmap(cellX, cellY);
}
}else {
if (corCells > 1){
//double corner
return getDoubleCornerBitmap(cellX, cellY);//
}else if (corCells == 1){
//out corner
return getOutCornerBitmap(cellX, cellY);
}
}
return null;
}
public function getDoubleCornerBitmap(cellX:int, cellY:int):Bitmap {
var dirtA:Boolean = cellX-1 >= 0 && cellY-1 >= 0 && int(grid.get(cellX-1, cellY-1)) == DIRT;
var dirtB:Boolean = cellX+1 < ROWS && cellY+1 < COLUMNS && int(grid.get(cellX-1, cellY-1)) == DIRT;
//var dirtC:Boolean = cellX-1 >= 0 && cellY+1 < COLUMNS && int(grid.get(cellX-1, cellY-1)) == DIRT;
//var dirtD:Boolean = cellX+1 < ROWS && cellY+1 < COLUMNS && int(grid.get(cellX-1, cellY-1)) == DIRT;
if (dirtA && dirtB) {
return dirt_cc;
}else {
return dirt_cc2;
}
}
public function getInCornerBitmap(cellX:int, cellY:int):Bitmap{
var dirtA:Boolean = cellX-1 >= 0 && int(grid.get(cellX-1, cellY)) == DIRT;
var dirtB:Boolean = cellX-1 >= 0 && cellY-1 >= 0 && int(grid.get(cellX-1, cellY-1)) == DIRT;
var dirtC:Boolean = cellY+1 < ROWS && int(grid.get(cellX, cellY+1)) == DIRT;
var dirtD:Boolean = cellY+1 < ROWS && cellX+1 < COLUMNS && int(grid.get(cellX+1, cellY+1)) == DIRT;
if ( isInCorner(dirtA, dirtB, dirtC, dirtD)) {
return dirt_ctr;
}
dirtA = dirtC;
dirtB = cellX-1 >= 0 && cellY+1 < ROWS && int(grid.get(cellX-1, cellY+1)) == DIRT;
dirtC = cellX+1 < COLUMNS && int(grid.get(cellX+1, cellY)) == DIRT;
dirtD = cellY-1 >= 0 && cellX+1 < COLUMNS && int(grid.get(cellX+1, cellY-1)) == DIRT;
if ( isInCorner(dirtA, dirtB, dirtC, dirtD)) {
return dirt_ctl;
}
dirtA = dirtC;
dirtB = cellX+1 < COLUMNS && cellY+1 < ROWS && int(grid.get(cellX+1, cellY+1)) == DIRT;
dirtC = cellY-1 >= 0 && int(grid.get(cellX, cellY-1)) == DIRT;
dirtD = cellY-1 >= 0 && cellX-1 >= 0 && int(grid.get(cellX-1, cellY-1)) == DIRT;
if ( isInCorner(dirtA, dirtB, dirtC, dirtD)) {
return dirt_cbl;
}
dirtA = dirtC;
dirtB = cellX+1 < COLUMNS && cellY-1 >= 0 && int(grid.get(cellX+1, cellY-1)) == DIRT;
dirtC = cellX-1 >= 0 && int(grid.get(cellX-1, cellY)) == DIRT;
dirtD = cellY+1 < ROWS && cellX-1 >= 0 && int(grid.get(cellX-1, cellY+1)) == DIRT;
if ( isInCorner(dirtA, dirtB, dirtC, dirtD)) {
return dirt_cbr;
}
return null;
}
public function isInCorner(dirtA:Boolean, dirtB:Boolean, dirtC:Boolean, dirtD:Boolean):Boolean {
return ( dirtA && (dirtC || dirtD) ) || ( dirtC && (dirtA || dirtB));
}
public function getStraightBitmap(cellX:int, cellY:int):Bitmap{
if (cellX-1 >= 0 && int(grid.get(cellX-1, cellY)) == DIRT){
return dirt_r;
}else if (cellX+1 < COLUMNS && int(grid.get(cellX+1, cellY)) == DIRT){
return dirt_l;
}else if (cellY-1 >= 0 && int(grid.get(cellX, cellY-1)) == DIRT){
return dirt_b;
}else {
return dirt_t;
}
}
public function getOutCornerBitmap(cellX:int, cellY:int):Bitmap{
if (cellX-1 >= 0 && cellY-1 >= 0 && int(grid.get(cellX-1, cellY-1)) == DIRT){
return dirt_br;
}else if (cellX-1 >= 0 && cellY+1 < ROWS && int(grid.get(cellX-1, cellY+1)) == DIRT){
return dirt_tr;
}else if (cellX+1 < COLUMNS && cellY-1 >= 0 && int(grid.get(cellX+1, cellY-1)) == DIRT){
return dirt_bl;
}else {
return dirt_tl;
}
}
public function countCellTypes(cellX:int, cellY:int):void {
midCells = 0;
corCells = 0;
var counter:int = 0;
for (var i:int = -1; i < 2;i++){
for (var j:int = -1; j < 2; j++){
if (cellX+i >= 0 && cellX+i < COLUMNS && cellY+j >= 0 && cellY+j < ROWS && int(grid.get(cellX+i, cellY+j)) == DIRT) {
switch(counter){
case 0:
case 2:
case 6:
case 8://CORNERS
corCells++;
break;
case 1:
case 3:
case 5:
case 7://MIDS
midCells++;
break;
}
}
counter++;
}
}
}
public function opposedCheck(cellX:int, cellY:int):Boolean {
var pass:Boolean = true;
if (cellX-1 >=0 && cellX+1 < COLUMNS){
pass = pass && !(int(grid.get(cellX-1, cellY)) == DIRT && int(grid.get(cellX+1, cellY)) == DIRT);
}
if (cellY-1 >=0 && cellY+1 < ROWS){
pass = pass && !(int(grid.get(cellX, cellY-1)) == DIRT && int(grid.get(cellX, cellY+1)) == DIRT);
}
return !pass;
}
public function mouseIsMoving(event:MouseEvent):void {
if (mouseDown){
tryCell(pixelToCell(this.mouseX), pixelToCell(this.mouseY));
}
}
public function mouseIsUp(event:MouseEvent):void {
trace("Mouse is Up");
mouseDown = false;
currentType = IDLE;
}
public function mouseIsDown(event:MouseEvent):void {
trace("Mouse is Down");
mouseDown = true;
tryCell(pixelToCell(this.mouseX), pixelToCell(this.mouseY));
}
public function pixelToCell(pixel:int):int {
return pixel/UNIT_SIZE;
}
public function cellToPixel(cell:int):int {
return cell*UNIT_SIZE;
}
public function initDataArray():void {
grid = new Array2(ROWS, COLUMNS);
for (var i:int = 0; i < COLUMNS;i++){
for (var j:int = 0; j < ROWS;j++){
grid.set(i,j,GRASS);
}
}
}
public function randomGrass():Bitmap {
return grasses[int(Math.random()*3)];
}
public function fillScreen():void {
trace("Filling screen with grass...");
var randGrass:Bitmap;
for (var i:int = 0; i < COLUMNS;i++){
for (var j:int = 0; j < ROWS;j++){
randGrass = randomGrass();
screen.copyPixels(randGrass.bitmapData, new Rectangle(0,0, UNIT_SIZE, UNIT_SIZE),new Point(UNIT_SIZE*i, UNIT_SIZE*j));
}
}
output.bitmapData = screen;
}
}
}