Skip to content

Instantly share code, notes, and snippets.

@omiend
Created July 7, 2015 09:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omiend/190413fb0a4a9f738bb7 to your computer and use it in GitHub Desktop.
Save omiend/190413fb0a4a9f738bb7 to your computer and use it in GitHub Desktop.
Three.js - LifeGame - Colorful
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>三次元ライフゲーム</title>
<script type="text/javascript" src="https://www.googledrive.com/host/0BxNQTV_CEVCHfm9kR1ZYdW1MYUtsLXhZV3Q4a3ZLQjgyWnZQZGF4MXpDYnZZNk9DRUg0QXM/javascript/three.js"></script><!-- Three.js -->
<script type="text/javascript" src="https://www.googledrive.com/host/0BxNQTV_CEVCHfm9kR1ZYdW1MYUtsLXhZV3Q4a3ZLQjgyWnZQZGF4MXpDYnZZNk9DRUg0QXM/javascript/TrackballControls.js"></script><!-- TrackballControls.js -->
<script type="text/javascript" src="https://www.googledrive.com/host/0BxNQTV_CEVCHfm9kR1ZYdW1MYUtsLXhZV3Q4a3ZLQjgyWnZQZGF4MXpDYnZZNk9DRUg0QXM/javascript/jquery-2.1.4.min.js"></script>
</head>
<body>
<div>
世代:<input id="gene" size="3"/>
<button onclick="random()">RANDOM</button>
<button onclick="start()">START</button>
<button onclick="stop()">STOP</button>
<button onclick="oneStep()">ONE STEP</button>
</div>
<hr />
<div id="container"></div>
<script>
// --------------------------------------------------------------
// --- HTML
// --------------------------------------------------------------
var container = document.getElementById("container"); // コンテナー
// Global変数 (Three.js)
var camera; // カメラ
var trackBall; // トラックボール
var scene; // シーン
var renderer; // レンダー
// Global変数 (LifeGame)
var cells; // セル
var tmpCells; // セル一時領域
var cellSize = 21; // セルのサイズ
var intervalId; // 繰り返し処理ID
var geneCount = 1; // 世代
// --------------------------------------------------------------
// 初期処理実行
// --------------------------------------------------------------
init();
animate();
// --------------------------------------------------------------
// --- Three.js
// --------------------------------------------------------------
// 初期化処理
function init() {
// カメラ初期化
initCamera();
// トラックボール初期化
initTrackBall();
// レンダー初期化
initRenderer();
// セル初期化
random();
// セル初期化
initCells = new Array(cellSize);
for (x = 0; x < cellSize; x++){
initCells[x] = new Array(cellSize);
for (y = 0; y < cellSize; y++){
initCells[x][y] = new Array(cellSize);
for (z = 0; z < cellSize; z++){
initCells[x][y][z] = 0;
}
}
}
// 描写
view();
}
// カメラ初期化
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 50;
}
// トラックボール初期化
function initTrackBall() {
trackBall = new THREE.TrackballControls(camera);
}
// レンダー初期化
function initRenderer() {
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000);
container.appendChild(renderer.domElement);
}
// 描写
function animate() {
requestAnimationFrame(animate);
renderer.render(scene,camera);
trackBall.update();
}
// --------------------------------------------------------------
// --- LifeGame
// --------------------------------------------------------------
// ライフゲームスタート
function start() {
// 既存処理をストップ
stop();
// 繰り返し処理実行
intervalId = setInterval(
function() {
// 世代交代処理実行
alternationOfGenerations();
// 描写
view();
}
,250
);
}
// 世代交代
function alternationOfGenerations() {
// 初期化
var tmpCells = $.extend(true, [], initCells);
for (x in cells) {
for (y in cells[x]) {
for (z in cells[x][y]) {
tmpCells[x][y][z] = roule(x, y, z);
}
}
}
// 変異しない場合はストップ
if (JSON.stringify(cells) == JSON.stringify(tmpCells)) {
stop();
} else {
// 世代更新
++geneCount;
cells = tmpCells;
}
}
// 変異ルール
function roule(x, y, z) {
var count = 0;
var xxFrom = parseInt(x) - 1;
var xxTo = parseInt(x) + 1;
var yyFrom = parseInt(y) - 1;
var yyTo = parseInt(y) + 1;
var zzFrom = parseInt(z) - 1;
var zzTo = parseInt(z) + 1;
for (xx = xxFrom; xx <= xxTo; xx++) {
if (xx < 0) continue;
if (xx == cellSize) break;
for (yy = yyFrom; yy <= yyTo; yy++) {
if (yy < 0) continue;
if (yy == cellSize) break;
for (zz = zzFrom; zz <= zzTo; zz++) {
if (zz < 0 || (x == xx && y == yy && z == zz)) continue;
if (zz == cellSize) break;
try {
if (cells[xx][yy][zz]) {
count = count + cells[xx][yy][zz];
}
} catch (e) {
}
}
}
}
// 死
if (count >= 8 || count <= 3) {
return 0;
// 誕生
} else if (count == 6) {
return 1;
// 変異なし
} else {
return cells[x][y][z];
}
}
// 描写
function view() {
$("#gene").val(geneCount);
scene = new THREE.Scene();
var geometry = new THREE.Geometry();
var colors = [];
for (x in cells) {
for (y in cells[x]) {
for (z in cells[x][y]) {
if (cells[x][y][z] == 1) {
var vertex = new THREE.Vector3();
vertex.x = parseInt(x) + (cellSize / 2 * -1);
vertex.y = parseInt(y) + (cellSize / 2 * -1);
vertex.z = parseInt(z) + (cellSize / 2 * -1);
geometry.vertices.push(vertex);
var color = new THREE.Color(Math.floor(Math.random() * 0xFFFFFF));
colors.push(color);
}
}
}
}
geometry.colors = colors;
scene.add(new THREE.PointCloud(geometry, new THREE.PointCloudMaterial({size:1, vertexColors: true})));
animate();
}
// ランダム値で初期化
function random() {
geneCount = 1;
cells = new Array(cellSize);
initCells = new Array(cellSize);
for (x = 0; x < cellSize; x++){
if (x == cellSize) break;
cells[x] = new Array(cellSize);
initCells[x] = new Array(cellSize);
for (y = 0; y < cellSize; y++){
if (y == cellSize) break;
cells[x][y] = new Array(cellSize);
initCells[x][y] = new Array(cellSize);
for (z = 0; z < cellSize; z++){
if (z == cellSize) break;
cells[x][y][z] = Math.floor(Math.random()*2);
initCells[x][y][z] = 0;
}
}
}
// 描画
view();
}
// 1ステップのみ実行
function oneStep() {
stop();
// 世代交代処理実行
alternationOfGenerations();
// 描写
view();
}
// ライフゲームストップ
function stop() {
console.log("ID:" + intervalId + "の処理をストップしました。");
clearInterval(intervalId);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment