flash on 2011-2-17
...
@author 啄木鳥@cybridge.jp
♥0 |
Line 149 |
Modified 2011-02-21 10:27:39 |
MIT License
archived:2017-03-20 17:53:02
ActionScript3 source code
/**
* Copyright kaaad ( http://wonderfl.net/user/kaaad )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/rA6u
*/
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.utils.Timer;
[SWF(backgroundColor="#3333cc", frameRate="60",width="128",height="128" )]
public class Main extends Sprite
{
public const SIZE:Number = 128;
public var screen:BitmapData;
public var CloudData:Array; // 濃度
public var CloudDataD:Array; // 乱数テーブル
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
// 背景色との加算合成
this.blendMode = BlendMode.ADD;
// BitmasDataの初期化
screen = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0xFFFFFFFF );
addChild( new Bitmap( screen ) );
// 雲データの初期化
initCloud();
// 描画
renderCloudData();
}
private function initCloud():void {
// 配列の確保+乱数テーブルの作成
CloudData = new Array(SIZE + 1);
CloudDataD = new Array(SIZE + 1);
var i:int;
var j:int;
for (i = 0; i < SIZE + 1;++i)
{
CloudData[i] = new Array(SIZE + 1);
CloudDataD[i] = new Array(SIZE + 1);
for (j = 0; j < SIZE + 1;++j) {
CloudDataD[i][j] = (Math.random()*2-1.0);
}
}
// 乱数テーブルから雲データの作成
updateCloud();
}
private function updateCloud():void{
// 初期の4点を求める
CloudData[0][0] = CloudDataD[0][0] * SIZE ;
CloudData[0][SIZE] = CloudDataD[0][SIZE] * SIZE ;
CloudData[SIZE][0] = CloudDataD[SIZE][0] * SIZE ;
CloudData[SIZE][SIZE] = CloudDataD[SIZE][SIZE] * SIZE ;
// 再帰処理で残りの点を求める
updateCloud_r(SIZE / 2);
}
private function updateCloud_r(level:int):void {
// 再帰処理脱出
if (level == 0)
{
return;
}
var i:int;
var j:int;
// 前に計算した4点の中間点を求める
for (i = level; i < SIZE; i += level*2 )
{
for (j = level; j < SIZE; j += level*2 ) {
CloudData[i][j] = (CloudData[i - level][j - level] + CloudData[i - level][j + level] + CloudData[i + level][j - level] + CloudData[i + level][j + level]) / 4 + (CloudDataD[i][j] * level);
}
}
// 前に計算した2点と↑で計算した2点から中間点を求める
var count:int;
var c:Number;
for (i = level; i < SIZE; i += level * 2 ) {
for (j = 0; j < SIZE + 1; j += level * 2 )
{
count = 0;
c = 0;
if (checkPoint(i - level, j)) {
++count;
c += CloudData[i - level][ j];
}
if (checkPoint(i + level, j)) {
++count;
c += CloudData[i + level][ j];
}
if (checkPoint(i, j - level)) {
++count;
c += CloudData[i][ j - level];
}
if (checkPoint(i, j + level)) {
++count;
c += CloudData[i][ j + level];
}
CloudData[i][j] = c / count + (CloudDataD[i][j] * level);
}
}
for (i = 0; i < SIZE + 1 ; i += level * 2 )
for (j = level; j < SIZE; j += level * 2 ) {
{
count = 0;
c = 0;
if (checkPoint(i - level, j)) {
++count;
c += CloudData[i - level][ j];
}
if (checkPoint(i + level, j)) {
++count;
c += CloudData[i + level][ j];
}
if (checkPoint(i, j - level)) {
++count;
c += CloudData[i][ j - level];
}
if (checkPoint(i, j + level)) {
++count;
c += CloudData[i][ j + level];
}
CloudData[i][j] = c / count+ (CloudDataD[i][j]*level);
}
}
// 再帰呼び出し
updateCloud_r(level / 2);
}
// 座標が適切かどうか調べる
private function checkPoint(i:int, j:int):Boolean
{
if (0 <= i && i < SIZE + 1 && 0 <= j && j < SIZE + 1) {
return true;
}
return false;
}
// レンダリング
private function renderCloudData():void
{
var i:int;
var j:int;
var c:int;
var c_max:Number;
var c_min:Number;
var d:Number;
c_max = CloudData[0][0];
c_min = -CloudData[0][0];
for (i = 0; i < SIZE;++i) {
for (j = 0; j < SIZE;++j ) {
c_max = Math.max(c_max, CloudData[i][j]);
c_min = Math.min(c_min, CloudData[i][j]);
}
}
d = c_max - c_min;
screen.lock();
for (i = 0; i < SIZE;++i) {
for (j = 0; j < SIZE;++j ) {
c = 255 * (CloudData[i][j] - c_min) / d;
screen.setPixel32(i, j, (0xff000000 | (c<<16) | (c<<8) | c ));
}
}
screen.unlock();
}
}
}