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

太陽系を通過せよ!

「ただの太陽系」に惑星の引力を実装してみました。
惑星間の引力による相互作用は高度すぎて僕にはちょっと分かりませんので、
ひとまずそれぞれの惑星に引力を持たせ、宇宙船のみが全ての惑星の
引力の影響を受けるようにしています。

画面をクリックするとスタートし、宇宙船がオートパイロットで
太陽系を斜めに横切ります。
途中で惑星の引力に負けると惑星に墜落。
逆に引力を利用して加速することもできます。

このコードをベースとして、来週くらいにはもう少し演出を加え
面白味を持たせたバージョンに改良したいと思います。
今のコードではゴールまで到達しても何の達成感も感じられないし…
Get Adobe Flash player
by mousepancyo 24 Jul 2010
/**
 * Copyright mousepancyo ( http://wonderfl.net/user/mousepancyo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/8vXm
 */

/*
「ただの太陽系」に惑星の引力を実装してみました。
惑星間の引力による相互作用は高度すぎて僕にはちょっと分かりませんので、
ひとまずそれぞれの惑星に引力を持たせ、宇宙船のみが全ての惑星の
引力の影響を受けるようにしています。

画面をクリックするとスタートし、宇宙船がオートパイロットで
太陽系を斜めに横切ります。
途中で惑星の引力に負けると惑星に墜落。
逆に引力を利用して加速することもできます。

このコードをベースとして、来週くらいにはもう少し演出を加え
面白味を持たせたバージョンに改良したいと思います。
今のコードではゴールまで到達しても何の達成感も感じられないし…
*/
package{
    import flash.display.Sprite
    import flash.events.Event;
    import flash.geom.Point;
    import flash.display.Shape;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.text.TextFormat;
    
    [SWF(width=465, height=465, backgroundColor=0,frameRate=30)]
    
    public class Main extends Sprite{
        
        private var _circleList:Vector.<Circle> = new Vector.<Circle>()
        private var _motionList:Vector.<CircleMotion> = new Vector.<CircleMotion>()
        private var _ship:Ship
        private var _tracer:Shape = new Shape()
        private var _msg:TextField = new TextField()
        private var _fmt:TextFormat = new TextFormat("_typewriter", 14, 0xFFFFFF, true, false, false, null, null, "center")
        //
        private const _sizeList:Vector.<int> = Vector.<int>([3, 4, 6, 4, 16, 18, 12, 10])
        private const _speedList:Vector.<Number> = Vector.<Number>([4.166,1.64,1,0.53,0.084,0.034,0.012,0.0061])
        private const _radList:Vector.<int> = Vector.<int>([30, 50, 75, 100, 125, 160, 190,220])
        private const _gravityList:Vector.<int> = Vector.<int>([30, 40, 60, 40, 160, 180, 120, 100])
        private const _circleColorList:Vector.<int> = Vector.<int>([0xB3B0B8, 0xADA224, 0x2DD0AB, 0xB34D0C, 0x907853, 0xA08B14, 0x83AAD7, 0x2D7DB8])
        private const _deceleration:Number = 0.2
        private const _shipSpeed:Number = 0.5
        private const _incidence:int = 1000
        
        public function Main(){
            init() 
        }
        
        private function init():void{
            var base:Base = new Base(0, stage.stageWidth, stage.stageHeight)
            addChild(base)
            var start_tx:TextField = new TextField()
            var goal_tx:TextField = new TextField()
            start_tx.defaultTextFormat = _fmt
            goal_tx.defaultTextFormat = _fmt
            start_tx.selectable = false
            goal_tx.selectable = false
            start_tx.autoSize = "left"
            goal_tx.autoSize = "right"
            start_tx.text = "[Start]"
            goal_tx.text = "[Goal]"
            goal_tx.x = stage.stageWidth-goal_tx.width
            goal_tx.y = stage.stageHeight-goal_tx.height
            addChild(start_tx)
            addChild(goal_tx)
            //
            for(var i:int=0; i<_sizeList.length; i++){
                var col:int = 0x303030
                createPlanet(_circleColorList[i], _sizeList[i], _speedList[i]*_deceleration, _radList[i], _gravityList[i])
                _circleList[i].addEventListener(Event.ENTER_FRAME, update)
                base.graphics.lineStyle(1, col, 1, true, "normal",null, null, 1)
                base.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2, _radList[i])    
            }
            createMoon()
            createRing()
            //
            _msg.defaultTextFormat = _fmt
            _msg.selectable = false
            _msg.width = stage.stageWidth
            _msg.y = 370
            _msg.autoSize = "center"
            _msg.text = "惑星の引力に捕まらないようゴール地点を目指そう\nAim to finish at the planet's gravity to catch.\n\nステージクリックでスタート\nClick on the Start Stage."
            addChild(_msg)
            //
            addChild(_tracer)
            stage.addEventListener(MouseEvent.CLICK, shipStart)
        }
        
        private function shipStart(e:MouseEvent):void{
            _ship = new Ship()
            addChild(_ship)
            _ship.addEventListener(Event.ENTER_FRAME, shipUpdate)
            _tracer.graphics.clear()
            _tracer.graphics.lineStyle(1, 0x33FF66, 0.5)
            _tracer.graphics.moveTo(_ship.x, _ship.y)
            stage.removeEventListener(MouseEvent.CLICK, shipStart)
            for(var i:int=0; i<_circleList.length; i++){
                _circleList[i].addEventListener(Circle.CRASH, crashCheck)
            }
            _msg.text = ""
        }
        
        private function createPlanet(color:int, size:int, speed:Number, rad:Number, grav:int):void{
            var circle:Circle = new Circle(color, size, speed, rad, grav)
            _circleList.push(circle)
            circle.x = stage.stageWidth/2
            circle.y = stage.stageHeight/2
            circle.pos = new Point(circle.x, circle.y)
            addChild(circle)
        }
        
        private function createMoon():void{
            var moon:Circle = new Circle(0xB9D7EC, 2, 13.18*_deceleration, 9, 0)
            moon.x = 0
            moon.y = 0
            moon.pos = new Point(moon.x, moon.y)
            _circleList[2].addChild(moon)
            moon.addEventListener(Event.ENTER_FRAME, update)
        }
        
        private function createRing():void{
            _circleList[5].graphics.lineStyle(1,0xFFE7BE, 0.5)
            _circleList[5].graphics.drawCircle(0,0,20)
            _circleList[5].graphics.lineStyle(2,0xFFE7BE, 0.2)
            _circleList[5].graphics.drawCircle(0,0,22)
            _circleList[5].graphics.lineStyle(1,0xFFE7BE, 0.3)
            _circleList[5].graphics.drawCircle(0,0,24)
        }
        
        private function update(e:Event):void{
            e.target.x = e.target.motion.setPos(e.target.pos).x
            e.target.y = e.target.motion.setPos(e.target.pos).y
        }
        
        private function crashCheck(e:Event):void{
            trace(e.target, "CRASH")
            for(var i:int=0; i<_circleList.length; i++){
                _circleList[i].removeEventListener(Circle.CRASH, crashCheck)
            }
            _ship.visible = false
        }
        
        private function shipUpdate(e:Event):void{
            if(_ship.visible){
                var point:Point = new Point()
                for(var i:int=0; i<_circleList.length; i++){
                    var p:Point = _circleList[i].gravity(_ship)
                    point.x += p.x 
                    point.y += p.y
                }
                p = null
                p = shipMove(_ship ,_shipSpeed)
                point.x += p.x 
                point.y += p.y
                _ship.x += point.x
                _ship.y += point.y
                //
                _tracer.graphics.lineTo(_ship.x, _ship.y)
                //
                if(_ship.x >= stage.stageWidth && _ship.y >= stage.stageHeight){
                    _ship.removeEventListener(Event.ENTER_FRAME, shipUpdate)
                removeChild(_ship)
                _ship = null
                stage.addEventListener(MouseEvent.CLICK, shipStart)
                _msg.text = "ゴールイン!\n見事な軌道で太陽系を通り抜けました。\nFinish line!\nWent through the solar system in orbit superb."
                }
            }else{
                particle()
                _ship.removeEventListener(Event.ENTER_FRAME, shipUpdate)
                removeChild(_ship)
                _ship = null
                stage.addEventListener(MouseEvent.CLICK, shipStart)
                _msg.text = "惑星の引力に引き込まれました\nWas drawn into the planet's gravitational pull\n\nステージクリックで再スタート\nClick on the Restart Stage."
            }
        }
        
        private function shipMove(target:Sprite ,speed:Number):Point{
            var p:Point = new Point()
            var rad:Number = Math.atan2(stage.stageHeight-target.y, target.stage.stageWidth-target.x);
            var rot:Number = rad*180/Math.PI;
            p.x = Math.cos(rot*Math.PI/180)*speed
            p.y = Math.sin(rot*Math.PI/180)*speed
            target.rotation = -rot
            return p
        }
        
        private function particle():void{
            for(var i:int=0; i<_incidence; i++){
                var size:int = Math.floor(Math.random()*4+1)
                var speed:Number = Math.random()*19+1
                var dust:Dust = new Dust(size/2, speed)
                addChild(dust)
                dust.x = _ship.x
                dust.y = _ship.y
                dust.cacheAsBitmap = true
                dust.addEventListener(Event.ENTER_FRAME, dust.bomb)
                dust.addEventListener(Dust.LIFE_END, removed)
            }
        }
        
        private function removed(e:Event):void{
            e.target.removeEventListener(Event.ENTER_FRAME, e.target.bomb)
            e.target.removeEventListener(Dust.LIFE_END, removed)
            removeChild(e.target as Dust)
        }
    }
}

