気体のような何か
パーティクル祭りらしいので。
クリックでピストン移動です。いろいろ怪しげです。
/**
* 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;
}
}