ringAround(rosies); #songsInCode

August 21st, 2009 »

Felt like making a #songsInCode in haXe

and just for fun actually writing the code and compiling it to see how it might look.

ringAround(rosies);
for(girl in girls){
    girl.pocket.fill(new Posies());
}
ashes+=2;
for(girl in girls){
    girl.fall(DOWN);
}

result… meh.

You need Flash 10 to view the awesome. It’s a free and fast upgrade.

Full source

build.hxml

#build file
-cp src
-swf-version 9
-swf-header 550:450:30:F5F0D9
-main RingAroundTheRosy
-swf deploy/out.swf

RingAroundTheRosy.hx

/*
    Ring around the rosy
    A pocketful of posies
    "Ashes, Ashes"
    We all fall down!

    ringAround(rosies);
    for(girl in girls){
        girl.pocket.fill(new Posies());
    }
    ashes+=2;
    for(girl in girls){
        girl.fall(DOWN);
    }

    ringAround(rosies);
    for(girl in girls){ girl.pocket.fill(new Posies()); } 
    ashes+=2;
    for(girl in girls){ girl.fall(DOWN); } 
    #songsInCode

*/
import haxe.Timer;
import com.remixtechnology.Utils;
import flash.Lib;
import flash.events.Event;
class RingAroundTheRosy
{
    private var girls: Array<Girl>;
    private var rhyme_timer: Timer;
    private var rhyme_line_counter: Int;
    private var rhyme_lines: Array<String>;
    private var rosies: Rosies;
    private var ashes: Int;

    private static inline var DOWN: String = "DOWN";
    private static inline var GIRL_COUNT: Int = 5;
    private static inline var RHYME_SPEED: Int = 3000; // 3seconds
    private static inline var DANCE_SPEED: Float = .04; // girls rotating in circular motion
    private static inline var DANCE_RADIUS: Float = Rosies.RADIUS + Girl.RADIUS + 20;
    private static inline var DANCE_PADDING: Float = 1.3; // hard coded, but should be calculated off known radiuses
    private static var RHYME_LINES: Array<String> = [
        '"Ring around the rosy"',
        '"A pocketful of posies"',
        '"Ashes, Ashes"',
        '"We all fall down!"'
    ];
    private static var RHYME_IN_CODE_LINES: Array<String> = [
"ringAround(rosies);",
"for(girl in girls){
    girl.pocket.fill(new Posies());
}",
"ashes+=2;",
"for(girl in girls){
    girl.fall(DOWN);
}"
    ];
    private static inline var RHYME_COLOR: UInt = 0x812030;
    private static inline var SPAWN_WICKED_GIRLS_LINE: Int = 0;
    private static inline var FILL_POCKETS_LINE: Int = 1;
    private static inline var SENSELESS_ASHES_LINE: Int = 2;
    private static inline var DESTROY_ALL_GIRLS_LINE: Int = 3;

    public function new()
    {
        rhyme_timer = new Timer(RHYME_SPEED);
        rhyme_timer.run = rhyme_tick;
        rhyme_lines = RHYME_LINES;

        Utils.updateTrace("");
        Utils.stf.setColor(RHYME_COLOR);

        rosies = new Rosies();
        Lib.current.addChild(rosies);

    }

    private inline function rhyme_tick(  ): Void
    {
        Utils.trace(rhyme_lines[rhyme_line_counter]);

        switch(rhyme_line_counter){

            case SPAWN_WICKED_GIRLS_LINE:

                ringAround(rosies);

            case FILL_POCKETS_LINE:

                for(girl in girls){
                    girl.pocket.fill(new Posies());
                }

            case SENSELESS_ASHES_LINE:

                ashes+=2;

            case DESTROY_ALL_GIRLS_LINE:

                for(girl in girls){
                    girl.fall(DOWN);
                }
        }

        if(rhyme_line_counter++ == rhyme_lines.length){
            rhyme_line_counter = 0;
            if(rhyme_lines == RHYME_LINES){
                rhyme_lines = RHYME_IN_CODE_LINES;
            }else{
                rhyme_lines = RHYME_LINES;
            }
            Utils.updateTrace("");
        }
    }

    private inline function ringAround( target:Rosies ): Void
    {
        girls = new Array<Girl>();

        var i:Int;
        var girl:Girl;
        for(i in 0...GIRL_COUNT){

            // initial position
            girl = new Girl(this);
            girls.push(girl);
            girl.pocket.x = Math.sin(i) * Girl.RADIUS;
            girl.pocket.y = Math.cos(i) * Girl.RADIUS;
            girl.angle = i*DANCE_PADDING;
            girl.x = rosies.x + Math.sin(girl.angle) * DANCE_RADIUS;
            girl.y = rosies.y + Math.cos(girl.angle) * DANCE_RADIUS;
            Lib.current.addChild(girl);

            // add loop
            girl.addEventListener(Event.ENTER_FRAME, loop);
        }
    }

    public inline function loop(event:Event):Void{
        var girl:Girl = cast(event.target, Girl);
        girl.x = rosies.x + Math.sin(girl.angle) * DANCE_RADIUS;
        girl.y = rosies.y + Math.cos(girl.angle)  * DANCE_RADIUS;
        girl.angle += DANCE_SPEED;
    }

    public static function main(): Void
    {
        var m: RingAroundTheRosy = new RingAroundTheRosy();
    }
}

