forked from: Saqoosha challenge for amateurs
/**
* Copyright mchang ( http://wonderfl.net/user/mchang )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/bfPT
*/
// forked from checkmate's Saqoosha challenge for amateurs
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import net.hires.debug.Stats;
[SWF(width="465", height="465", backgroundColor="#000000", frameRate="60")]
public class Rainbow extends Sprite
{
private var _umbrella:Sprite;
private var _umbrellaBitmapData:BitmapData;
private var _canvas:BitmapData;
private var _point:Point;
private var _filter:BlurFilter;
private var _rainbows:Array;
public function Rainbow()
{
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
private function initialize(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
// Stage の設定
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
// 初期化
_point = new Point();
_rainbows = new Array();
_filter = new BlurFilter();
// 傘の表示
_umbrella = new Umbrella();
addChild(_umbrella);
_umbrella.addEventListener(Event.COMPLETE, completeHandler);
}
private function completeHandler(e:Event):void
{
// 傘を BitmapData にする
var rectangle:Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
var matrix:Matrix = new Matrix();
matrix.translate(0, 0);
_umbrellaBitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0);
_umbrellaBitmapData.draw(_umbrella, matrix, null, null, rectangle);
addChild(new Bitmap(_umbrellaBitmapData)) as Bitmap;
// Sprite の傘は消す
removeChild(_umbrella);
// 虹の粒をふらせる
// BitmapData の第四引数は、transparent で、true だと透明(デフォルト)、false だと不透明
_canvas = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0);
addChild(new Bitmap(_canvas)) as Bitmap;
// Stats
//addChild(new Stats());
// 更新
addEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void
{
// 虹の粒をつくる
if (Math.random() < 0.08) {
_rainbows.push(new RainbowParticle(stage.stageWidth, stage.stageHeight));
}
// 虹の粒をふらす
_canvas.lock();
_canvas.fillRect(_canvas.rect, 0);
var matrix:Matrix;
var p:RainbowParticle;
for each (p in _rainbows) {
var color:uint = _umbrellaBitmapData.getPixel(p.x, p.y);
if (color != 0 && (p.x < 230 || 239 < p.x)) {
// 背景が黒以外で真ん中じゃないところっぽかったら、虹の粒の色を変える
p.change();
}
p.update();
matrix = new Matrix();
matrix.translate(p.x, p.y);
_canvas.draw(p, matrix, new ColorTransform());
// 外に出たらばいばい
if (stage.stageHeight < p.y) {
_rainbows.splice(_rainbows.indexOf(p), 1);
}
}
_canvas.applyFilter(_canvas, _canvas.rect, _point, _filter);
_canvas.unlock();
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.display.BitmapData;
import frocessing.color.ColorLerp;
import org.libspark.betweenas3.core.easing.IEasing;
import org.libspark.betweenas3.easing.*;
class Umbrella extends Sprite
{
private var _grad:Gradation;
private var _umbrella:Sprite;
private var _stick:Sprite;
private var _now:String = "Minus";
private var _centerPt = new Point(233, 260);
private var _leftPt:Point = new Point(233, 380);
private var _leftCtrl:Point = new Point(233, 260);
private var _rightPt = new Point(233, 380);
private var _rightCtrl = new Point(233, 260);
private var _stickPt1:Point = new Point(233, 460);
private var _stickPt2:Point = new Point(233, 465);
private var _umbrellaWidth:uint = 240;
private var _gradWidth:uint = 353;
public function Umbrella():void
{
_grad = new Gradation(
0xFFFFFF, 0xFFF200, 0xFF34D7, 0x9524CC, 0x1178D9,
0xFFF200, 0xFF34D7, 0x9524CC, 0x1178D9
);
makeStick();
}
private function makeStick():void
{
_stick = new Sprite();
addChild(_stick);
addEventListener(Event.ENTER_FRAME, stickFrameHandler);
}
private function stickFrameHandler(e:Event):void
{
_stick.graphics.clear();
_stick.graphics.lineStyle(5, 0xFFFFFF);
_stick.graphics.moveTo(_stickPt2.x, _stickPt2.y);
_stick.graphics.lineTo(_stickPt1.x, _stickPt1.y);
if (_stickPt1.y < 385) {
removeEventListener(Event.ENTER_FRAME, stickFrameHandler);
makeUmbrella();
} else {
_stickPt1.y -= 5;
}
}
private function makeUmbrella():void
{
_grad.setEasing(Circ.easeInOut);
_umbrella = new Sprite();
addChild(_umbrella);
addEventListener(Event.ENTER_FRAME, umbrellaFrameHandler);
}
private function umbrellaFrameHandler(e:Event):void
{
// 右
_umbrella.graphics.lineStyle(1, _grad.getColor(_leftPt.x / _gradWidth));
_umbrella.graphics.moveTo(_centerPt.x, _centerPt.y);
_umbrella.graphics.curveTo(_leftCtrl.x, _leftCtrl.y, _leftPt.x, _leftPt.y);
// 左
_umbrella.graphics.lineStyle(1, _grad.getColor(_rightPt.x / _gradWidth));
_umbrella.graphics.moveTo(_centerPt.x, _centerPt.y);
_umbrella.graphics.curveTo(_rightCtrl.x, _rightCtrl.y, _rightPt.x, _rightPt.y);
// 円弧を描く
if (_leftPt.x < 113) {
removeEventListener(Event.ENTER_FRAME, umbrellaFrameHandler);
dispatchEvent(new Event(Event.COMPLETE));
} else {
_leftCtrl.x -= 2;
_leftPt.x -= 2;
_rightCtrl.x += 2;
_rightPt.x += 2;
}
// 傘のなみなみ
if (_now == "Minus") {
_leftPt.y -= 1;
_rightPt.y -= 1;
if (_leftPt.y < 370) {
_now = "Plus";
}
} else if (_now == "Plus") {
_leftPt.y += 1;
_rightPt.y += 1;
if (380 < _leftPt.y) {
_now = "Minus";
}
}
}
}
class RainbowParticle extends Sprite
{
private var _grad:Gradation;
private var _color:Number = 0xFFFFFF;
private var _vy:Number = Math.random() * 1; // 速度
private var _vx:Number = Math.random() * 0.5; // 速度
private var _ay:Number = 0.02; // 加速度
private var _radius:Number; // 半径
private var _pt = new Point(233, 380);
private var _gradWidth:uint = 353;
private var _stageWidth:Number;
private var _stageHeight:Number;
public function RainbowParticle(stageWidth:Number, stageHeight:Number):void
{
_stageWidth = stageWidth;
_stageHeight = stageHeight;
_grad = new Gradation(
0xFFFFFF, 0xFFF200, 0xFF34D7, 0x9524CC, 0x1178D9,
0xFFF200, 0xFF34D7, 0x9524CC, 0x1178D9
);
_grad.setEasing(Circ.easeInOut);
_radius = Math.random() * 4 + 1;
graphics.beginFill(_color);
graphics.drawCircle(0, 0, _radius);
graphics.endFill();
this.x = Math.floor(Math.random() * _stageWidth);
this.y = -_radius;
}
public function update():void
{
_vy += _ay;
y += _vy;
}
public function change():void
{
var rand:Number = Math.random() * _gradWidth;
graphics.clear();
graphics.beginFill(_grad.getColor(rand / _gradWidth));
graphics.drawCircle(0, 0, _radius);
graphics.endFill();
// 傘の中心から今の位置までの角度
var dx:Number = x - _pt.x;
var dy:Number = y - _pt.y;
var radians:Number = Math.atan2(dy, dx);
// 速度
var vx:Number = Math.cos(radians) * _vx;
var vy:Number = Math.sin(radians) * _vy;
x += vx;
y += vy;
}
}
class Gradation {
private var _colors:Array;
private var _easing:IEasing;
public function Gradation(...args) {
_colors = args.concat();
_easing = Linear.linear;
}
public function setEasing(easing:IEasing):void {
_easing = easing;
}
public function getColor(position:Number):uint {
position = (position < 0 ? 0 : position > 1 ? 1 : position) * (_colors.length - 1);
var idx:int = position;
var alpha:Number = _easing.calculate(position - idx, 0, 1, 1);
if (alpha == 0) {
return _colors[idx];
} else {
return ColorLerp.lerp(_colors[idx], _colors[idx + 1], alpha);
}
}
}