#12 Conway's Game of Life ver.2 (flash on 2009-8-28)
Conway's Game of Life
*
* 1px=1セル、463x463のライフゲーム。
* クリック: 拡大機能の開始/終了
* キー押下: 初期化(タイムラグ有)
*
* @author krogue
♥0 |
Line 180 |
Modified 2009-08-28 21:37:24 |
MIT License
archived:2017-03-29 13:27:50
ActionScript3 source code
/**
* Copyright krogue ( http://wonderfl.net/user/krogue )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pBin
*/
/**
* Conway's Game of Life
*
* 1px=1セル、463x463のライフゲーム。
* クリック: 拡大機能の開始/終了
* キー押下: 初期化(タイムラグ有)
*
* @author krogue
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]
public class ConwayGame extends Sprite {
private var game:Game;
private var updateCount:uint; // 0..59 の範囲でループ
public function ConwayGame() {
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(event:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
initialize();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(event:Event):void {
update();
}
private function initialize():void {
updateCount = 0;
game = addChild(new Game()) as Game;
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
stage.addEventListener(MouseEvent.CLICK, clickHandler);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
private function update():void {
if (updateCount == 0) {
game.draw();
}
game.drawZoomWindow();
updateCount++;
if (updateCount >= 60) {
updateCount = 0;
}
}
private function keyUpHandler(event:KeyboardEvent):void {
game.reset();
}
private function clickHandler(event:MouseEvent):void {
game.focus(event.stageX, event.stageY);
game.zoom = !game.zoom;
}
private function mouseMoveHandler(event:MouseEvent):void {
game.focus(event.stageX, event.stageY);
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.getTimer;
class Game extends Sprite {
private const WIDTH:int = 465;
private const HEIGHT:int = 465;
private const ZOOM_WIDTH:int = WIDTH / 15; // = 31
private const ZOOM_HEIGHT:int = HEIGHT / 15; // = 31
private const SCALE:int = 5;
private const COLOR_LIFE:uint = 0xFF000000;
private const COLOR_DEAD:uint = 0xFFFFFFFF;
private const INIT_LIFE_NUM:int = WIDTH * HEIGHT / 5;
private var _zoom:Boolean = false;
private var rows:Array /* of Array */ = new Array(HEIGHT);
private var zoomRect:Rectangle =
new Rectangle(0, 0, ZOOM_WIDTH, ZOOM_HEIGHT);
private var bitmap:Bitmap = addChildAt(new Bitmap(), 0) as Bitmap;
private var window:Bitmap = addChildAt(new Bitmap(), 1) as Bitmap;
private var shape:Shape = addChildAt(new Shape(), 2) as Shape;
public function Game() {
bitmap.bitmapData = new BitmapData(WIDTH, HEIGHT, false, COLOR_DEAD);
window.bitmapData = new BitmapData(zoomRect.width, zoomRect.height,
false, COLOR_DEAD);
window.scaleX = SCALE;
window.scaleY = SCALE;
reset();
}
private function updateCount():void {
var endY:int = rows.length - 1;
for (var y:int = 1; y < endY; y++) {
var cols:Array /* of Cell */ = rows[y];
var ncols:Array /* of Cell */ = rows[y + 1];
var endX:int = cols.length - 1;
for (var x:int = 1; x < endX; x++) {
var col:Cell = cols[x];
if (col.life) {
cols[x + 1].count++;
ncols[x - 1].count++;
ncols[x].count++;
ncols[x + 1].count++;
}
if (cols[x + 1].life) col.count++;
if (ncols[x - 1].life) col.count++;
if (ncols[x].life) col.count++;
if (ncols[x + 1].life) col.count++;
}
}
}
public function draw():void {
updateCount();
const bmd:BitmapData = bitmap.bitmapData;
bmd.lock();
var endY:int = rows.length - 1;
for (var y:int = 1; y < endY; y++) {
var cols:Array /* of Cell */ = rows[y];
var endX:int = cols.length - 1;
for (var x:int = 1; x < endX; x++) {
var col:Cell = cols[x];
col.life = ((col.count == 3) || (col.count == 2 && col.life));
bmd.setPixel(x, y, (col.life ? COLOR_LIFE : COLOR_DEAD));
col.count = 0;
}
}
bmd.unlock();
}
public function drawZoomWindow():void {
shape.visible = _zoom;
window.visible = _zoom;
if (_zoom) {
shape.graphics.clear();
shape.graphics.lineStyle(0, 0x00FF00);
shape.graphics.drawRect(zoomRect.x, zoomRect.y,
zoomRect.width, zoomRect.height);
if (zoomRect.x < WIDTH / 2 - zoomRect.width / 2) {
window.x = WIDTH - window.width;
} else {
window.x = 0;
}
window.bitmapData.copyPixels(bitmap.bitmapData, zoomRect,
new Point());
}
}
public function focus(x:int, y:int):void {
const hw:int = zoomRect.width / 2;
const hh:int = zoomRect.height / 2;
zoomRect.x = Math.min(Math.max(x, hw), WIDTH - hw) - hw;
zoomRect.y = Math.min(Math.max(y, hh), HEIGHT - hh) - hh;
}
public function reset():void {
for (var y:int = 0; y < rows.length; y++) {
var cols:Array = new Array(WIDTH);
for (var x:int = 0; x < cols.length; x++) {
cols[x] = new Cell((y * WIDTH + x < INIT_LIFE_NUM), 0);
}
rows[y] = cols;
}
for (var i:int = HEIGHT * WIDTH - 1; i > 0; i--) {
var index:int = Math.floor(Math.random() * (i + 1));
var tx:int = index % WIDTH;
var ty:int = index / WIDTH;
var ix:int = i % WIDTH;
var iy:int = i / WIDTH;
var work:Cell = rows[ty][tx];
rows[ty][tx] = rows[iy][ix];
rows[iy][ix] = work;
}
}
public function get zoom():Boolean {
return _zoom;
}
public function set zoom(value:Boolean):void {
_zoom = value;
}
}
class Cell {
public var life:Boolean;
public var count:uint;
public function Cell(life:Boolean, count:uint) {
this.life = life;
this.count = count;
}
}