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

気体のような何か

パーティクル祭りらしいので。
クリックでピストン移動です。いろいろ怪しげです。
Get Adobe Flash player
by k0rin 17 Apr 2009
/**
 * Copyright k0rin ( http://wonderfl.net/user/k0rin )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cnd8
 */

// パーティクル祭りらしいので。
// クリックでピストン移動です。いろいろ怪しげです。
package {
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "0x000000")]
	public class Gas10000 extends Sprite {
		private const W:int = stage.stageWidth;
		private const H:int = stage.stageHeight;
		
		private const NUMBER_OF_MOLECULES:int = 10000;
		private var molecules:Vector.<Molecule> = new Vector.<Molecule>();
		
		private var frameBuffer:BitmapData = new BitmapData(W, H, false, 0x00000000);
		private var colorTransform:ColorTransform;
		
		private var world:BitmapData = new BitmapData(W, H, true, 0x00000000);
		private const T:int = 10;
		
		private var map:Vector.<int> = new Vector.<int>(W * H);
		private const MAP_VOID:int = 0;
		private const MAP_WALL:int = 1;
		private const MAP_PISTON:int = 2;
		
		private const CYLINDER_X:int = W * 0.15;
		private const CYLINDER_Y:int = H / 2;
		private const CYLINDER_LENGTH:int = W * 0.7;
		private const CYLINDER_RADIUS:int = H * 0.15;
		
		private const PISTON_T:int = W * 0.07;
		private var pistonX:Number = CYLINDER_X + CYLINDER_LENGTH * 0.65;
		private var pistonVX:Number = 0;
		
		private var hud:Shape = new Shape();
		
		public function Gas10000() {
			drawSolid(MAP_WALL, 0xFFFFFFFF, 0, 0, T, H);
			drawSolid(MAP_WALL, 0xFFFFFFFF, W - T, 0, T, H);
			drawSolid(MAP_WALL, 0xFFFFFFFF, 0, 0, W, T);
			drawSolid(MAP_WALL, 0xFFFFFFFF, 0, H - T, W, T);
			
			drawSolid(MAP_WALL, 0xFFEEEEFF, CYLINDER_X, CYLINDER_Y - CYLINDER_RADIUS, T, CYLINDER_RADIUS * 2);
			drawSolid(MAP_WALL, 0xFFEEEEFF, CYLINDER_X, CYLINDER_Y - CYLINDER_RADIUS - T, CYLINDER_LENGTH, T);
			drawSolid(MAP_WALL, 0xFFEEEEFF, CYLINDER_X, CYLINDER_Y + CYLINDER_RADIUS    , CYLINDER_LENGTH, T);
			
			drawPiston();
			
			for (var i:int = 0; i < NUMBER_OF_MOLECULES; i++) {
				var x:int = Math.random() * W;
				var y:int = Math.random() * H;
				if (map[y * W + x] != MAP_VOID) {
					i--;
					continue;
				}
				// 動きが見えにくいので、酸素のようなものと窒素のようなものに分けてみる。
				molecules.push(new Molecule(x, y, i < NUMBER_OF_MOLECULES * 0.2 ? 0xFFFFFF : 0x99AAFF));
			}
			colorTransform = new ColorTransform(1, 1, 1, 1, -120, -120, -120);
			
			addChild(new Bitmap(frameBuffer));
			addChild(new Bitmap(world));
			addChild(hud);
			
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		private function drawSolid(attribution:int, color:uint, x:int, y:int, w:int, h:int):void {
			for (var iy:int = y; iy < y + h; iy++) {
				for (var ix:int = x; ix < x + w; ix++) {
					map[iy * W + ix] = attribution;
				}
			}
			world.fillRect(new Rectangle(x, y, w, h), color);
		}
		
		private function drawPiston():void {
			drawSolid(MAP_PISTON, 0xFFEEEEFF, pistonX, CYLINDER_Y - CYLINDER_RADIUS, PISTON_T, CYLINDER_RADIUS * 2);
			drawSolid(MAP_WALL, 0xFF444466, pistonX + PISTON_T, CYLINDER_Y - T, W - pistonX - PISTON_T, T * 2);
		}
		private function erasePiston():void {
			drawSolid(MAP_VOID, 0x00000000, pistonX, CYLINDER_Y - CYLINDER_RADIUS, PISTON_T, CYLINDER_RADIUS * 2);
			drawSolid(MAP_VOID, 0x00000000, pistonX + PISTON_T, CYLINDER_Y - T, W - pistonX - PISTON_T, T * 2);
		}
		
		private var isMouseDown:Boolean = false;
		private function mouseDownHandler(event:MouseEvent):void {
			isMouseDown = true;
		}
		private function mouseUpHandler(event:MouseEvent):void {
			isMouseDown = false;
		}
		
		private function enterFrameHandler(event:Event):void {
			frameBuffer.colorTransform(frameBuffer.rect, colorTransform);
			frameBuffer.lock();
			for each(var m:Molecule in molecules) {
				if (map[int(m.y) * W + int(m.x + m.vx)]) {
					if (map[int(m.y) * W + int(m.x + m.vx)] == MAP_PISTON) {
						if (m.x < pistonX + PISTON_T / 2) {
							m.x = pistonX;
						}
						if (m.x > pistonX + PISTON_T / 2) {
							m.x = pistonX + PISTON_T;
						}
						pistonVX += m.vx * 0.008;
					}
					m.vx = -m.vx;
				}
				m.x += m.vx;
				if (map[int(m.y + m.vy) * W + int(m.x)]) {
					m.vy = -m.vy;
				}
				m.y += m.vy;
				frameBuffer.setPixel(m.x, m.y, m.color);
			}
			frameBuffer.unlock();
			
			var g:Graphics = hud.graphics;
			g.clear();
			if (isMouseDown) {
				g.lineStyle(2, 0xFF0000);
				g.moveTo(pistonX + PISTON_T / 2, CYLINDER_Y);
				g.lineTo(mouseX, mouseY);
				pistonVX += (mouseX - pistonX) * 0.008;
				
				if (pistonVX > 5) { pistonVX = 5; };
				if (pistonVX < -5) { pistonVX = -5; };
			}
			
			erasePiston();
			pistonVX *= 0.7;
			pistonX += pistonVX;
			if (pistonX < CYLINDER_X + T + 5) {
				pistonX = CYLINDER_X + T + 5;
			}
			if (pistonX > W - T - PISTON_T) {
				pistonX = W - T - PISTON_T;
			}
			drawPiston();
		}
	}
}

class Molecule {
	public var x:Number;
	public var y:Number;
	public var vx:Number;
	public var vy:Number;
	public var color:uint;
	
	private static const SPEED_FACTOR:Number = 4;
	private static const MAX_SPEED:Number = 10;
	
	public function Molecule(x:Number, y:Number, color:uint) {
		this.x = x;
		this.y = y;
		this.color = color;
		
		// 正規分布
		var speed:Number = Math.sqrt( -2 * Math.log(1 - Math.random())) * SPEED_FACTOR;
		// すり抜け防止
		if (speed > MAX_SPEED) {
			speed = MAX_SPEED;
		}
		var angle:Number = 2 * Math.PI * Math.random();
		vx = Math.cos(angle) * speed;
		vy = Math.sin(angle) * speed;
	}
}