//class Circle
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.Event;

class Circle extends Sprite{
    private var _pos:Point = new Point()
    private var _speed:Number
    private var _radius:Number
    private var _motion:CircleMotion;
    private var _gravity:int
    
    public static const CRASH:String = "crash"
    
    public function Circle(color:int,r:int, speed:Number, rad:Number, gravity:int):void{
        _speed = speed
        _radius = rad
        _gravity = gravity
        //
        var colors:Array = [color, 0]
        var alphas:Array = [1, 1]
        var ratios:Array = [0, 50]
        graphics.beginGradientFill("radial", colors, alphas, ratios)
        graphics.drawCircle(0,0,r)
        graphics.endFill()
        //
        _motion = new CircleMotion(_speed, _radius)
    }
    
    public function gravity(target:Sprite):Point{
        var p:Point = new Point()
        var dist:Number = Math.sqrt((this.x-target.x)*(this.x-target.x)+(this.y-target.y)*(this.y-target.y));
        var rad:Number = Math.atan2(this.y-target.y, this.x-target.x);
        var rot:Number = rad*180/Math.PI;
        p.x = Math.cos(rot*Math.PI/180)*_gravity/dist/10
        p.y = Math.sin(rot*Math.PI/180)*_gravity/dist/10
        
        if(target.hitTestPoint(this.x, this.y, true)){
           dispatchEvent(new Event(Circle.CRASH))
            return new Point(0, 0) 
        }else{
            return p
        }
    }
    
