Taiko.as (メインクラス)
package {
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.geom.Point;
    import flash.events.Event;

    [SWF(width="550",height="400",backgroundColor="0x0",frameRate="24")]

    public class Taiko extends Sprite{
        private const TOTAL:int = 10;
        private const RADIUS:Number = 80;
        
        //must be between 0 and 1, inclusive
        private const FLAT:Number = 0.05;
        
        private var rootAry:Array;
        private var destAry:Array;
        private var t:Number = 0;
        private var rootCircle:Shape;
        private var destCircle:Shape;
        
        private var slider1:SimpleSlider;
        private var slider2:SimpleSlider;
        
        public function Taiko(){
            init();
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function init():void{
            rootAry = new Array();
            destAry = new Array();
            
            for (var i:int=0; i<TOTAL; i++){
                var tRoot:Number = 2*Math.PI*i/TOTAL;
                var rootX:Number = stage.stageWidth/2 + RADIUS*Math.cos(tRoot);
                var rootY:Number = 100 + RADIUS*Math.sin(tRoot)*FLAT;
                var rootP:Point = new Point(rootX,rootY);
                rootAry.push(rootP);
                
                var tDest:Number = tRoot + Math.PI/4;//add offset
                var destX:Number = stage.stageWidth/2 + RADIUS*Math.cos(tDest);
                var destY:Number = 300 + RADIUS*Math.sin(tDest)*FLAT;
                var destP:Point = new Point(destX,destY);
                destAry.push(destP);
                
                var spr:Frame = new Frame(rootP,destP,0x00FFFF);
                addChild(spr);
            }
            
            rootCircle = new Shape();
            rootCircle.graphics.lineStyle(0,0x00FFFF,1);
            rootCircle.graphics.drawCircle(0,0,RADIUS);
            rootCircle.x = stage.stageWidth/2;
            rootCircle.y = 100;
            rootCircle.scaleY = FLAT;
            addChild(rootCircle);
            
            destCircle = new Shape();
            destCircle.graphics.lineStyle(0,0x00FFFF,1);
            destCircle.graphics.drawCircle(0,0,RADIUS);
            destCircle.x = stage.stageWidth/2;
            destCircle.y = 300;
            destCircle.scaleY = FLAT;
            addChild(destCircle);
            
            //move the circle
            slider1 = new SimpleSlider(100,350,350);
            slider1.x = stage.stageWidth - 50;
            slider1.y = stage.stageHeight/2 - slider1.height/2;
            addChild(slider1);
            
            //control the angular velocity
            slider2 = new SimpleSlider(0,20,5);
            slider2.x = 50;
            slider2.y = stage.stageHeight/2 - slider2.height/2;
            addChild(slider2);
        }
        
        private function onEnterFrame(e:Event):void{
            t += slider2.value;
            
            if (t>=360){
                t = 0;
            }
            
            for (var i:int=0; i<TOTAL; i++){
                var theta:Number = t*Math.PI/180;
                var tRoot:Number = 2*Math.PI*i/TOTAL;
                rootAry[i].x = stage.stageWidth/2 + RADIUS*Math.cos(tRoot+theta);
                rootAry[i].y = 100 + RADIUS*Math.sin(tRoot+theta)*FLAT;
                var tDest:Number = 2*Math.PI*i/TOTAL + Math.PI/4;//add offset
                destAry[i].x = stage.stageWidth/2 + RADIUS*Math.cos(tDest+theta);
                destAry[i].y = slider1.value + RADIUS*Math.sin(tDest+theta)*FLAT;
            }
            
            destCircle.y = slider1.value;
        }
    }
}
Frame.as
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Point;

    public class Frame extends Sprite{
        private const TOTAL:int = 5;
        private var segments:Array;
        private var color:uint;
        
        private var targetRoot:Point;
        private var targetDest:Point;
        
        public function Frame(rootP:Point,destP:Point,col:uint){
            this.color = col;
            this.targetRoot = rootP;
            this.targetDest = destP;
                        
            segments = new Array();
            for(var i:uint = 0; i<TOTAL; i++){
                var segment:Segment = new Segment(40,0,color);
                segments.push(segment);
                addChild(segment);
            }

            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onEnterFrame(event:Event):void{
            var target:Point = reach(segments[0], targetDest.x,targetDest.y);
            
            for(var i:uint = 1; i < TOTAL; i++){
                var segment:Segment = segments[i];
                target = reach(segment, target.x, target.y);
                
                //for the root
                if (i == TOTAL-1){
                    segment.x = targetRoot.x;
                    segment.y = targetRoot.y;
                }
            }

            for(i = TOTAL-1; i>0; i--){
                position(segments[i-1], segments[i]);
            }
        }
        
        private function reach(segment:Segment, xpos:Number, ypos:Number):Point{
            var dx:Number = xpos - segment.x;
            var dy:Number = ypos - segment.y;
            var angle:Number = Math.atan2(dy, dx);
            segment.rotation = angle * 180 / Math.PI;
            
            var w:Number = segment.getPin().x - segment.x;
            var h:Number = segment.getPin().y - segment.y;
            var tx:Number = xpos - w;
            var ty:Number = ypos - h;
            return new Point(tx, ty);
        }
        
        private function position(segChild:Segment, segParent:Segment):void{
            segChild.x = segParent.getPin().x;
            segChild.y = segParent.getPin().y;
        }
    }
}
Segment.as
package
{
    import flash.display.Sprite;
    import flash.geom.Point;

    public class Segment extends Sprite{
        private var color:uint;
        private var segmentWidth:Number;
        private var segmentHeight:Number;
        
        public function Segment(segmentWidth:Number, segmentHeight:Number, color:uint = 0xffffff){
            this.segmentWidth = segmentWidth;
            this.segmentHeight = segmentHeight;
            this.color = color;
            init();
        }
        
        public function init():void{
            graphics.lineStyle(0,color,0.5);
            graphics.beginFill(color);
            graphics.drawRoundRect(-segmentHeight / 2, 
                                   -segmentHeight / 2,
                                   segmentWidth + segmentHeight,
                                   segmentHeight,
                                   segmentHeight,
                                   segmentHeight);
            graphics.endFill();
            
            graphics.drawCircle(0, 0, 1);
            graphics.drawCircle(segmentWidth, 0, 1);
        }
        
        public function getPin():Point{
            var angle:Number = rotation * Math.PI / 180;
            var xPos:Number = x + Math.cos(angle) * segmentWidth;
            var yPos:Number = y + Math.sin(angle) * segmentWidth;
            return new Point(xPos, yPos);
        }
    }
}
SimpleSlider.as (by Keith Peters)
package
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.events.Event;
    
    public class SimpleSlider extends Sprite
    {
        private var _width:Number = 16;
        private var _height:Number = 100;
        private var _value:Number;
        private var _max:Number = 100;
        private var _min:Number = 0;
        private var _handle:Sprite;
        private var _back:Sprite;
        private var _backWidth:Number = 0;
        private var _handleHeight:Number = 6;
        private var _backColor:uint = 0xcccccc;
        private var _backBorderColor:uint = 0x999999;
        private var _handleColor:uint = 0xeeeeee;
        private var _handleBorderColor:uint = 0xcccccc;
        private var _handleRadius:Number = 2;
        private var _backRadius:Number = 2;
        
        public function SimpleSlider(min:Number=0, max:Number=100, value:Number=100)
        {
            _min = min;
            _max = max;
            _value = Math.min(Math.max(value, min), max)
            init();
        }
        
        private function init():void
        {
            _back = new Sprite();
            addChild(_back);
            
            _handle = new Sprite();
            addChild(_handle);
            _handle.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            
            draw();
            updatePosition();
        }
        
        private function draw():void
        {
            drawBack();
            drawHandle();
        }
        
        private function drawBack():void
        {
            _back.graphics.clear();
            _back.graphics.beginFill(_backColor);
            _back.graphics.lineStyle(0, _backBorderColor);
            _back.graphics.drawRoundRect(0, 0, _backWidth, _height, _backRadius, _backRadius);
            _back.graphics.endFill();
            _back.x = _width / 2 - _backWidth / 2;
        }
        
        private function drawHandle():void
        {
            _handle.graphics.clear();
            _handle.graphics.beginFill(_handleColor);
            _handle.graphics.lineStyle(0, _handleBorderColor);
            _handle.graphics.drawRoundRect(0, 0, _width, _handleHeight, _handleRadius, _handleRadius);
            _handle.graphics.endFill();
        }
    
        private function updatePosition():void
        {
            var handleRange:Number = _height - _handleHeight;
            var valueRange:Number = _max - _min;
            _handle.y = handleRange - (_value - _min) / valueRange * handleRange;
        }
        
        private function updateValue():void
        {
            var handleRange:Number = _height - _handleHeight;
            var valueRange:Number = _max - _min;
            _value = (handleRange - _handle.y) / handleRange * valueRange + _min;
            dispatchEvent(new Event(Event.CHANGE));
        }
        
        private function onMouseUp(event:MouseEvent):void
        {
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            _handle.stopDrag();
        }
        
        private function onMouseDown(event:MouseEvent):void
        {
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            _handle.startDrag(false, new Rectangle(0, 0, 0, _height - _handleHeight));
        }
        
        private function onMouseMove(event:MouseEvent):void
        {
            updateValue();
        }


        
        public function invalidate():void
        {
            draw();
        }
        
        public function move(x:Number, y:Number):void
        {
            this.x = x;
            this.y = y;
        }
        
        public function setSize(w:Number, h:Number):void
        {
            _width = w;
            _height = h;
            draw();
        } 
        
        public function set backBorderColor(n:uint):void
        {
            _backBorderColor = n;
            draw();
        }
        public function get backBorderColor():uint
        {
            return _backBorderColor;
        }
        
        public function set backColor(n:uint):void
        {
            _backColor = n;
            draw();
        }
        public function get backColor():uint
        {
            return _backColor;
        }
        
        public function set backRadius(n:Number):void
        {
            _backRadius = n;
        }
        public function get backRadius():Number
        {
            return _backRadius;
        }
        
        public function set backWidth(n:Number):void
        {
            _backWidth = n;
            draw();
        }
        public function get backWidth():Number
        {
            return _backWidth;
        }
        
        public function set handleBorderColor(n:uint):void
        {
            _handleBorderColor = n;
            draw();
        }
        public function get handleBorderColor():uint
        {
            return _handleBorderColor;
        }
        
        public function set handleColor(n:uint):void
        {
            _handleColor = n;
            draw();
        }
        public function get handleColor():uint
        {
            return _handleColor;
        }
        
        public function set handleRadius(n:Number):void
        {
            _handleRadius = n;
            draw();
        }
        public function get handleRadius():Number
        {
            return _handleRadius;
        }
        
        public function set handleHeight(n:Number):void
        {
            _handleHeight = n;
            draw();
            updatePosition();
        }
        public function get handleHeight():Number
        {
            return _handleHeight;
        }
        
        override public function set height(n:Number):void
        {
            _height = n;
            draw();
        }
        override public function get height():Number
        {
            return _height;
        }
        
        public function set max(n:Number):void
        {
            _max = n;
            updatePosition();
        }
        public function get max():Number
        {
            return _max;
        }
        
        public function set min(n:Number):void
        {
            _min = n;
            updatePosition();
        }
        public function get min():Number
        {
            return _min;
        }
        
        public function set value(n:Number):void
        {
            _value = n;
            _value = Math.min(_max, Math.max(_value, _min));
            updatePosition();
        }
        public function get value():Number
        {
            return _value;
        }
        
        override public function set width(n:Number):void
        {
            _width = n;
            draw();
        }
        override public function get width():Number
        {
            return _width;
        }
    }
}
Powered by blog Boreal Kiss 2008.