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

forked from: forked from: 万有引力のお勉強

万有引力のお勉強

書籍「FLASH LAB」のsatelliteという項目を
自分なりに租借してAS3で組みなおしてみました。
惑星がひとつだったり、出現の仕方がちょっと違いますが、
まぁ(面倒だったので)アレンジ的な感じで。

真ん中の惑星(?)はドラッグ可能です。
なんか軌道が変わりまくってるから、多分計算が違うのかなぁ・・・。

ついでにZ軸もつけてみました。
FP10になって焦点距離とか考えなくてよくなったのは
うれしいですね。ここら辺もうちょっと勉強しないと
損かなと実感。

衛星の最大移動距離が惑星より小さいと
惑星の中から衛星が出てきて不恰好な状態に・・・。

あとは全体的に不恰好なんで、エフェクトとか模様とか
付けてみたい気がします。

(5/2 6:47 単純な間違いをしてたと思って治したら更に悪化・・・
Z軸の計算間違ってるっぽい気が・・・)
// forked from runouw's forked from: 万有引力のお勉強
// forked from Hiiragi's 万有引力のお勉強
package 
{
    /* 万有引力のお勉強
     * 
     * 書籍「FLASH LAB」のsatelliteという項目を
     * 自分なりに租借してAS3で組みなおしてみました。
     * 惑星がひとつだったり、出現の仕方がちょっと違いますが、
     * まぁ(面倒だったので)アレンジ的な感じで。
     * 
     * 真ん中の惑星(?)はドラッグ可能です。
     * なんか軌道が変わりまくってるから、多分計算が違うのかなぁ・・・。
     * 
     * ついでにZ軸もつけてみました。
     * FP10になって焦点距離とか考えなくてよくなったのは
     * うれしいですね。ここら辺もうちょっと勉強しないと
     * 損かなと実感。
     * 
     * 衛星の最大移動距離が惑星より小さいと
     * 惑星の中から衛星が出てきて不恰好な状態に・・・。
     * 
     * あとは全体的に不恰好なんで、エフェクトとか模様とか
     * 付けてみたい気がします。
     * 
     * (5/2 6:47 単純な間違いをしてたと思って治したら更に悪化・・・
     * Z軸の計算間違ってるっぽい気が・・・)
     */
    import flash.display.Sprite;
    import flash.events.Event;
    import com.flashdynamix.utils.SWFProfiler
    import flash.events.MouseEvent;
    
    [SWF(width=465,height=465,frameRate=30,backgroundColor=0x000000)]

    public class Main extends Sprite 
    {

        private var targetPlanet:planet = new planet(0x0000FF, 20);
        
        private var satelliteNum:uint = 50;
        private var satelliteArray:Vector.<planet> = new Vector.<planet>;

        private const MG:Number = 1;
                private const TIME:Number = 0.5;
        
        private var maxSpeed:Number = 20;
        
        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);

            SWFProfiler.init(this);
            
            targetPlanet.x = stage.stageWidth / 2;
            targetPlanet.y = stage.stageHeight / 2;
            targetPlanet.z = 0;
            targetPlanet.name = "targetPlanet";
            
            targetPlanet.addEventListener(MouseEvent.MOUSE_DOWN, onPlanetMouseDown);
            targetPlanet.addEventListener(MouseEvent.MOUSE_UP, onPlanetMouseUp);
            satelliteArray.push(targetPlanet);
            
            this.addChild(targetPlanet);
            
            var cp_x:Number = stage.stageWidth / 2;
            var cp_y:Number = stage.stageHeight / 2;
            
            for (var i:uint = 0; i < satelliteNum; i++) {
                //var p:planet = new planet(0xFF6600, 3);
                var p:planet = new planet(Math.random()*0xAAAAAA+0x555555, 3);
                p.x = cp_x + Math.random() * 100 - 50;
                p.y = cp_y + Math.random() * 100 - 50;
                this.addChild(p);
                satelliteArray.push(p);
            }
            
            this.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
        }
        
        private function onPlanetMouseUp(e:MouseEvent):void 
        {
            var p:planet = e.target as planet;
            p.stopDrag();
        }
        
        private function onPlanetMouseDown(e:MouseEvent):void 
        {
            var p:planet = e.target as planet;
            p.startDrag();
        }
        
        private function onEnterFrameHandler(e:Event):void 
        {
            //satelliteArray.forEach(movePlanet);
                        for each(var p:planet in satelliteArray){
                            for each(var s:planet in satelliteArray){
                                if(p!==s){
                                    // planets now have a gravitational pull on each other
                                    movePlanet(p,s)
                                }
                            }
                            if(p.name != "targetPlanet"){ 
                                p.x += p.vx*TIME;
                        p.y += p.vy*TIME;
                    p.z += p.vz*TIME;
                            }
                        }
            
            //zSort
            satelliteArray.sort(function(x:planet, y:planet):Number { return y.z - x.z; } );
            var num:uint = satelliteArray.length;
            for (var i:uint = 0; i < num; i++) {
                this.setChildIndex(satelliteArray[i], i);
            }
        }
        
        private function movePlanet(item:planet, targetPlanet:planet):void
        {
            if (item.name != "targetPlanet") {
                var dx:Number = targetPlanet.x - item.x;
                var dy:Number = targetPlanet.y - item.y;
                var dz:Number = targetPlanet.z - item.z;
                
                                // using a faster alternative than trig...

                //var radXY:Number = Math.atan2(dy, dx);
                //var radYZ:Number = Math.atan2(dy, dz);
                
                //var distanceXY:Number = dx * dx + dy * dy;
                //var distanceYZ:Number = dy * dy + dz * dz;

                                
                
                //var aXY:Number = MG / (distanceXY + 4000);
                                    //var aYZ:Number = MG / (distanceYZ + 4000);
                //var aYZ:Number = MG / (distanceXY + 4000);
                
                //var aXY_x:Number = aXY * Math.cos(radXY);
                     //var aXY_y:Number = aXY * Math.sin(radXY);
                                     //var aXY_y:Number = aXY * Math.sin(radYZ);
                //var aYZ_z:Number = aYZ * Math.cos(radYZ);
                
                                var d:Number = Math.sqrt(dx * dx + dy * dy + dz * dz);
                                var g:Number = MG/(d); // should be d*d*d
                                if (targetPlanet.name == "targetPlanet") {
                                    g *= 5;
                                }
                                
                item.vx += (dx/d)*g*TIME;
                item.vy += (dy/d)*g*TIME;
                item.vz += (dz/d)*g*TIME;
                
                //limiter
                if (item.vx > maxSpeed) {
                    item.vx = maxSpeed;
                } else if (item.vx < -maxSpeed) {
                    item.vx = -maxSpeed;
                }
                
                if (item.vy > maxSpeed) {
                    item.vy = maxSpeed;
                } else if (item.vy < -maxSpeed) {
                    item.vy = -maxSpeed;
                }
                
                
            }

        }
        
    }
    
}

import flash.display.Sprite;

internal class planet extends Sprite{
    
    private var _vx:Number = Math.random() * 20 - 10;
    private var _vy:Number = Math.random() * 20 - 10;
    private var _vz:Number = Math.random() * 20 - 10;
    
    public function planet(color:uint,size:uint) {
        this.graphics.beginFill(color);
        this.graphics.drawCircle(0, 0, size);
        this.graphics.endFill();
    }
    
    public function get vx():Number {
        return _vx;
    }
    
    public function set vx(arg1:Number):void {
        _vx = arg1;
    }
    
    public function get vy():Number {
        return _vy;
    }
    
    public function set vy(arg1:Number):void {
        _vy = arg1;
    }
    
    public function get vz():Number {
        return _vz;
    }
    
    public function set vz(arg1:Number):void {
        _vz = arg1;
    }
}