БлогNot. Немного "Жизни"...

Помощь дата->рейтинг Поиск Почта RSS канал Статистика nickolay.info Домой

Немного "Жизни"...

По статистике, как минимум каждый 3-й программист это писал :) Ещё одна js-canvas-манипуляция на тему классической "Жизни" Конвея.

Что-то скучно, делами заниматься не хочется, и спать тоже :(

Играется на тороидальном поле, так законченней, раз бесконечного не сделать :) Настройки видны в тексте. "Мерцание"цвета фигур - просто так :) Для начала игры кликните по полю, для паузы - кликните ещё раз. Клавиша F5 - начать заново.

 Скрипт в работе

Полный исходник (предполагается, что будет размещён в Юникоде):

<!doctype html>
<html>
<head>
 <title>Conway's Life Game</title>
 <meta charset='utf-8' />
</head>
<body>

<div align="center"><small>
<font color="darkred">клик по полю</font>:&nbsp;старт/стоп
&nbsp;&nbsp;&nbsp;
<font color="darkred">F5</font>:&nbsp;перезагрузить
&nbsp;&nbsp;&nbsp;
<font color="darkred">крткст</font>:&nbsp;с.т.</small></div>

<div id="div" align="center">
<canvas id="canvas" style="border:0px">
<p>Похоже, ваш браузер не поддерживает HTML5 и тег &lt;canvasas&gt;.</p>
<p>Попробуйте использовать один из следующих браузеров:</p>
<ul>
 <li>Chrome (&gt;4.0)</li>
 <li>Opera (&gt;9.0)</li>
 <li>Opera Mobile (&gt;10.0)</li>
 <li>Firefox (&gt;2.0)</li>
 <li>Safari (&gt;3.1)</li>
 <li>iOS Safari (&gt;3.2)</li>
 <li>Android Browser (&gt;2.1)</li>
 <li>Internet Explorer (&gt;=9.0)</li>
</ul>
</canvas>
</div>

<script type="application/x-javascript">

var b = document.getElementById("div");
var c = document.getElementById("canvas");
var a = c.getContext("2d");
c.width=document.body.clientWidth; //размеры
c.height=screen.height-132;        //холста

var baseSize = 5; //размер ячейки, пикс., [1-??]
var startPerCent = 13; //начальный процент живых клеток, [1-99]
var levelRGB=100; //предельная яркость R,G или B для закрашенной клетки, [0-255]
var mainDelay=10; //главная задержка, мс., [5-??]

function lifeGameFunction (width, height, baseSize) {
 this.width = width;
 this.height = height;
 this.baseSize = baseSize;
 this.grid = new Array();

 this.initGame = function(){
  for (var i = 0; i < this.width; i++) {
   this.grid[i] = new Array();
   for (var j = 0; j < this.height; j++) {
    this.grid[i][j] = false;
   }
  }
 };

 this.fillFieldByRandom = function (perCentOfLive) {
  for (var i = 0; i < this.width; i++) {
   for (var j = 0; j < this.height; j++) {
    this.grid[i][j] = Math.floor(Math.random() * 100/perCentOfLive) == 0;
   }
  }
 }

 this.gridPosition = function(i, widthCanvas) {
  var gridX = Math.floor((i%widthCanvas)/this.baseSize);
  var gridY = Math.floor((i/widthCanvas)/this.baseSize);
  return {x: gridX, y: gridY};
 }

 this.neighbours = function(x,y) {
  var cnt = 0;
  if (x == 0) x = this.width;
  if (y == 0) y = this.height;
  for (var i=x-1; i<x+2; i++) {
   for (var j=y-1; j<y+2; j++) {
    if (!(i == x && j == y)) {
     var posX = i % this.width;
     var posY = j % this.height;
     if (this.grid[posX][posY]) cnt++;
    }
   }
  }
  return cnt;
 }

 this.oneStep  = function() {
  var newGrid = new Array();
  for (var i=0; i<this.width; i++) {
   newGrid[i] = new Array();
   for (var j = 0; j < this.height; j++) {
    newGrid[i][j] = false;
   }
  }
  for (var i=0; i<this.width; i++) {
   for (var j=0; j<this.height; j++) {
    var numNeighbours = this.neighbours (i,j);
    if (this.grid[i][j]) {
     if (numNeighbours == 2 || numNeighbours == 3) { //классические правила
      newGrid[i][j] = true;
     }
    }
    else {
     if (numNeighbours == 3) {
      newGrid[i][j] = true;
     }
    }
   }
  }
  this.grid = newGrid;
 }

 this.getRandomInt = function (min, max) {
  return min + Math.floor(Math.random() * (max - min + 1));
 }

 this.drawField = function (c) {
  var dataArray = c.createImageData(this.width*this.baseSize, this.height*this.baseSize);
  var area = dataArray.data.length;
  var widthCanvas = this.width * this.baseSize;
  var R = this.getRandomInt(0,levelRGB);
  var G = this.getRandomInt(0,levelRGB);
  var B = this.getRandomInt(0,levelRGB);
  for (var i=0; i<area/4; i++) {
   var position = this.gridPosition (i, widthCanvas);
   var gridX = position.x;
   var gridY = position.y;
   if (this.grid[gridX][gridY]) {
    dataArray.data[4*i] =   R;  //R - The color red (from 0-255)
    dataArray.data[4*i+1] = G;  //G - The color green (from 0-255)
    dataArray.data[4*i+2] = B;  //B - The color blue (from 0-255)
    dataArray.data[4*i+3] = 255;//A - The alpha channel (from 0-255; 0 is transparent and 255 is fully visible)
   }
  }
  c.putImageData (dataArray,0,0);
 }

} //lifeGameFunction
    

function mainGameCycle() {
 lifeGame.oneStep();
 lifeGame.drawField(a);
 window.idTimeout = setTimeout(mainGameCycle, mainDelay);
}


function startOrStopGame(){
 if (window.idTimeout) {
  clearTimeout (window.idTimeout);
  window.idTimeout = undefined;
 }
 else{
  window.idTimeout = setTimeout(mainGameCycle, mainDelay);
 }
}

function main() {
 var width = Math.floor(c.width / baseSize);
 var height  = Math.floor(c.height / baseSize);
 window.lifeGame = new lifeGameFunction (width, height, baseSize);
 lifeGame.initGame();
 lifeGame.fillFieldByRandom(startPerCent);
 lifeGame.drawField(a);
  window.onclick = startOrStopGame;
}

window.onload = main;
    
</script>
<noscript>
<p><b>Для работы приложения нужен включённый в браузере Javascript!</b></p>
</noscript>

</body></html>

Несколько раз запустив, обратил внимание, что самодвижущиеся планёры возникают из хаоса достаточно часто, но далеко они не улетают, сражённые неподвижными или крутящимися на месте фигурами. Всё как в большой жизни :)

 Golly - open-source приложение для игры "Жизнь", невероятные конфигурации

 Продвинутая Жизнь на Хабре


теги: графика javascript игра

комментарии (0)

27.01.2016, 23:55; рейтинг: 3476

  свежие записипоиск по блогукомментироватьстатистика

Наверх Яндекс.Метрика
© PerS
вход