Girl.hx

import flash.display.Sprite;
import flash.events.Event;
import flash.Lib;
class Girl extends Sprite{

    private var main: RingAroundTheRosy;
    private var fallspeed: Float;

    public var pocket: Pocket;
    public var angle: Float;

    private static inline var COLOR: UInt = 0xF093BC;
    public static inline var RADIUS: Float = 20; // girls that reveal their true weight O_O
    private static inline var FALL_FACTOR: Float = 1.5;

    public function new( _main:RingAroundTheRosy )
    {
        main = _main;
        super();
        graphics.beginFill(COLOR);
        graphics.drawCircle(0,0,RADIUS);
        graphics.endFill();

        pocket = new Pocket(); // yes they can only afford one
        addChild(pocket);

        addEventListener(Event.ENTER_FRAME, loop);

        fallspeed = 1;
    }

    private inline function loop( _ ): Void
    {
        rotation++;
    }

    private function falling( _ ): Void
    {
        y+= fallspeed *= FALL_FACTOR;
        if(y > Lib.current.stage.stageHeight + RADIUS){
            Lib.current.removeChild(this);
            removeEventListener(Event.ENTER_FRAME, loop);
            removeEventListener(Event.ENTER_FRAME, main.loop);
            removeEventListener(Event.ENTER_FRAME, falling);
        }
    }

    public inline function fall( where:String ): Void
    {
        // "where" does nothing really
        addEventListener(Event.ENTER_FRAME, falling);
    }
}

Pocket.hx

import flash.display.Sprite;
import flash.display.DisplayObject;
class Pocket extends Sprite{

    private static inline var COLOR: UInt = 0xA0538C;
    private static inline var RADIUS: Float = 10;

    public function new(  )
    {
        super();
        graphics.beginFill(COLOR);
        graphics.drawCircle(0,0,RADIUS);
        graphics.endFill();
    }

    public inline function fill( stuff:DisplayObject ): Void
    {
        addChild(stuff);
    }
}

Posies.hx

import flash.display.Sprite;
class Posies extends Sprite{

    private static inline var COLOR: UInt = 0x9F8F23;
    private static inline var RADIUS: Float = 6;

    public function new(  )
    {
        super();
        graphics.beginFill(COLOR);
        graphics.drawCircle(0,0,RADIUS);
        graphics.endFill();
    }
}

Rosies.hx

