ライフゲーム
ライフゲーム
( http://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0 )
SPACEを押せばライフゲーム開始
あとは,数字キーを押したり、
Zでズームしたりして遊ぶ。
LIFE GAME
start/stop: SPACE
reset: c
decel/accel: ← / →
random: x
zoom: z
stamp: 1-3
stamp reverse (x): +↑
stamp reverse (y): +↓
stamp reverse (x/y): +SHIHT
/**
* Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4g7u
*/
// forked from shohei909's 足し算をするセルオートマン - celllular automaton,which do addition
package {
/*
* ライフゲーム
* とりあえずSPACEを押せばライフゲーム開始
* あとは,数字キーを押したり、
* Zでズームしたりして遊ぶ。
*
* LIFE GAME
*
* start/stop: SPACE
* reset: c
* decel/accel: ← / →
* random: x
* zoom: z
* stamp: 1-3
* stamp reverse (x): +↑
* stamp reverse (y): +↓
* stamp reverse (x/y): +SHIHT
*/
import flash.events.KeyboardEvent;
import flash.display.Sprite;
import flash.events.Event;
public class FlashTest extends Sprite {
public var game:Game;
public var zoom:Boolean = false;
public var zoomX:int;
public var zoomY:int;
public var revX:Boolean = false;
public var revY:Boolean = false;
public function FlashTest() {
game = new Game();
stage.frameRate = 60;
addChild(game);
stage.addEventListener( KeyboardEvent.KEY_DOWN , onDown);
stage.addEventListener( KeyboardEvent.KEY_UP , onUp);
addEventListener( Event.ENTER_FRAME , onFrame);
}
public function onDown(e:KeyboardEvent):void{
if(e.keyCode == 32){
game.brain.player(null);
}else if(e.keyCode == 67){
game.brain.reset(null);
}else if(e.keyCode == 88){
game.brain.random(null);
}else if(e.keyCode == 37){
if(Game.SPAN < 256){Game.SPAN*=2;}
}else if(e.keyCode == 39){
if(Game.SPAN > 1){Game.SPAN/=2;}
}else if(e.keyCode == 38){
revX = true;
}else if(e.keyCode == 40){
revY = true;
}else if(e.keyCode == 90 && zoom==false){
zoom = true;
zoomX = mouseX;
zoomY = mouseY;
}else if(e.keyCode >= 48 &&e.keyCode <= 57){
//ショートカット1
var num:int = e.keyCode-48;
var i:int = game.brain.mouseX / Game._SCALE;
var j:int = game.brain.mouseY / Game._SCALE;
if(revY){var dx:int = -1;}else{dx=1;}
if(revX){var dy:int = -1;}else{dy=1;}
if(e.shiftKey){var r:Boolean = true;}else{r=false;}
game.brain.stamp(i,j,num,dx,dy,r);
}
}
public function onUp(e:KeyboardEvent):void{
if(e.keyCode == 90){
zoom = false;
}else if(e.keyCode == 38){
revX = false;
}else if(e.keyCode == 40){
revY = false;
}
}
public function onFrame(e:Event):void{
if(zoom){
game.scaleX = (4 + game.scaleX*7)/8;
game.scaleY = game.scaleX;
}else{
game.scaleX = (1 + game.scaleX*7)/8;
game.scaleY = game.scaleX;
}
zoomX = (31*zoomX + mouseX)/32;
zoomY = (31*zoomY + mouseY)/32;
game.x = zoomX - (game.scaleX * zoomX);
game.y = zoomY - (game.scaleX * zoomY);
}
}
}
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.display.*;
import mx.utils.*;
class Game extends Sprite{
public static var _WIDTH:int = 116;
public static var _HEIGHT:int = 116;
public static var _SCALE:int = 4;
public static var SPAN:int = 16;
public static var ELECT:Boolean = false;
public static var BIRTH_MIN:int = 3;
public static var BIRTH_MAX:int = 3;
public static var LIVE_MIN:int = 2;
public static var LIVE_MAX:int = 3;
public static var DATA:Array = [
[[0,1,1],[1,1,0],[0,1,0]],
[[1,0,0],[0,1,1],[1,1,0]],
[[0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,1]],
[[0,0,1],[1,0,0,0,1],[0,0,0,0,0,1],[1,0,0,0,0,1],[0,1,1,1,1,1]],
[[0,0,1,1],[1,0,0,0,0,1],[0,0,0,0,0,0,1],[1,0,0,0,0,0,1],[0,1,1,1,1,1,1]],
[[1,1,1,1,1,1,1,1,1,1]],
[
[0,0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,1,0,1],
[0,0,0,0,0,0,1,0,1],
[0,0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,0,0,0,0,0,0,1,1,0],
[0,1,0,0,1,0,0,0,0,0,1,0,0,1],
[0,0,1,1,0,0,0,0,0,0,1,1,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,0],
[0,0,0,0,0,0,1,0,1],
[0,0,0,0,0,0,1,0,1],
[0,0,0,0,0,0,0,1,0]
],
[
[0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,1],
[0],[0],[0],
[1],[0,1,1],[0,0,1],[0,0,1],[0,1],
[0],[0],
[0,0,0,1,0],[0,0,0,0,1],[1,0,0,0,1],[0,1,1,1,1]
],
[
[0,0,1,0,0,0,0,1,0,0,0],
[1,1,0,1,1,1,1,0,1,1,0],
[0,0,1,0,0,0,0,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,1,1,1,1,0,1,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0]
],
[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]
];
public var brain:Medium;
public function Game():void{
brain = new Medium();
addChild(brain);
addEventListener("mouseDown",onDown);
addEventListener("enterFrame",loop);
}
public function onDown(e:MouseEvent):void{
var i:int = e.target.mouseX / _SCALE;
var j:int = e.target.mouseY / _SCALE;
brain.cells[i + _WIDTH*j].change(null);
}
private function loop(e:Event):void{
brain.loop();
}
}
class Medium extends Bitmap{
public var w:int = 0;
public var h:int = 0;
public var cellSize:int = 25;
public var play:Boolean = false;
public var cells:Vector.<Cell>;
public var electrons:Vector.<Electron>;
private var count:int = 0;
private var nowMap:BitmapData;
public var eShape:EShape = new EShape();
public function Medium(){
w = Game._WIDTH;
h = Game._HEIGHT;
cellSize = Game._SCALE;
electrons = new Vector.<Electron>();
cells = new Vector.<Cell>();
for(var i:int=0;i<w;i++){
for(var j:int=0;j<h;j++){
cells[i*h + j] = new Cell(j,i);
}
}
//ライフゲーム用---------------------------
for(var n:int=0;n<w;n++){
for(var m:int=0;m<h;m++){
for(var k:int= -1;k<2;k++){
for(var l:int= -1;l<2;l++){
i = n+k;
j = m+l;
if( i>=0 && i<h && (k!=0 || l!=0) ){
connect(n+m*w,i+j*w);
}
}
}
}
}
//------------------------------------------
nowMap = new BitmapData( w*cellSize+2, h*cellSize+2, false, 0x000000 );
super(new BitmapData( w*cellSize+2, h*cellSize+2, false, 0x000000 ));
}
public function player(e:Event):void{
play = (play == false);
}
public function reset(e:Event):void{
for each(var cell:Cell in cells){
cell.alive = false;
cell.count = 0;
}
}
public function random(e:Event):void{
for(var i:int=0; i<cells.length/25; i++){
var n:int = cells.length*Math.random();
cells[n].alive = true;
}
}
public function loop():void{
drow();
count++;
if(count%Game.SPAN == 0 && play){
for(var i:uint=0; i<w; i++){
for(var j:uint=0; j<h; j++){
cell = cells[i+j*w];
if(cell.alive){
if(Game.ELECT){
for each(var syn:Synapse in cell.synapses){
var sx:int = (cell.x+1/2) * cellSize;
var sy:int = (cell.y+1/2) * cellSize;
var tx:int = (syn.target.x+1/2) * cellSize;
var ty:int = (syn.target.y+1/2) * cellSize;
for(var n:uint=0;n<syn.strength;n++){
var el:Electron = new Electron(sx,sy,tx,ty,Game.SPAN);
electrons.push(el);
}
}
}
cell.pass();
}
}
}
for each(var cell:Cell in cells){
cell.setting();
}
}
}
public function connect(st:int, en:int,s:int = 1):void{
if(en>=0 && en < cells.length){
cells[st].synapses.push( new Synapse(cells[en],s));
}
}
public function drow():void{
nowMap.lock();
bitmapData.lock();
for(var i:int=0; i<w; i++){
for(var j:int=0; j<h; j++){
var cell:Cell = cells[i+j*w];
var rect:Rectangle = new Rectangle(i*cellSize+1,j*cellSize+1,cellSize-1,cellSize-1);
if(cell.alive){
nowMap.fillRect(rect, cell.color);
}else if(cell.over){
nowMap.fillRect(rect, 0x191111 );
}else{
nowMap.fillRect(rect, 0x111111);
}
}
}
for( i=0;i< electrons.length;i++){
var el:Electron = electrons[i];
var mtr:Matrix = new Matrix();
mtr.translate(el.x, el.y);
nowMap.draw(eShape,mtr);
if(el.life == 0){
electrons.splice(i,1);
i--;
}else{ el.move(); }
}
rect = bitmapData.rect;
var point:Point = new Point(0,0);
var rate:uint = 0xE0;
nowMap.unlock();
bitmapData.merge(nowMap,rect,point,rate,rate,rate,rate);
nowMap.fillRect(rect,0x000000);
bitmapData.unlock();
}
public function stamp(j:int,i:int,num:int,dx:int=1,dy:int=1,rot:Boolean=false):void{
var data:Array = Game.DATA[num];
for(var n:int = 0; n < data.length;n++){
for(var m:int = 0; m < data[n].length;m++){
if(rot){
var an:int = m*dx+i; var am:int = n*dy+j;
}else{
an= n*dx+i;am= m*dy+j;
}
if(an>=0 && an<w && am>=0 && am<h){
cells[an*h+am].alive=(data[n][m]>0);
}
}
}
}
}
class EShape extends Shape{
public function EShape():void{
filters = [new GlowFilter(0x00AAFF)];
with(graphics){
beginFill (0xFFFFFF, 1.0);
drawCircle( 0, 0 ,2);
}
}
}
class Electron{
public var x:int;
public var y:int;
public var targetX:int;
public var targetY:int;
public var life:int;
private var r:Number;
private var deg:Number;
private var dv:Number;
public function Electron(sx:int,sy:int,tx:int,ty:int,l:int){
targetX = tx;
targetY = ty;
x = sx;
y = sy;
life = l;
var lx:int = x-targetX;
var ly:int = y-targetY;
r = Math.sqrt( lx*lx + ly*ly)/life;
deg = Math.atan2(ly, lx);
dv = Math.random()*0.4-0.2;
}
public function move():void{
var nr:Number = r * life;
deg += dv;
x = targetX + nr * Math.cos(deg);
y = targetY + nr * Math.sin(deg);
life--;
}
}
class Cell{
public var x:int;
public var y:int;
public var alive:Boolean = false;
public var over:Boolean = false;
public var count:int = 0;
public var color:uint = 0;
public var synapses:Vector.<Synapse>;
public function Cell(px:int,py:int){
x = px;
y = py;
synapses = new Vector.<Synapse>();
changeColor();
}
public function changeColor():void{
color = 0xFFFFFF*Math.random();
color = ColorUtil.adjustBrightness2(color,-50);
color = ColorUtil.adjustBrightness(color,100);
}
public function pass():void{
changeColor();
for each(var synapse:Synapse in synapses){synapse.pass();}
}
public function setting():void{
over = (
( alive && (count > Game.LIVE_MAX ) )
||( (alive == false) && (count > Game.BIRTH_MAX ) )
);
alive = (
( alive && (count >= Game.LIVE_MIN ) && (count <= Game.LIVE_MAX ) )
||( (alive == false) && (count >= Game.BIRTH_MIN ) && (count <= Game.BIRTH_MAX ) )
);
count = 0;
}
public function change(e:Event = null):void{
alive = (alive == false);
}
}
class Synapse{
public var target:Cell;
public var strength:int;
public function Synapse( t:Cell, stg:int = 1){
target=t; strength=stg;
}
public function pass():void{
target.count += strength;
}
}