forked from: 【AS100本ノック】8回目:水
AS100本ノック
* 8回目のお題は「水」
* あなたなりの「水」を表現してください。
* --
* 校庭の蛇口で遊ぶイメージでした。
* 水に見えないこともない・・・。
/**
* Copyright mex_ichikawa ( http://wonderfl.net/user/mex_ichikawa )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/nul3
*/
// forked from mex's 【AS100本ノック】8回目:水
/*
* AS100本ノック
* 8回目のお題は「水」
* あなたなりの「水」を表現してください。
* --
* 校庭の蛇口で遊ぶイメージでした。
* 水に見えないこともない・・・。
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.InterpolationMethod;
import flash.display.Loader;
import flash.display.SpreadMethod;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BitmapFilter;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.system.LoaderContext;
[SWF(width=465, height=465, backgroundColor=0xFFFFFF, frameRate=30)]
public class Fountain extends Sprite
{
public static const STAGE_WIDTH:uint = 465;
public static const STAGE_HEIGHT:uint = 465;
private static const REQUEST_IMAGE:String = "http://farm3.static.flickr.com/2643/4130117846_303944dc18_o.jpg";
private static const CREATE_POS_X:uint = 460;
private static const CREATE_POS_Y:uint = 460;
private static const CREATE_NUM:uint = 10;
private static const BASE_POWER_X:Number = -50;
private static const BASE_POWER_Y:Number = -50;
private static const BASE_SIZE:Number = 15;
private static const BASE_COLOR:uint = 0xFF808080;
private static const GRAVITY:Number = 0.9;
private static const FRICTION:Number = 0.96;
private var _waters:Vector.<WaterParticle>;
private var _bm:Bitmap;
private var _bmd:BitmapData;
private var _filter:BitmapData;
private var _particle:BitmapData;
private var _imgLoader:Loader;
private var _powerScaleX:Number;
private var _powerScaleY:Number;
public function Fountain()
{
init();
}
private function init():void
{
//format
_waters = new Vector.<WaterParticle>();
_bmd = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xFFFFFFFF);
_filter = new BitmapData(stage.stageWidth, stage.stageHeight, true, BASE_COLOR);
_powerScaleX = _powerScaleY = 0.5;
//background
var request:URLRequest = new URLRequest(REQUEST_IMAGE);
var context:LoaderContext = new LoaderContext(true);
_imgLoader = new Loader();
_imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
try
{
_imgLoader.load(request, context);
} catch (error:Error) {
trace("image load failed.");
}
//attach
_bm = new Bitmap(_bmd);
addChild(_bm);
}
private function completeHandler(event:Event):void
{
_imgLoader.x = (_imgLoader.width - STAGE_WIDTH) / 2;
_imgLoader.y = (_imgLoader.height - STAGE_HEIGHT) / 2;
_bmd.draw(_imgLoader);
//event
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
private function enterFrameHandler(event:Event):void
{
createWater();
drawWater();
}
private function mouseMoveHandler(event:MouseEvent):void
{
_powerScaleX = 1 - event.stageX / stage.width;
_powerScaleY = 1 - event.stageY / stage.height;
}
private function createWater():void
{
var wp:WaterParticle;
for(var i:uint=0,imax:uint=CREATE_NUM; i<imax; i++)
{
wp = new WaterParticle();
wp.x = CREATE_POS_X;
wp.y = CREATE_POS_Y;
wp.px = BASE_POWER_X * _powerScaleX * (Math.random() / 2 + 0.5);
wp.py = BASE_POWER_Y * _powerScaleY * (Math.random() / 2 + 0.5);
wp.size = BASE_SIZE * (Math.random() / 2 + 0.5);
wp.data = getBitmapCircle(wp.size);
_waters.push(wp);
}
}
private function drawWater():void
{
var newlist:Vector.<WaterParticle> = new Vector.<WaterParticle>();
var mtx:Matrix = new Matrix();
_filter.lock();
_filter.fillRect(_filter.rect, BASE_COLOR);
for(var i:uint=0,imax:uint=_waters.length; i<imax; i++)
{
if(_waters[i].isActive())
{
_waters[i].x += _waters[i].px;
_waters[i].y += _waters[i].py;
_waters[i].px *= FRICTION;
_waters[i].py *= FRICTION;
_waters[i].py += GRAVITY;
//ドット絵?
// _filter.setPixel(
// _waters[i].x,
// _waters[i].y,
// 0x0000
// );
//水っぽいけど、重い。
mtx = new Matrix;
mtx.translate(
_waters[i].x - _waters[i].size/2,
_waters[i].y - _waters[i].size/2
);
_filter.draw(
_waters[i].data,
mtx
);
//速いけど、角ばって水じゃない
// _filter.fillRect(
// new Rectangle(
// _waters[i].x - _waters[i].size/2,
// _waters[i].y - _waters[i].size/2,
// _waters[i].size,
// _waters[i].size
// ),
// 0x000000
// );
newlist.push(_waters[i]);
}
}
_waters = newlist;
_filter.unlock();
var bmd:BitmapData = _bmd.clone()
bmd.applyFilter(
_bmd,
_bmd.rect,
new Point(0,0),
getBitmapFilter()
);
_bm.bitmapData = bmd;
}
private function getBitmapFilter():BitmapFilter
{
var mapBitmap:BitmapData = _filter;
var mapPoint:Point = new Point(0, 0);
var channels:uint = BitmapDataChannel.RED;
var componentX:uint = channels;
var componentY:uint = channels;
var scaleX:Number = 0.5;
var scaleY:Number = -30;
var mode:String = DisplacementMapFilterMode.CLAMP;
var color:uint = 0;
var alpha:Number = 0;
return new DisplacementMapFilter(mapBitmap,
mapPoint,
componentX,
componentY,
scaleX,
scaleY,
mode,
color,
alpha
);
}
private function getBitmapCircle(radius:Number):BitmapData
{
var s:Sprite = new Sprite();
var g:Graphics = s.graphics;
var m:Matrix = new Matrix();
var bd:BitmapData = new BitmapData(radius * 2, radius * 2, true, 0x00000000);
var scale:Number = 1.0 / 1638.4 * radius * 2;
m.identity();
m.scale(scale , scale);
m.translate(radius, radius);
g.beginGradientFill(
GradientType.RADIAL,
[0x000000, 0x000000],
[1, 0.5],
[0x00, 0xFF],
m,
SpreadMethod.PAD,
InterpolationMethod.RGB,
0
);
g.drawCircle(
radius,
radius,
radius
);
bd.draw(s);
return bd;
}
}
}
import flash.display.BitmapData;
class WaterParticle
{
public var x:Number;
public var y:Number;
public var px:Number;
public var py:Number;
public var size:Number;
public var data:BitmapData;
public function WaterParticle()
{
}
public function isActive():Boolean
{
if(y <= Fountain.STAGE_HEIGHT + size/2
&& y >= -size/2
&& x <= Fountain.STAGE_WIDTH + size/2
&& x >= -size/2)
{
return true;
}
return false;
}
}