In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

[1日1Wonderfl]5日目: 惑星っぽくなってきた

1日1Wonderfl 5/30日目
とりあえず惑星にしてみた。
*  質量の計算をまるっと抜かしてるので色々と物足りない。
*  あと、ぼつぼつコードに明らさまに汚ない部分が見え始めたので、
*  そこらへんを簡潔に書けるように試行錯誤していく。
*
*  前回 ColorMatrixFilter を使って BitmapData の色を変更していたのを
*  今回は ColorTransform 使ってみた。が、
*  どちらの方がコスト的に良いのかは未調査。近々テストしてみる。
*
*  frocessing に入ってる ColorHSV はものっそいツボ。
*  frocessing.color パッケージに入ってるのは全部良い感じ。な気がする。
// forked from soundkitchen's [1日1Wonderfl]4日目: 惑星なりそこない
// 1日1Wonderfl 5/30日目
/**
 *  とりあえず惑星にしてみた。
 *  質量の計算をまるっと抜かしてるので色々と物足りない。
 *  あと、ぼつぼつコードに明らさまに汚ない部分が見え始めたので、
 *  そこらへんを簡潔に書けるように試行錯誤していく。
 *
 *  前回 ColorMatrixFilter を使って BitmapData の色を変更していたのを
 *  今回は ColorTransform 使ってみた。が、
 *  どちらの方がコスト的に良いのかは未調査。近々テストしてみる。
 *
 *  frocessing に入ってる ColorHSV はものっそいツボ。
 *  frocessing.color パッケージに入ってるのは全部良い感じ。な気がする。
 */
package
{
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.filters.GlowFilter;
    import flash.geom.ColorTransform;

    import com.flashdynamix.utils.SWFProfiler;

    import frocessing.color.ColorHSV;

    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.core.data.UserData;
    import org.papervision3d.materials.BitmapMaterial;
    import org.papervision3d.materials.special.ParticleMaterial;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.objects.special.ParticleField;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;

    [SWF(width=465, height=465, frameRate=30, backgroundColor=0x000000)]

    /**
     *  document class.
     */
    public class Main extends Sprite
    {
        public static const NUM_PLANETS:uint = 6;
        public static const CAMERA_DISTANCE:uint = 2000;

        private var camera:Camera3D;
        private var renderer:BasicRenderEngine;
        private var scene:Scene3D;
        private var viewport:Viewport3D;

        private var root3d:DisplayObject3D;
        private var sun:Sphere;
        private var planets:Vector.<DisplayObject3D>;

        public function Main()
        {
            addEventListener(Event.ADDED_TO_STAGE, initialize);
        }

        private function initialize(evt:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, initialize);

            //  setup stage.
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.HIGH;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            //  set profiler.
            SWFProfiler.init(this);

            //  setup pv3d.
            setupPV3D();

            //  create background particle field.
            createBackground();

            //  create sun object.
            createSun();

            //  create planet object(s).
            createPlanets();

            addEventListener(Event.ENTER_FRAME, step);
        }

        /**
         *  setup papervision3d.
         */
        private function setupPV3D():void
        {
            //  camera.
            camera = new Camera3D();
            camera.zoom = 1.5;
            camera.focus = 200;
            camera.target = DisplayObject3D.ZERO;

            //  renderer.
            renderer = new BasicRenderEngine();

            //  scene.
            scene = new Scene3D();

            //  viewport.
            viewport = new Viewport3D(465, 465, true);
            addChild(viewport);

            //  create root container object.
            root3d = new DisplayObject3D();
            scene.addChild(root3d);
        }

        /**
         *  create background particle field.
         */
        private function createBackground():void
        {
            var mat:ParticleMaterial,
                obj:ParticleField;

            mat = new ParticleMaterial(0xa8a8a8, .7, ParticleMaterial.SHAPE_CIRCLE);
            obj = new ParticleField(mat, 500, 4, 4000, 4000, 4000);

            root3d.addChild(obj);
        }

        /**
         *  create sphere object as sun.
         */
        private function createSun():void
        {
            var bmd:BitmapData,
                mat:BitmapMaterial;

            bmd = new BitmapData(465, 465, true, 0);
            bmd.perlinNoise(465/8, 465/8, 8, 10, true, true, BitmapDataChannel.RED);
            mat = new BitmapMaterial(bmd);
            sun = new Sphere(mat, 800, 32, 24);
            sun.useOwnContainer = true;
            sun.filters = [
                new GlowFilter(0xff0000, .6, 64, 64, 2),
            ];

            root3d.addChild(sun);
        }

        /**
         *  create sphere object as planet(s).
         */
        private function createPlanets():void
        {
            var i:uint,
                s:Number,
                angle:Number,
                distance:Number,
                src:BitmapData,
                bmd:BitmapData,
                mat:BitmapMaterial,
                wrapper:DisplayObject3D,
                obj:Sphere,
                hsv:ColorHSV;

            s = 100;
            src = new BitmapData(s, s, true, 0);
            src.perlinNoise(s/8, s/8, 8, 20, true, true, BitmapDataChannel.RED, true);
            hsv = new ColorHSV(0, 1, 1, 1);

            planets = new Vector.<DisplayObject3D>(NUM_PLANETS, true);
            for (i=0; i<NUM_PLANETS; i++)
            {
                angle = Math.random() * Math.PI * 2;
                distance = Math.random() * 2000 + 1000;

                hsv.h = angle / Math.PI * 180;

                bmd = src.clone();
                bmd.colorTransform(bmd.rect, new ColorTransform(hsv.r/0xff, hsv.g/0xff, hsv.b/0xff, hsv.a, 0, 0, 0, 0));
                mat = new BitmapMaterial(bmd);
                obj = new Sphere(mat, 100, 12, 9);
                obj.x = Math.cos(angle) * distance;
                obj.z = Math.sin(angle) * distance;
                obj.useOwnContainer = true;
                obj.filters = [
                    new GlowFilter(hsv.value, .6, 16, 16, 2),
                ];

                //  TODO: fix this poor logic.
                obj.userData = new UserData({
                    'accel': (3000 - distance) / 2500
                });

                wrapper = new DisplayObject3D();
                wrapper.addChild(obj);
                root3d.addChild(wrapper);
                planets[i] = obj;
            }
        }

        /**
         *  will execute triggered enter frame event.
         */
        private function step(evt:Event):void
        {
            var angleX:Number, angleY:Number,
                accel:Number,
                obj:DisplayObject3D;

            angleX = (mouseX / stage.stageWidth) * Math.PI * 2;
            angleY = (mouseY / stage.stageHeight) * Math.PI * 2;

            //  TODO: fix this poor code.
            sun.rotationY -= .5;
            for each (obj in planets)
            {
                accel = obj.userData.data['accel'];
                obj.rotationY -= 2 * accel;
                DisplayObject3D(obj.parent).rotationY -= 1 * accel;
            }

            camera.x += (Math.sin(angleX) * CAMERA_DISTANCE - camera.x) * .2;
            camera.z += (Math.cos(angleX) * CAMERA_DISTANCE - camera.z) * .2;
            camera.y += (Math.sin(angleY) * CAMERA_DISTANCE - camera.y) * .2;

            renderer.renderScene(scene, camera, viewport);
        }
    }
}