import flash.display.Sprite;
import flash.events.Event;
import flash.Lib;
class Rosies extends Sprite{

    private static inline var COLOR: UInt = 0x450408;
    public static inline var RADIUS: Float = 35;

    public function new(  )
    {
        super();
        graphics.beginFill(COLOR);
        graphics.drawCircle(0,0,RADIUS);
        graphics.endFill();

        addEventListener(Event.ENTER_FRAME, loop);
    }

    private inline function loop( _ ): Void
    {
        x = Lib.current.mouseX;
        y = Lib.current.mouseY;
    }
}

com.remixtechnology.Utils

snippet, not full class file, only includes methods used for this app

package com.remixtechnology;
import flash.Lib;
import flash.Error;
import flash.display.Stage;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
class Utils{
    public static var stf:ShadowedTextField;


    public static inline function trace(obj:Dynamic):Void{
        if(stf == null){
            stf = new ShadowedTextField();
            Lib.current.stage.addChild(stf);
            stf.setText(Std.string(obj));
        }else{
            stf.appendText(Std.string(obj));
        }
    }
    public static function updateTrace(obj:Dynamic):Void{
        if(stf != null){
            stf.setText(Std.string(obj));
        }else{
            Utils.trace(obj);
        }
    }

}

com.remixtechnology.ShadowedTextField

package com.remixtechnology;

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.AntiAliasType;

class ShadowedTextField extends Sprite
{

    private var fgColor:UInt;
    private var bgColor:UInt;
    private var xoff:Float;
    private var yoff:Float;

    private var tfFore:TextField;
    private var tfBack:TextField;
    private var fmtFore:TextFormat;
    private var fmtBack:TextFormat;

    private var size:Int;
    private var font:String;

    public function new( ?text:String )
    {
        bgColor = 0x000000;
        fgColor = 0xFFCC00;
        xoff = 1;
        yoff = 1;
        size = 14;
        font = 'Verdana';

        mouseChildren = false;
        mouseEnabled = false;

        tfBack = new TextField();
        tfBack.autoSize = TextFieldAutoSize.LEFT;
        tfBack.selectable = false;
        tfBack.x = xoff;
        tfBack.y = yoff;
        addChild(tfBack);

        tfFore = new TextField();
        tfFore.autoSize = TextFieldAutoSize.LEFT;
        tfFore.selectable = false;
        addChild(tfFore);

        fmtFore = new TextFormat();
        fmtFore.color = fgColor;
        fmtFore.size = size;
        fmtFore.font = font;
        fmtFore.bold = true;

        fmtBack = new TextFormat();
        fmtBack.color = bgColor;
        fmtBack.size = size;
        fmtBack.font = font;
        fmtBack.bold = true;

        if(text != null) setText(text);

        super();
    }

    public inline function setText(n:String):Void
    {
        tfFore.text = n;
        tfFore.setTextFormat(fmtFore);

        tfBack.text = n;
        tfBack.setTextFormat(fmtBack);
    }

    public inline function appendText(n:String):Void
    {
        tfFore.appendText("\n" + n);
        tfFore.setTextFormat(fmtFore);

        tfBack.appendText("\n" + n);
        tfBack.setTextFormat(fmtBack);
    }

    public inline function setColor(color:UInt):Void
    {
        fmtFore.color = color;
        tfFore.setTextFormat(fmtFore);
    }

    public inline function setShadowColor(color:UInt):Void
    {
        fmtBack.color = color;
        tfBack.setTextFormat(fmtBack);
    }

    public inline function setSize(size:Int):Void{
        fmtFore.size = size;
        tfFore.setTextFormat(fmtFore);

        fmtBack.size = size;
        tfBack.setTextFormat(fmtBack);
    }

    public inline function bold(b:Bool):Void{
        if(b){
            fmtFore.bold = true;
            fmtBack.bold = true;
        }else{
            fmtFore.bold = false;
            fmtBack.bold = false;
        }
    }

}

Say Anything