ひよこちゃん 綱が!
//////////////////////////////////////////////////////////////////////////////
ひよこちゃん 綱が!
//////////////////////////////////////////////////////////////////////////////
/**
* Copyright ProjectNya ( http://wonderfl.net/user/ProjectNya )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lXS3
*/
// forked from ProjectNya's ひよこちゃん 綱の上でめらめら
// forked from ProjectNya's ひよこちゃん 綱の上でゆらゆら
////////////////////////////////////////////////////////////////////////////////
// ひよこちゃん 綱が!
////////////////////////////////////////////////////////////////////////////////
package {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.system.Security;
import flash.utils.Timer;
import flash.events.TimerEvent;
[SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]
public class Main extends Sprite {
private var loader:PiyoLoader;
private static var piyoPath:String = "http://www.project-nya.jp/images/flash/piyo.swf";
private var piyo:MovieClip;
private static var radius:uint = 10;
private static var radian:Number = Math.PI/180;
private static var speed:uint = 5;
private var rope1:Sprite;
private var rope2:Sprite;
private var fire:Fire;
private var smoke:TeraFire;
public function Main() {
//Wonderfl.disable_capture();
Wonderfl.capture_delay(4);
init();
}
private function init():void {
var sky:Sky = new Sky(465, 350);
addChild(sky);
var ground:Ground = new Ground(465, 115);
addChild(ground);
ground.y = 350;
fire = new Fire();
addChild(fire);
fire.init(80, 160, {x: 360, y: 400, offset: 10});
smoke = new TeraFire(0, 0, 12, 48, 0xCCCCCC, 0xFFFFFF);
smoke.x = 360;
smoke.y = 188;
rope1 = new Sprite();
rope2 = new Sprite();
addChild(rope1);
addChild(rope2);
rope1.graphics.lineStyle(4, 0xFFFFFF);
rope1.graphics.moveTo(232, 200);
rope1.graphics.curveTo(348, 200, 465, 180);
rope2.graphics.lineStyle(4, 0xFFFFFF);
rope2.graphics.moveTo(0, 180);
rope2.graphics.curveTo(116, 200, 232, 200);
loader = new PiyoLoader();
loader.addEventListener(PiyoLoader.COMPLETE, complete, false, 0, true);
loader.load(piyoPath);
}
private function complete(evt:Event):void {
loader.removeEventListener(PiyoLoader.COMPLETE, complete);
piyo = loader.content;
addChild(piyo);
addChild(rope2);
//addChild(smoke);
piyo.x = 232;
piyo.y = 196;
piyo.scaleX = piyo.scaleY = 2;
piyo.shade.visible = false;
loader = null;
piyo.velocity = 0;
piyo.angle = 0;
addEventListener(Event.ENTER_FRAME, update, false, 0, true);
fire.burn();
var timer:Timer = new Timer(2000, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, tick, false, 0, true);
timer.start();
}
private function update(evt:Event):void {
piyo.piyo.rotation = piyo.velocity;
piyo.velocity = radius*Math.sin(piyo.angle*radian);
piyo.angle += speed;
}
private function tick(evt:TimerEvent):void {
evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, tick);
addChild(smoke);
}
}
}
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.HTTPStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.system.Security;
import flash.system.LoaderContext;
class PiyoLoader extends Sprite {
private var loader:Loader;
private var info:LoaderInfo;
public var content:MovieClip;
public static const IO_ERROR:String = IOErrorEvent.IO_ERROR;
public static const HTTP_STATUS:String = HTTPStatusEvent.HTTP_STATUS;
public static const SECURITY_ERROR:String = SecurityErrorEvent.SECURITY_ERROR;
public static const INIT:String = Event.INIT;
public static const COMPLETE:String = Event.COMPLETE;
public function PiyoLoader() {
Security.allowDomain("www.project-nya.jp");
loader = new Loader();
info = loader.contentLoaderInfo;
}
public function load(file:String):void {
info.addEventListener(IOErrorEvent.IO_ERROR, ioerror, false, 0, true);
info.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpstatus, false, 0, true);
info.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityerror, false, 0, true);
info.addEventListener(Event.INIT, initialize, false, 0, true);
info.addEventListener(Event.COMPLETE, complete, false, 0, true);
try {
loader.load(new URLRequest(file), new LoaderContext(true));
} catch (err:Error) {
trace(err.message);
}
}
public function unload():void {
loader.unload();
}
private function ioerror(evt:IOErrorEvent):void {
loader.unload();
dispatchEvent(new Event(PiyoLoader.IO_ERROR));
}
private function httpstatus(evt:HTTPStatusEvent):void {
dispatchEvent(new Event(PiyoLoader.HTTP_STATUS));
}
private function securityerror(evt:SecurityErrorEvent):void {
dispatchEvent(new Event(PiyoLoader.SECURITY_ERROR));
}
private function initialize(evt:Event):void {
content = MovieClip(info.content);
dispatchEvent(new Event(PiyoLoader.INIT));
}
private function complete(evt:Event):void {
info.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
info.removeEventListener(HTTPStatusEvent.HTTP_STATUS, httpstatus);
info.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityerror);
info.removeEventListener(Event.INIT, initialize);
info.removeEventListener(Event.COMPLETE, complete);
//addChild(loader);
dispatchEvent(new Event(PiyoLoader.COMPLETE));
}
}
import flash.display.Shape;
import flash.geom.Matrix;
import flash.display.GradientType;
class Sky extends Shape {
private static var _width:uint;
private static var _height:uint;
private static var color1:uint = 0x000066;
private static var color2:uint = 0x000000;
public function Sky(w:uint, h:uint) {
_width = w;
_height = h;
draw();
}
private function draw():void {
var colors:Array = [color1, color2];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(_width, _height, 0.5*Math.PI, 0, 0);
graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
graphics.drawRect(0, 0, _width, _height);
graphics.endFill();
}
}
import flash.display.Shape;
import flash.geom.Matrix;
import flash.display.GradientType;
class Ground extends Shape {
private static var _width:uint;
private static var _height:uint;
private static var color1:uint = 0x001100;
private static var color2:uint = 0x004400;
public function Ground(w:uint, h:uint) {
_width = w;
_height = h;
draw();
}
private function draw():void {
var colors:Array = [color1, color2];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(_width, _height, 0.5*Math.PI, 0, 0);
graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
graphics.drawRect(0, 0, _width, _height);
graphics.endFill();
}
}
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;
import flash.display.BlendMode;
import flash.filters.BlurFilter;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Point;
import flash.events.Event;
class Fire extends Sprite {
private var xPos:uint;
private var yPos:uint;
private var fireWidth:uint;
private var fireHeight:uint;
private var noise:Sprite;
private var noiseBD:BitmapData;
private var light:Shape;
private var lightOffset:uint;
private var flare:Sprite;
private var flareBase:Sprite;
private var fire:Shape;
private var flareBD:BitmapData;
private var baseMask:Shape;
private var fireMask:Shape;
private var map:DisplacementMapFilter;
private static var baseX:uint = 12;
private static var baseY:uint = 24;
private static var numOctaves:uint = 3;
private var randomSeed:uint;
private var speedList:Array;
private static var speed:uint = 2;
private var offsetsList:Array;
private var scale:Number = 0;
public function Fire() {
}
public function init(w:uint, h:uint, option:Object):void {
fireWidth = w;
fireHeight = h;
if (option.x != undefined) xPos = option.x;
if (option.y != undefined) yPos = option.y;
if (option.offset != undefined) lightOffset = option.offset;
initialize();
}
private function initialize():void {
createPerlinNoise(fireWidth, fireHeight);
if (lightOffset) createLight();
createFlare(fireWidth, fireHeight);
}
private function createPerlinNoise(w:uint, h:uint):void {
noise = new Sprite();
addChild(noise);
noise.visible = false;
noiseBD = new BitmapData(w + 40, h + 40, true);
noise.addChild(new Bitmap(noiseBD));
}
private function createLight():void {
light = new Shape();
addChild(light);
light.visible = false;
light.x = xPos;
light.y = yPos + lightOffset;
createGradientLight(light);
}
private function createFlare(w:uint, h:uint):void {
flare = new Sprite();
addChild(flare);
flare.visible = false;
flare.x = xPos;
flare.y = yPos;
flare.blendMode = BlendMode.ADD;
var blur:BlurFilter = new BlurFilter(16, 16, 3);
baseMask = new Shape();
addChild(baseMask);
baseMask.x = xPos;
baseMask.y = yPos - fireHeight*0.1;
baseMask.scaleX = baseMask.scaleY = 2;
createEggMask(baseMask);
flare.mask = baseMask;
baseMask.filters = [blur];
flare.cacheAsBitmap = true;
baseMask.cacheAsBitmap = true;
flareBase = new Sprite();
flare.addChild(flareBase);
fire = new Shape();
flareBase.addChild(fire);
createGradientFire(fire);
fireMask = new Shape();
flareBase.addChild(fireMask);
createEggMask(fireMask);
fireMask.filters = [blur];
fire.mask = fireMask;
fire.cacheAsBitmap = true;
fireMask.cacheAsBitmap = true;
flareBD = new BitmapData(w + 40, h + 40, true);
randomSeed = Math.floor(Math.random()*100);
speedList = new Array();
offsetsList = new Array();
for (var n:uint = 0; n < numOctaves; n++) {
var xSpeed:Number = Math.random()*speed - speed*0.5;
var ySpeed:Number = Math.random()*speed + speed*3;
speedList[n] = new Point(xSpeed, ySpeed);
offsetsList[n] = new Point(0, 0);
}
}
public function burn():void {
flare.visible = true;
addEventListener(Event.ENTER_FRAME, createFire, false, 0, true);
fireMask.scaleX = fireMask.scaleY = scale;
light.visible = true;
light.scaleX = light.scaleY = scale;
removeEventListener(Event.ENTER_FRAME, clearFire);
addEventListener(Event.ENTER_FRAME, burnFire, false, 0, true);
}
private function burnFire(evt:Event):void {
scale += (1 - scale)*0.2;
fireMask.scaleX = fireMask.scaleY = scale;
light.scaleX = light.scaleY = scale;
if (Math.abs(1 - scale) < 0.005) {
scale = 1;
removeEventListener(Event.ENTER_FRAME, burnFire);
}
}
public function clear():void {
removeEventListener(Event.ENTER_FRAME, burnFire);
addEventListener(Event.ENTER_FRAME, clearFire, false, 0, true);
}
private function clearFire(evt:Event):void {
scale += (0 - scale)*0.2;
fireMask.scaleX = fireMask.scaleY = scale;
light.scaleX = light.scaleY = scale;
if (Math.abs(0 - scale) < 0.005) {
scale = 0;
light.visible = false;
removeEventListener(Event.ENTER_FRAME, createFire);
removeEventListener(Event.ENTER_FRAME, clearFire);
}
}
private function createFire(evt:Event):void {
for (var n:uint = 0; n < numOctaves; n++) {
offsetsList[n].x += speedList[n].x;
offsetsList[n].y += speedList[n].y;
}
noiseBD.lock();
noiseBD.perlinNoise(baseX, baseY, numOctaves, randomSeed, false, true, 1, true, offsetsList);
noiseBD.unlock();
flareBD.lock();
flareBD.draw(noise);
var point:Point = new Point(0, 0);
map = new DisplacementMapFilter(flareBD, point, 1, 1, -10, 90, DisplacementMapFilterMode.CLAMP, 0xFFFFFF);
flareBD.unlock();
flareBase.filters = [map];
}
private function createGradientFire(target:Shape):void {
var w:uint = fireWidth + 40;
var h:uint = fireHeight + 40;
var colors:Array = [0xFF0000, 0x990000, 0xFF9900, 0xFFFF66, 0xFFFFFF, 0xFFFFFF];
var alphas:Array = [1, 1, 1, 1, 1, 1];
var ratios:Array = [25, 51, 127, 204, 229, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(w, -h, -0.5*Math.PI, 0, 0);
target.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0.75);
target.graphics.drawRect(-w*0.5, -h+20, w, h);
target.graphics.endFill();
}
private function createEggMask(target:Shape):void {
var w:Number = fireWidth;
var h:Number = fireHeight;
target.graphics.beginFill(0xFFFFFF);
target.graphics.moveTo(-w*0.5, -h*0.2);
target.graphics.curveTo(-w*0.4, -h, 0, -h);
target.graphics.curveTo(w*0.4, -h, w*0.5, -h*0.2);
target.graphics.curveTo(w*0.5, 0, 0, 0);
target.graphics.curveTo(-w*0.5, 0, -w*0.5, -h*0.2);
target.graphics.endFill();
}
private function createGradientLight(target:Shape):void {
var colors:Array = [0xFFFF00, 0xFFFF00, 0xFFCC00, 0x000000];
var alphas:Array = [0.6, 0.3, 0.2, 0];
var ratios:Array = [0, 102, 153, 255];
var matrix:Matrix = new Matrix();
var w:Number = fireWidth*1.6;
var h:Number = fireWidth*0.4;
matrix.createGradientBox(w, h, 0, -w*0.5, -h*0.5);
target.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
target.graphics.drawEllipse(-w*0.5, -h*0.5, w, h);
target.graphics.endFill();
}
}
////////////////////////////////////////////////////////////////////////////////
// com.trick7.effects.TeraFire (炎エフェクト)
// http://www.trick7.com/blog/2008/07/27-205806.php
// http://www.libspark.org/svn/as3/TeraFire/src/com/trick7/effects/TeraFire.as
////////////////////////////////////////////////////////////////////////////////
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
class TeraFire extends Sprite{
//横方向ゆらぎ速度
public var phaseRateX:Number;
//縦方向ゆらぎ速度
public var phaseRateY:Number;
private var offsets:Array= [new Point(),new Point()];
private var seed:Number = Math.random();
private var fireW:Number;
private var fireH:Number;
//火の色
//private var fireColorIn:uint;
//private var fireColorOut:uint;
private var ball:Sprite;
private var gradientImage:BitmapData;
private var displaceImage:BitmapData;
//火の玉の中心の上下位置偏差(-1で上端、1で下端)
private var focalPointRatio:Number = 0.6;
//炎の揺らぎのせいで描画エリアをはみ出してしまうのを防ぐための余白幅
private const margin:int = 10;
private var rdm:Number;
//コンストラクタ
public function TeraFire(xPos:Number=0, yPos:Number=0, fireWidth:Number=30, fireHeight:Number=90, fireColorIn:uint = 0xFFCC00, fireColorOut:uint = 0xE22D09){
fireW = fireWidth;
fireH = fireHeight;
phaseRateX = 0;
phaseRateY = 5;
var matrix:Matrix = new Matrix();
matrix.createGradientBox(fireW,fireH,Math.PI/2,-fireW/2,-fireH*(focalPointRatio+1)/2);
var colors:Array = [fireColorIn, fireColorOut, fireColorOut];
var alphas:Array = [1,1,0];
var ratios:Array = [30, 100, 220];
var home:Sprite = new Sprite();
ball = new Sprite();
//炎本体
ball.graphics.beginGradientFill(GradientType.RADIAL,colors, alphas, ratios, matrix,"pad","rgb",focalPointRatio);
ball.graphics.drawEllipse(-fireW/2,-fireH*(focalPointRatio+1)/2,fireW,fireH);
ball.graphics.endFill();
//余白確保用透明矩形
ball.graphics.beginFill(0x000000,0);
ball.graphics.drawRect(-fireW/2,0,fireW+margin,1);
ball.graphics.endFill();
addChild(home);
home.addChild(ball);
this.x = xPos;
this.y = yPos;
addEventListener(Event.ENTER_FRAME,loop);
//ゆらぎ用のBitmap(ステージに貼付ける必要はないのでBitmapに貼る必要はない)
displaceImage = new BitmapData(fireW+margin,fireH,false,0xFFFFFFFF);
//火の芯付近の揺らぎを抑える用のグラデーション
var matrix2:Matrix = new Matrix();
matrix2.createGradientBox(fireW+margin,fireH,Math.PI/2,0,0);
var gradient_mc:Sprite = new Sprite;
gradient_mc.graphics.beginGradientFill(GradientType.LINEAR,[0x666666,0x666666], [0,1], [120,220], matrix2);
gradient_mc.graphics.drawRect(0,0,fireW+margin,fireH);//drawのターゲットなので生成位置にこだわる必要はない。
gradient_mc.graphics.endFill();
gradientImage = new BitmapData(fireW+margin,fireH,true,0x00FFFFFF);
gradientImage.draw(gradient_mc);//gradient_mcを消す必要は?
//同サイズの炎の揺らぎをランダム化
rdm = Math.floor(Math.random()*10);
//確認検証用コード
/*this.startDrag(true);//検証用マウス吸着
import flash.display.Bitmap;
var bmp:Bitmap = new flash.display.Bitmap(displaceImage);
bmp.x = -fireW/2;
bmp.y = -fireH*(focalPointRatio+1)/2;
home.addChild(bmp);
bmp.alpha = 0.4;//揺らぎマップのコピーを半透明表示(擬似コピーなので揺らぎマップ本体ではない!)
home.addChild(gradient_mc);//根元の揺らぎ抑えるグラデーションを表示。場所は適当
*/
}
private function loop(e:Event):void{
//もやもや画像を上スクロール移動させる
for(var i:int = 0; i < 2; ++i){
offsets[i].x += phaseRateX;
offsets[i].y += phaseRateY;
}
//もやもやした白黒画像を生成
displaceImage.perlinNoise(30+rdm, 60+rdm, 2, seed, false, false, 7, true, offsets);
//芯付近の揺らぎを抑える
displaceImage.copyPixels(gradientImage,gradientImage.rect,new Point(),null, null, true);
var dMap:DisplacementMapFilter = new DisplacementMapFilter(displaceImage, new Point(), 1, 1, 20, 10, DisplacementMapFilterMode.CLAMP);
ball.filters = [dMap];
}
}
/*
課題点:
・DisplacementMapFilterの元マップが原寸な必要ないかも。半分のサイズを拡大して使って負荷下げれたらいいかも。
・やや右寄りに揺らぐ分だけ余計にサイズ確保してる部分(margin)の処理が不細工。
*/