Star Field Generator
/**
* Copyright virtualtoy ( http://wonderfl.net/user/virtualtoy )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/erwH8
*/
package {
import com.bit101.components.*;
import flash.display.*;
import flash.events.*;
[SWF(width = "465", height = "465", backgroundColor = "0")]
public class Main extends Sprite {
public static const SCENE_WIDTH:Number = 465;
public static const SCENE_HEIGHT:Number = 465;
private var _bitmap:Bitmap = new Bitmap();
private var _seedStepper:NumericStepper;
private var _numNovaeStepper:NumericStepper;
private var _nebulaBaseXSlider:HSlider;
private var _nebulaBaseYSlider:HSlider;
private var _nebulaRedCheck:CheckBox;
private var _nebulaGreenCheck:CheckBox;
private var _nebulaBlueCheck:CheckBox;
private var _nebulaColorThresholdStepper:NumericStepper;
/**
* Update:
* - fixed CelestialTexture.drawNebula
* - optimizations
* - more parameters to adjust
*/
public function Main() {
addChild(_bitmap);
createUI();
refresh();
}
private function refresh():void {
if (_bitmap.bitmapData) {
_bitmap.bitmapData.dispose();
}
var randomSeed:int = _seedStepper.value;
var nebulaColors:uint = (_nebulaRedCheck.selected ? BitmapDataChannel.RED : 0) |
(_nebulaGreenCheck.selected ? BitmapDataChannel.GREEN : 0) |
(_nebulaBlueCheck.selected ? BitmapDataChannel.BLUE : 0);
var texture:BitmapData =
CelestialTexture.createStarField(SCENE_WIDTH, SCENE_HEIGHT, randomSeed);
CelestialTexture.drawNova(texture, _numNovaeStepper.value, 20, randomSeed);
CelestialTexture.drawNebula(texture, randomSeed, nebulaColors, _nebulaColorThresholdStepper.value, _nebulaBaseXSlider.value, _nebulaBaseYSlider.value);
_bitmap.bitmapData = texture;
}
private function randomize():void {
_seedStepper.value = int(Math.random() * 10000);
_numNovaeStepper.value = int(Math.random() * 200);
_nebulaBaseXSlider.value = Math.random() * 0.9 + 0.1;
_nebulaBaseYSlider.value = Math.random() * 0.9 + 0.1;
_nebulaRedCheck.selected = Math.random() < 0.5;
_nebulaGreenCheck.selected = Math.random() < 0.5;
_nebulaBlueCheck.selected = Math.random() < 0.5;
_nebulaColorThresholdStepper.value = int(Math.random() * 0xFF);
refresh();
}
private function createUI():void {
var window:Window = new Window(this, 0, 0, "Star Field Settings");
window.hasMinimizeButton = true;
window.setSize(170, 200);
new Label(window.content, 5, 5, "Random seed:");
_seedStepper = new NumericStepper(window.content, 80, 5);
_seedStepper.minimum = 1;
new Label(window.content, 5, 30, "Num novae:");
_numNovaeStepper = new NumericStepper(window.content, 80, 30);
_numNovaeStepper.minimum = 0;
new Label(window.content, 5, 55, "Nebula base X:");
_nebulaBaseXSlider = new HSlider(window.content, 80, 55);
_nebulaBaseXSlider.width = 80;
new Label(window.content, 5, 80, "Nebula base Y:");
_nebulaBaseYSlider = new HSlider(window.content, 80, 80);
_nebulaBaseYSlider.width = 80;
new Label(window.content, 5, 105, "Nebula colors:");
_nebulaRedCheck = new CheckBox(window.content, 80, 105, "R");
_nebulaGreenCheck = new CheckBox(window.content, 105, 105, "G");
_nebulaBlueCheck = new CheckBox(window.content, 130, 105, "B");
new Label(window.content, 5, 130, "Nebula threshold:");
_nebulaColorThresholdStepper = new NumericStepper(window.content, 80, 130);
_nebulaColorThresholdStepper.minimum = 0x00;
_nebulaColorThresholdStepper.maximum = 0xFF;
_nebulaColorThresholdStepper.width = 80;
var refreshButton:PushButton = new PushButton(window.content, 5, 155, "Refresh", function(e:Event):void { refresh(); } );
refreshButton.width = 75;
var randomizeButton:PushButton = new PushButton(window.content, 85, 155, "Randomize", function(e:Event):void { randomize(); } );
randomizeButton.width = 80;
// default values
_seedStepper.value = 1;
_numNovaeStepper.value = 20;
_nebulaBaseXSlider.setSliderParams(0, 1, 0.2);
_nebulaBaseYSlider.setSliderParams(0, 1, 0.2);
_nebulaRedCheck.selected =
_nebulaGreenCheck.selected =
_nebulaBlueCheck.selected = true;
_nebulaColorThresholdStepper.value = 0x90;
}
}
}
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
class CelestialTexture {
private static const ZERO_POINT:Point = new Point();
private static const TEMP_MATRIX:Matrix = new Matrix();
public static function createStarField(width:int, height:int, randomSeed:int = 0, intensity:Number = 0.02):BitmapData {
var texture:BitmapData = new BitmapData(width, height, true, 0xFF000000);
var tempTexture:BitmapData = new BitmapData(width, height, true, 0);
tempTexture.noise(randomSeed, 0, 255, BitmapDataChannel.RED, true);
texture.pixelDissolve(tempTexture, tempTexture.rect, ZERO_POINT, randomSeed, width * height * intensity);
tempTexture.dispose();
return texture;
}
public static function drawNebula(target:BitmapData, randomSeed:int = 0, colorChannels:uint = 7, colorThreshold:uint = 0x10, percentBaseX:Number = 0.2, percentBaseY:Number = 0.2, blur:Number = 8):void {
colorThreshold &= 0xFF;
if (colorChannels & BitmapDataChannel.RED) {
colorThreshold <<= 16;
}else if (colorChannels & BitmapDataChannel.GREEN) {
colorThreshold <<= 8;
}else if (!(colorChannels & BitmapDataChannel.BLUE)) {
return;
}
var tempTexture:BitmapData = new BitmapData(target.width, target.height, true, 0);
tempTexture.perlinNoise(target.width * percentBaseX, target.height * percentBaseY, 4, randomSeed, true, true, colorChannels, false);
tempTexture.threshold(tempTexture, tempTexture.rect, ZERO_POINT, "<", colorThreshold, 0x00FFFFFF, 0x00FFFFFF);
if(blur > 0) {
tempTexture.applyFilter(tempTexture, tempTexture.rect, ZERO_POINT, new BlurFilter(blur, blur));
}
target.draw(tempTexture, null, null, BlendMode.HARDLIGHT);
tempTexture.dispose();
}
public static function drawNova(target:BitmapData, numNovae:int, baseSize:Number, randomSeed:int = 0):void {
if (numNovae <= 0) {
return;
}
var randomPixels:BitmapData = new BitmapData(numNovae, 1, true);
randomPixels.noise(randomSeed, 0, 255);
var novaShape:Shape = new Shape();
var g:Graphics = novaShape.graphics;
TEMP_MATRIX.identity();
TEMP_MATRIX.scale(0.05, 1);
g.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0xFFFFFF], [1, 0], [0, baseSize / 4], TEMP_MATRIX);
g.drawCircle(0, 0, baseSize);
g.endFill();
TEMP_MATRIX.identity();
TEMP_MATRIX.scale(1, 0.05);
g.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0xFFFFFF], [1, 0], [0, baseSize / 4], TEMP_MATRIX);
g.drawCircle(0, 0, baseSize);
g.endFill();
target.lock();
for (var i:int = 0; i < numNovae; i++) {
var randomPixel:uint = randomPixels.getPixel(i, 0);
var rand1:Number = ((randomPixel & 0xFF0000) >> 16) / 255.0;
var rand2:Number = ((randomPixel & 0x00FF00) >> 8) / 255.0;
var rand3:Number = (randomPixel & 0x0000FF) / 255.0;
TEMP_MATRIX.identity();
TEMP_MATRIX.scale(rand3, rand3);
var size:Number = baseSize * rand3;
var tx:Number = target.width * rand1;
var ty:Number = target.height * rand2;
var top:Number = ty - size;
var bottom:Number = ty + size;
var left:Number = tx - size;
var right:Number = tx + size;
if(left < 0) tx -= left;
if(right > target.width) tx -= right - target.width;
if(top < 0) ty -= top;
if(bottom > target.height) ty -= bottom - target.height;
TEMP_MATRIX.translate(tx, ty);
target.draw(novaShape, TEMP_MATRIX, null, BlendMode.ADD, null, true);
}
target.unlock();
randomPixels.dispose();
}
}