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

シャボン玉

http://wonderfl.net/code/aaaf48abc914b94ed6cb53bd35256b873a603ae3
に触発されて
/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/jgZP
 */

// http://wonderfl.net/code/aaaf48abc914b94ed6cb53bd35256b873a603ae3
// に触発されて
package {
    import flash.display.*;
    import flash.text.TextField;
    import flash.utils.getTimer;
    import flash.filters.DisplacementMapFilter;
    import flash.geom.*;
    import flash.events.*;
    
    public class RollingBubbles extends Sprite {
        private var _tf : TextField;
        private var _bubbles : Array;
        private const K : uint = 100;
        
        private var _bmdBubbles : Array; // <BitmapData>
  
        public function RollingBubbles() {
            _tf = new TextField();
            _tf.width = 465;
            _tf.height = 465;
//            addChild(_tf);
            
            _bmdBubbles = makeBubbleData(100, K);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            
            _bubbles = [];
        }
        
        private var _time : Number = 0;
        
        private function onEnterFrame(e : Event) : void
        {
        		appendBubbles();
        		moveBubbles();
        		renderBubbles();
        		_time++;
        }
        
        // シャボン玉を発生
        private function appendBubbles() : void
        {
        		if(_time % 10 == 0){
        			var b : Bubble = new Bubble(
        				Math.random() * 465,
        				465,
        				Math.random() * 0.7 + 0.3,
        				Math.random() * 200,
        				Math.random() * 10,
        				Math.random() * 300 + 100,
        				-Math.random() * 3 - 2
        				);
        			addChild(b);
        			b.smoothing = true;
//        			b.pixelSnapping = "never";
        			_bubbles.push(b);
        		}
        }
        
        // シャボン玉を動かす
        private function moveBubbles() : void
        {
        		for(var i : int = _bubbles.length - 1;i >= 0;i--){
        			var b : Bubble = _bubbles[i];
        			b.step();
        			if(b.y < -b.height){
        				removeChild(b);
        				removeElement(_bubbles, i);
        			}
        		}
        }
        
        private static function removeElement(a : Array, ind : uint) : Array
        {
        		if(ind == a.length - 1){
        			a.pop();
        		}else{
        			a[ind] = a.pop();
        		} 
        		return a;
        }
        
        // シャボン玉を描画       
        private function renderBubbles() : void
        {
        		for each(var b : Bubble in _bubbles){
        			if(_time % 3 == 0){
	        			b.state = (b.state + 1) % K;
	        			b.bitmapData = _bmdBubbles[b.state];
        			}
        		}
        }
        
        // シャボン玉データをつくる
        private static function makeBubbleData(R : Number, cyc : int) : Array
        { 
        		var W : Number = 2 * R;
        	
        		// red:alpha, green:+x, blue:+y
            var base : BitmapData = new BitmapData(W, W, false, 0x008080);
            base.lock();
            for(var i : uint = 0;i < W;i++){
            		for(var j : uint = 0;j < W;j++){
            			var d2 : Number = (i - R) * (i - R) + (j - R) * (j - R);
					if(d2 < R * R){
						var d : Number = Math.sqrt(d2);
						var rr : Number = Math.asin(d/R) / (Math.PI / 2)*R;
						var cx : uint = 128 + (i - R) / d * (rr - d) * 4;
						var cy : uint = 128 + (j - R) / d * (rr - d) * 4;
						var thickness : uint = Math.min(0xff, Math.abs(rr)*1.2 + 0x10);
						base.setPixel(i, j, thickness << 16 | cx << 8 | cy);
					}
            		}
            }
            base.unlock();
            var dmf : DisplacementMapFilter = new DisplacementMapFilter(base, new Point(), BitmapDataChannel.GREEN, BitmapDataChannel.BLUE, R, R, "ignore");
            
            var bmds : Array = [];
            var src : BitmapData = new BitmapData(W, W, false, 0x000000);
            var seed : int = new Date().getTime();
            var offsets : Array = [];
            var dxs : Array = [];
            for(i = 0;i < 3;i++){
            		offsets.push(new Point());
            		dxs.push(int(Math.random() * 10 - 5) * int(W / cyc));
            }
            	
            	src.lock();
            for(i = 0;i < cyc;i++){
	            src.perlinNoise(W, W, 3, seed, true, false, 7, false, offsets);
	            src.colorTransform(src.rect, new ColorTransform(1.8, 1.8, 1.8, 1));
	            for(j = 0;j < 3;j++){
	            		offsets[j].x += dxs[j];
	            		offsets[j].y += dxs[2 - j];
	            }
            
	            var dst : BitmapData = new BitmapData(W, W, true, 0x000000);
	            dst.lock();
	            dst.applyFilter(src, src.rect, new Point(), dmf);
	            dst.copyChannel(base, base.rect, new Point(), BitmapDataChannel.RED, BitmapDataChannel.ALPHA);
	            dst.unlock();
	            bmds.push(dst);
            }
            src.unlock();
            base.dispose();
            src.dispose();
            
            return bmds;
        }

        private function tr(...o : Array) : void
        {
            _tf.appendText(o + "\n");
        }
    }
}

import flash.display.Bitmap;

class Bubble extends Bitmap
{
	public var xx : Number;
	public var xy : Number;
	public var w : Number; // 振幅
	public var cyc : Number; // 周期
	public var t : Number; // 位相
	public var vy : Number;
	public var state : uint; // 使っているBitmapDataの番号
	
	public function Bubble(xx : Number, xy : Number, scale : Number, state : uint, w : Number, cyc : Number, vy : Number)
	{
		super();
		this.xx = xx;
		this.xy = xy;
		this.x = xx;
		this.y = xy;
		this.w = w;
		this.cyc = cyc;
		this.vy = vy;
		this.t = Math.random() * cyc * 2 * Math.PI;
		scaleX = scale;
		scaleY = scale;
	}
	
	public function step() : void
	{
		t++;
		xx += w * Math.cos(t/cyc);
		xy += vy;
		x = xx;
		y = xy;
	}
}