forked from: PerlinNoise Terrain View
/**
* Copyright H.S ( http://wonderfl.net/user/H.S )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/t9iZ
*/
// forked from greentec's PerlinNoise Terrain View
package
{
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import com.bit101.components.TextArea;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.geom.Rectangle;
//import flash.display.BlendMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
/**
* ...
* @author ypc
*/
[SWF(width=465, height=465, backgroundColor=0x000000, frameRate=10)]
public class Main extends Sprite
{
public var tileSprite:Sprite;
public var tileBitmapData:BitmapData;
public var tileBitmap:Bitmap;
public var tileBitmapDataWidth:int = 400;
public var tileBitmapDataHeight:int = 400;
public var tileBitmapDataCellWidth:int;
public var tileBitmapDataCellHeight:int;
public var noiseSprite:Sprite;
public var noiseBitmap:Bitmap;
public var noiseBitmapData:BitmapData;
public var noiseBitmapDataWidth:int = 100;
public var noiseBitmapDataHeight:int = 100;
public var landCellnum:uint;
public var clone:BitmapData;
public var threshold:uint = 0x333333;
public var terrainColorDict:Array = [0x000080, 0x0000ff, 0x0080ff, 0xf0f040, 0x20a000, 0xe0e000, 0x808080, 0xffffff];
public var terrainColorNum:Array = [0, 0.125, 0.5, 0.53125, 0.5625, 0.6875, 0.875, 1];
public var randomSeed:int = Math.random() * int.MAX_VALUE;
public var offsets:Array = [];
public var speeds:Array = [];
public var numOctaves:int = 7;
public var numOctavesMax:int = 7;
public var channelOptions:int = Math.random() * 15 + 1;
public var stitch:Boolean = true;
public var fractalNoise:Boolean = false;
public var helpLabel:Label;
public var playButton:PushButton;
public var reverseButton:PushButton;
public var randomizeButton:PushButton;
public var partition:int = 12;
public var radius:int = 170;
public var shape:Shape = new Shape();
public var verts:Vector.<Number> = new Vector.<Number>();
public var uvts:Vector.<Number> = new Vector.<Number>();
public var indices:Vector.<int> = new Vector.<int>();
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
// don't take a capture
Wonderfl.disable_capture();
for (var cols:int = 0; cols <= partition; cols++) {
for (var rows:int = 0; rows <= partition; rows++) {
var x:Number = radius * Math.cos(Math.PI * (rows / partition - 0.5)) * Math.sin(Math.PI * (cols / partition - 0.5));
var y:Number = radius * Math.sin(Math.PI * (rows / partition - 0.5));
verts.push(x, y);
uvts.push(cols / partition, rows / partition, 1);
if (cols < partition && rows < partition ) {
var topLeft:int = cols * (partition + 1) + rows;
var bottomLeft:int = topLeft + 1;
var topRight:int = topLeft + partition + 1;
var bottomRight:int = topRight + 1;
indices.push(topLeft, bottomLeft, topRight, bottomLeft, bottomRight, topRight);
}
}
}
var i:int;
for (i = 0; i < numOctavesMax; i += 1)
{
offsets[i] = new Point(0, 0);
speeds.push(new Point(Math.random()*8-4, Math.random()*8-4))
}
graphics.beginFill(0, 1);
graphics.drawRect(0, 0, 465, 465);
tileSprite = new Sprite();
//addChild(tileSprite);
addChild(shape);
shape.x = stage.stageWidth / 2;
shape.y =200;
tileBitmapData = new BitmapData(tileBitmapDataWidth, tileBitmapDataHeight, false);
tileBitmap = new Bitmap(tileBitmapData);
tileSprite.addChild(tileBitmap);
//tileBitmap.blendMode = BlendMode.ADD;
noiseSprite = new Sprite();
addChild(noiseSprite);
noiseBitmapData = new BitmapData(noiseBitmapDataWidth, noiseBitmapDataHeight, false);
//noiseBitmapData.noise(randomSeed, 0, 255, 1, true);
noiseBitmapData.perlinNoise(noiseBitmapDataWidth, noiseBitmapDataHeight, numOctaves, randomSeed, false, fractalNoise, 7, true, offsets);
noiseBitmap = new Bitmap(noiseBitmapData);
noiseBitmap.x = 465 - 50;
//noiseSprite.addChild(noiseBitmap);
tileBitmapDataCellWidth = tileBitmapDataWidth / noiseBitmapDataWidth;
tileBitmapDataCellHeight = tileBitmapDataHeight / noiseBitmapDataHeight;
drawCell();
helpLabel = new Label(this, 10, 410, "numOctaves : " + String(numOctaves) + "\nrandomSeed : " + String(randomSeed) + "\nland : " + String(int(10000 * landCellnum / (noiseBitmapDataWidth * noiseBitmapDataHeight))/100) + " %");
playButton = new PushButton(this, 465 / 3, 410, "Play", onPlay);
playButton.toggle = true;
reverseButton = new PushButton(this, playButton.x + playButton.width, 410, "Reverse", onReverse);
randomizeButton = new PushButton(this, 465 / 3, playButton.y + playButton.height, "Randomize", onRandomize);
//addEventListener(Event.ENTER_FRAME, onEnterFrame);
//stage.addEventListener(MouseEvent.CLICK, onMouseClick);
drawTexture();
}
private function onReverse(e:Event):void
{
var i:int;
for (i = 0; i < speeds.length; i += 1)
{
speeds[i].x *= -1;
speeds[i].y *= -1;
}
}
private function onRandomize(e:Event):void
{
randomSeed = Math.random() * int.MAX_VALUE;
//fractalNoise = Math.random() < 0.5 ? true : false;
//numOctaves = Math.random() * 4 + 4;
var i:int;
for (i = 0; i < numOctavesMax; i += 1)
{
speeds[i] = new Point(Math.random() * 8 - 4, Math.random() * 8 - 4);
}
noiseBitmapData.perlinNoise(noiseBitmapDataWidth, noiseBitmapDataHeight, numOctaves, randomSeed, false, fractalNoise, 7, true, offsets);
drawCell();
helpLabel.text = "numOctaves : " + String(numOctaves) + "\nrandomSeed : " + String(randomSeed) + "\nland : " + String(int(10000 * landCellnum / (noiseBitmapDataWidth * noiseBitmapDataHeight))/100) + " %";
}
private function onPlay(e:Event):void
{
if (e.target.selected == false)
//hasEventListener(Event.ENTER_FRAME))
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
playButton.label = "Play";
}
else
{
addEventListener(Event.ENTER_FRAME, onEnterFrame);
playButton.label = "Stop";
}
}
private function drawCell():void
{
var i:int;
var j:int;
var colorNum:Number;
var color:uint;
var k:int;
var t:Number;
landCellnum = 0;
for (i = 0; i < noiseBitmapDataWidth; i += 1)
{
for (j = 0; j < noiseBitmapDataHeight; j += 1)
{
colorNum = noiseBitmapData.getPixel(i, j) / 0xffffff;
//color = terrainColorDict[0];
for (k = 0; k < terrainColorNum.length - 1; k += 1)
{
if (terrainColorNum[k] <= colorNum && terrainColorNum[k+1] >= colorNum)
{
t = (colorNum - terrainColorNum[k]) / (terrainColorNum[k + 1] - terrainColorNum[k]);
color = interpolateColor(terrainColorDict[k], terrainColorDict[k + 1], t);
if (k >= 3)
{
landCellnum += 1;
}
}
}
tileBitmapData.fillRect(new Rectangle(i * tileBitmapDataCellWidth, j * tileBitmapDataCellHeight, tileBitmapDataCellWidth, tileBitmapDataCellHeight), color);
}
}
}
public static function interpolateColor(fromColor:uint, toColor:uint, progress:Number):uint
{
var q:Number = 1-progress;
var fromR:uint = (fromColor >> 16) & 0xFF;
var fromG:uint = (fromColor >> 8) & 0xFF;
var fromB:uint = fromColor & 0xFF;
var toR:uint = (toColor >> 16) & 0xFF;
var toG:uint = (toColor >> 8) & 0xFF;
var toB:uint = toColor & 0xFF;
var resultR:uint = fromR*q + toR*progress;
var resultG:uint = fromG*q + toG*progress;
var resultB:uint = fromB*q + toB*progress;
var resultColor:uint = resultR << 16 | resultG << 8 | resultB;
return resultColor;
}
private function onEnterFrame(e:Event):void
{
var i:int;
for (i = 0; i < numOctaves; i += 1)
{
offsets[i].x += speeds[i].x;
offsets[i].y += speeds[i].y;
}
noiseBitmapData.perlinNoise(noiseBitmapDataWidth, noiseBitmapDataHeight, numOctaves, randomSeed, false, fractalNoise, 7, true, offsets);
drawCell();
helpLabel.text = "numOctaves : " + String(numOctaves) + "\nrandomSeed : " + String(randomSeed) + "\nland : " + String(int(10000 * landCellnum / (noiseBitmapDataWidth * noiseBitmapDataHeight))/100) + " %";
drawTexture();
}
private function drawTexture():void {
shape.graphics.clear();
shape.graphics.beginBitmapFill(tileBitmapData);
shape.graphics.drawTriangles(verts, indices, uvts, "positive");
shape.graphics.lineStyle (1, 0xFFFFFF, 0.25);
for (var cols:int = 0; cols <= partition; cols++) {
for (var rows:int = 0; rows <= partition; rows++) {
var topLeft:int = (cols * (partition + 1) + rows) * 2;
var bottomLeft:int = topLeft + 2;
var topRight:int = topLeft + (partition + 1) * 2;
if (rows <partition) {
shape.graphics.moveTo(verts[topLeft], verts[topLeft + 1]);
shape.graphics.lineTo(verts[bottomLeft], verts[bottomLeft + 1]);
}
if (cols <partition) {
shape.graphics.moveTo(verts[topLeft], verts[topLeft + 1]);
shape.graphics.lineTo(verts[topRight], verts[topRight + 1]);
}
}
}
shape.graphics.endFill();
}
}
}