    public function get motion():CircleMotion{
        return _motion
    }
    public function set pos(p:Point):void{
        _pos = p
    }
    public function get pos():Point{
        return _pos
    }
    public function set speed(s:Number):void{
        _speed = s
    }
    public function get speed():Number{
        return _speed
    }
    public function set radius(r:Number):void{
        _radius = r
    }
    public function get radius():Number{
        return _radius
    }
}

//class CircreMotion
import flash.geom.Point;

class CircleMotion{
   private var _angle:Number;
   private var _speed:Number;
   private var _radius:Number;
   private var _point:Point = new Point()
   
   public function CircleMotion(speed:Number, rad:Number){
       _speed = speed
       _radius = rad
       _angle = (Math.floor(Math.random()*18))*10
   }
    
    public function setPos(pos:Point):Point{
        var radian:Number = _angle * Math.PI / 90;
        _point.x = pos.x + _radius * Math.cos(radian);
        _point.y = pos.y + _radius * Math.sin(radian);
        _angle += _speed;
        return _point
    }
    
    public function set speed(speed:Number):void{
        _speed = speed;
    }
    public function get speed():Number{
        return _speed;
    }
    public function set radius(rad:Number):void{
        _radius = rad;
    }
    public function get radius():Number{
        return _radius;
    }
}

//
import flash.display.Sprite;
class Ship extends Sprite{
    public function Ship(){
        graphics.beginFill(0x33FF66)
        graphics.moveTo(-5,-5)
        graphics.lineTo(0,-2)
        graphics.lineTo(5,-5)
        graphics.lineTo(0,7)
        graphics.lineTo(-5,-5)
        graphics.endFill()
    }
    
}

import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.ColorTransform;

class Dust extends Sprite{
    
    private var _size:int
    private var _speed:Number
    private var _life:uint = 25
    private var _rot:Number
    public static const COLOR:int = 0xFFFFFF
    public static const LIFE_END:String = "life_end"
    
    public function Dust(size:int, speed:Number){
        var shape:Shape = new Shape()
        shape.graphics.beginFill(COLOR)
        shape.graphics.drawCircle(0,0,size)
        shape.graphics.endFill()
        _speed = speed
        _size = size
        _rot = Math.random()*360
        addChild(shape)
    }
    
    public function bomb(e:Event):void{
        e.target.x += Math.cos(_rot*Math.PI/180)*_speed
        e.target.y += Math.sin(_rot*Math.PI/180)*_speed
        //
        _rot-=3
        _life--
        if(_life==0){
            e.target.addEventListener(Event.ENTER_FRAME, death)
            if(e.target.x<-100 || e.target.x>stage.stageWidth+100 || e.target.y<-100 || e.target.y>stage.stageHeight+100){
                e.target.removeEventListener(Event.ENTER_FRAME, bomb)
                e.target.removeEventListener(Event.ENTER_FRAME, death)
                dispatchEvent(new Event(Dust.LIFE_END))
            }
        }
    }
    
    private function death(e:Event):void{
        if(e.target.scaleX >= 0){
            e.target.scaleX-=0.01
            e.target.scaleY-=0.01
        }else{
            e.target.removeEventListener(Event.ENTER_FRAME, bomb)
            e.target.removeEventListener(Event.ENTER_FRAME, death)
            dispatchEvent(new Event(Dust.LIFE_END))
        }
    }
}

//class Base
import flash.display.Sprite
import flash.text.TextField;

class Base extends Sprite{
    public function Base(color:int,w:int,h:int):void{
        graphics.beginFill(color, 1)
        graphics.drawRect(0,0,w,h)
        graphics.endFill()
    }
}