Toggle navigation
Sign Up
Log In
Explore
Works
Folders
Tools
Collections
Artists
Groups
Groups
Topics
Tasks
Tasks
Jobs
Teams
Jobs
Recommendation
More Effects...
ActionScript
/* see: http://wonderfl.net/blog/2010/04/wonderfliphone.html open this url in your iPhone Safari! http://wonderfl.net/code/fa4c79ba8c8a892b7f76175360a3a0729f0507eb/fullscreen or shorter http://tinyurl.com/yasmwse */ package { import flash.display.*; import flash.events.Event; import flash.events.MouseEvent; import flash.net.URLLoader; import flash.net.URLRequest; public class Tree extends Sprite{ public function Tree(){ var cfdg :String = <>>; start( cfdg ); } private function start( cfdg :String ) :void { var art :ContextFreeArt = new ContextFreeArt( cfdg, 640, 640 ); addChild( art ); stage.addEventListener( MouseEvent.CLICK, function(ev:MouseEvent) :void { art.tick(); }); } } } function log(...args) :void {} //package jp.maaash { import flash.display.Sprite; ////////import jp.maaash.contextfreeart.Tokenizer; //import jp.maaash.contextfreeart.Compiler; //import jp.maaash.contextfreeart.Renderer; //public class ContextFreeArt extends Sprite { [SWF(width=660,height=660,backgroundColor=0xffffff,frameRate=60)] class ContextFreeArt extends Sprite { private var renderer :Renderer; public function ContextFreeArt( cfdg_text :String, width :Number = 640, height :Number = 640 ) { var t :Tokenizer = new Tokenizer; var tokens :Array = t.tokenize( cfdg_text ); var c :Compiler = new Compiler; var compiled :Object = c.compile( tokens ); logger("compiled: ",compiled); renderer = new Renderer( width, height ); renderer.clearQueue(); renderer.render( compiled, this ); } public function tick() :void { renderer.tick(); } private function logger(... args) :void { if ( 1 ) { return; } log.apply(null, (new Array("[ContextFreeArt]", this)).concat(args)); } } //} //package jp.maaash.contextfreeart { //import jp.maaash.contextfreeart.state.*; import flash.utils.getDefinitionByName; //public class Compiler{ class Compiler{ private const keywords :Array = [ "startshape", "rule", "background" ]; public var compiled :Object = {}; public var state :IState; private var curKey :String; private var curValues :Array; private var obj :Object; public function Compiler(){ } public function compile( tokens :Array ) :Object { state = new General; while ( tokens.length > 0 ) { var token :String = tokens.shift(); var nextState :Array = state.eat( token, this ); //logger("[compile]token: "+token+" nextState: "+nextState); if ( nextState ) { next( nextState ); } } return compiled; } private function next( state_and_args :Array ) :void { var className :String = state_and_args.shift(); // uppercase the 1st char className = className.substr(0,1).toUpperCase() + className.substr(1); switch( className ) { case "Startshape": state = new Startshape; break; case "General": state = new General; break; case "Background": state = new Background; break; case "Rule": state = new Rule; break; case "RuleWeight": state = new RuleWeight( state_and_args ); break; case "RuleDraw": state = new RuleDraw( state_and_args ); break; case "ShapeAdjustment": state = new ShapeAdjustment( state_and_args ); break; default: throw('unknown className: '+className); } } private function logger(... args) :void { if ( 1 ) { return; } log.apply(null, (new Array("[compiler]", this)).concat(args)); } } //} //package jp.maaash.contextfreeart { //public class Tokenizer{ class Tokenizer{ private var input :String; private const stopChars :Array = [" ", "{", "}", "\n", "\r", "\t"]; public function Tokenizer() { } // TODO: String comments // TODO: Handle ordered arguments (i.e., square brakets) // TODO: Handle the | operator public function tokenize( _input :String ) :Array { input = _input; // To make it easier to parse, we pad the brackets with spaces. input = input.replace( /([{}])/g, " $1"); var tokens :Array = new Array; var head :Object = { lastPos: 0 }; while( 1 ) { head = tokenizeNext( head.lastPos ); if ( head == null ) { break; } if ( head.token ) { tokens.push( head.token ); } } logger("[tokenize]tokens: ",tokens); return tokens; } private function tokenizeNext( pos :Number ) :Object { var stops :Array = new Array; var len :int = stopChars.length; for ( var i:int=0; i
0 ) { if ( queue.length > 0 ) { isRendering = true; var concurrent :int = Math.min( queue.length - 1, maxThreads ); for ( var i :int=0; i <= concurrent; i++ ) { var args :Array = queue.shift(); drawRule.apply( null, args ); } center(); } } private function center() :void { var rect :Rectangle = container.getRect( container ); // resize centeringScale = Math.min( width / rect.width, height / rect.height ) * 0.9; centeringMatrix.a = centeringMatrix.d = centeringScale; // centering centeringMatrix.tx = width /2 - (rect.left + rect.right ) / 2 * centeringScale; centeringMatrix.ty = height/2 - (rect.top + rect.bottom) / 2 * centeringScale; container.transform.matrix = centeringMatrix; //logger("[center]mtx,rect,container: ",centeringMatrix,rect,container); } private function draw() :void { var ruleName :String = compiled.startshape; var foregroundColor :Color = new Color; drawRule( ruleName, new Matrix, foregroundColor ); } private function drawRule( ruleName :String, mtx :Matrix, color :Color, priority :Number = 0 ) :void { //logger("[drawRule]ruleName: "+ruleName+" mtx: ",mtx); // When things get too small, we can stop rendering. // Too small, in this case, means less than half a pixel. if( Math.abs( mtx.a ) * globalScale * centeringScale < 0.5 && Math.abs( mtx.b ) * globalScale * centeringScale < 0.5 ){ //logger("[drawRule]return"); return; } var shape :Object = chooseShape( ruleName ); drawShape( shape, mtx, color, priority ); } private function chooseShape( ruleName :String ) :Object { // Choose which rule to go with... //logger("[chooseShape]ruleName: "+ruleName); var choices :Array = compiled[ ruleName ]; if ( ! choices ) { throw("no rule found for "+ruleName); } var sum :Number = 0; for( var i :int=0; i
360){ h -= 360; } var r :Number, g :Number, b :Number; if (h < 120){ r = (120 - h) / 60; g = h / 60; b = 0; }else if (h < 240){ r = 0; g = (240 - h) / 60; b = (h - 120) / 60; }else{ r = (h - 240) / 60; g = 0; b = (360 - h) / 60; } r = Math.min(r, 1); g = Math.min(g, 1); b = Math.min(b, 1); r = 2 * s * r + (1 - s); g = 2 * s * g + (1 - s); b = 2 * s * b + (1 - s); if (l < 0.5){ r = l * r; g = l * g; b = l * b; }else{ r = (1 - l) * r + 2 * l - 1; g = (1 - l) * g + 2 * l - 1; b = (1 - l) * b + 2 * l - 1; } r = Math.ceil(r * 255); g = Math.ceil(g * 255); b = Math.ceil(b * 255); // Putting a semicolon at the end of an rgba definition // causes it to not work. //return "rgba(" + r + ", " + g + ", " + b + ", " + a + ")"; //
,
to do: graphics.beginFill.apply( null, color.split(',') ) return [ (r * 256*256 + g * 256 + b), a ]; } // hsba to hsba private function adjustColor( adjs :Adjustment, color :Color ) :Color { // See http://www.contextfreeart.org/mediawiki/index.php/Shape_adjustments var newColor :Color = new Color; newColor.h = color.h; newColor.s = color.s; newColor.b = color.b; newColor.a = color.a; // Add num to the drawing hue value, modulo 360 newColor.h += adjs.hue; newColor.h %= 360; // If adj<0 then change the drawing [blah] adj% toward 0. // If adj>0 then change the drawing [blah] adj% toward 1. if ( adjs.saturation != 0 ) { if( adjs.saturation > 0 ){ newColor.s += adjs.saturation * (1-color.s); } else { newColor.s += adjs.saturation * color.s; } } if ( adjs.brightness != 0 ) { if( adjs.brightness > 0 ){ newColor.b += adjs.brightness * (1-color.b); } else { newColor.b += adjs.brightness * color.b; } } if ( adjs.alpha != 0 ) { if( adjs.alpha > 0 ){ newColor.a += adjs.alpha * (1-color.a); } else { newColor.a += adjs.alpha * color.a; } } return newColor; } public function clearQueue() :void { queue = new Array; } private function logger(... args) :void { if ( 1 ) { return; } log.apply(null, (new Array("[Renderer]", this)).concat(args)); } } //} //package jp.maaash.contextfreeart { //public class Color { class Color { public var h :Number = 0; public var s :Number = 0; public var b :Number = 0; public var a :Number = 1; public function Color(){ } } //} //package jp.maaash.contextfreeart { //public class Adjustment{ class Adjustment{ public var name :String; public var flipDefined :Boolean = false; public var flip :Number; public var sizeX :Number = 1; public var sizeY :Number = 1; public var rotate :Number = 0; public var x :Number = 0; public var y :Number = 0; public var hue :Number = 0; public var saturation :Number = 0; public var brightness :Number = 0; public var alpha :Number = 0; public function Adjustment() { } public function fill( obj :Object ) :void { for( var key :String in obj ){ switch( key ) { case "f": case "flip": flipDefined = true; flip = obj[key]; break; case "s": case "size": var size :* = obj[key]; if ( typeof(size) == "number" ) { size = [size,size]; } sizeX = size[0]; sizeY = size[1]; break; case "r": rotate = obj[key]; break; case "h": hue = obj[key]; break; case "sat": saturation = obj[key]; break; case "b": brightness = obj[key]; break; case "a": alpha = obj[key]; break; case "rotate": case "x": case "y": case "hue": case "saturation": case "brightness": case "alpha": this[key] = obj[key]; break; default: throw("unsupported adjustment: "+key); } } } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //public class Rule implements IState { class Rule implements IState { public function Rule(){ } public function eat( token :String, compiler :Compiler ) :Array { var ruleName :String = token; // Create a blank rule if it doesn't aleady exist if ( ! compiler.compiled[ ruleName ] ) { compiler.compiled[ ruleName ] = []; } return [ "ruleWeight", ruleName ]; } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //public class RuleDraw implements IState { class RuleDraw implements IState { private var weight :Number = 1; private var ruleName :String; public function RuleDraw( args :Array ) { ruleName = args[0]; } public function eat( token :String, compiler :Compiler ) :Array { if( token == "}" ){ return [ "general" ]; } return [ "shapeAdjustment", token, ruleName ]; } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //public class Startshape implements IState { class Startshape implements IState { public function Startshape() { } public function eat( token :String, compiler :Compiler ) :Array { // uppercase the 1st char compiler.compiled[ "startshape" ] = token; return [ "general" ]; } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //public class AbstractArgument implements IState { class AbstractArgument implements IState { protected var curKey :String = null; protected var curValues :Array = []; protected var obj :Object = {}; protected var compiler :Compiler; public function AbstractArgument(){ } public function eat( token :String, _compiler :Compiler ) :Array { compiler = _compiler; switch ( token ) { case "}": flushKey(); return onDone( obj ); case "{": return null; } // If it's a keyword name... if( token.match(/[a-z_]+/i) ) { flushKey(); curKey = token; curValues = []; } // Otherwise it's a value (and hence a number) else { curValues.push( parseFloat(token) ); } return null; } protected function onDone( obj :Object ) :Array { return null; } // abstract protected function flushKey() :void { if ( curKey ) { // If there is only one value for the key, we don't need to wrap // it in an array. if ( curValues.length == 1 ) { obj[ curKey ] = curValues[0]; } else { obj[ curKey ] = curValues; } } } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //import jp.maaash.contextfreeart.Adjustment; //public class Background extends AbstractArgument { class Background extends AbstractArgument { public function Background() { } override protected function onDone( obj :Object ) :Array { var adj :Adjustment = new Adjustment; adj.fill( obj ); compiler.compiled[ "background" ] = adj; compiler = null; return [ "general" ]; } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //import jp.maaash.contextfreeart.Adjustment; //public class ShapeAdjustment extends AbstractArgument { class ShapeAdjustment extends AbstractArgument { private var name :String; private var ruleName :String; public function ShapeAdjustment( args :Array ) { name = args[0]; ruleName = args[1]; } override protected function onDone( obj :Object ) :Array { trace(this + ".onDone(obj :Object ) : " + obj ); var shape :Adjustment = new Adjustment(); shape.name = name; shape.fill( obj ); // We are always adding to the lastest rule we've created. var last :int = compiler.compiled[ ruleName ].length - 1; compiler.compiled[ ruleName ][ last ].draw.push( shape ) compiler = null; return [ "ruleDraw", ruleName ]; } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //public interface IState { interface IState { function eat( token :String, compiler :Compiler ) :Array; } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //public class RuleWeight implements IState { class RuleWeight implements IState { private var weight :Number = 1; private var ruleName :String; public function RuleWeight( args :Array ) { ruleName = args[0]; } public function eat( token :String, compiler :Compiler ) :Array { if ( token != "{" ) { weight = parseFloat( token ); return null; } else { // "{" compiler.compiled[ ruleName ].push({ weight: weight, draw: [] }); return [ "ruleDraw", ruleName ]; } } } //} //package jp.maaash.contextfreeart.state { //import jp.maaash.contextfreeart.Compiler; //public class General implements IState { class General implements IState { public function General(){ } public function eat( token :String, compiler :Compiler ) :Array { return [ token ]; } } //}
Join Effecthub.com
Working with Global Gaming Artists and Developers!
Login
Sign Up
Or Login with Your Email Address:
Email
Password
Remember
Or Sign Up with Your Email Address:
Your Email
This field must contain a valid email
Set Password
Password should be at least 1 character
Stay informed via email