Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Игра Жизнь - это клеточный автомат созданный в 1970 году Джоном Конвеем
Это не совсем игра, а просто симуляция клеток по определенным правилам.От игрока лишь требуется размещать эти клетки.
В этом посте мы сделаем "Игру Жизнь" на HTML странице при помощи CSS & JS
Правила
Клетка - она может быть либо живой (темной), либо мертвой (белой).
У клетки есть 8 соседей вокруг и могут влиять на нее.
Если клетка мертва и у нее есть 3 живых соседа, тогда она рождается.
Если клетка жива и у нее есть 2 или 3 соседа, то она остается живой.В противном случае умирает от перенаселения или одиночества
Пишем главную страницу:
Создаем базовый код HTML и подключаем к нему .css и .js
Обозначим главный блок div в котором будут находится все клетки:
<div class="mainBox"></div>
.mainBox {
border: solid 3px #000000;
display: flex;
flex-wrap: wrap;
width: 45%;
height: 83%;
margin: 4% 26%;
position: fixed;
justify-content: flex-start;
}
Внутрь mainBox создаем 256 штук:
<div class="cellBox"></div>
Также сразу же даем класс deathCell и функцию onclick="aliveButtons(this)" для того чтобы в будущем оживлять клетки на которые мы нажимаем
Должно выйти так:
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
Даем стили:
.cellBox { /* Стили клеток */
display: block;
width: 5.77%;
height: 5.75%;
border: solid 2px #808080;
background-color: #ffffff;
}
.deathCell { /* Класс мертвой клетки */
background-color: #ffffff;
}
.aliveCell { /* Класс живой клетки */
background-color: #2c2c2c;
}
Делаем возможность оживлять/убивать кнопки:
В первую очередь сделаем визуальное выделение, чтобы пользователь знал, что на клетки можно нажимать
Для этого воспользуемся :hover
.cellBox:hover {
background-color: #000000;
cursor: pointer;
}
Теперь перейдем на JS и воспользуемся нашими функциями aliveButtons(this)
function aliveButtons(obj) { // получаем через (this) нажатую клетку
if (obj.classList.contains("deathCell")) { // проверяем мертва ли клетка
// оживляем клетку
obj.classList.add("aliveCell") // добавляем класс aliveCell
obj.classList.remove("deathCell") // убираем класс deathCell
} else if (obj.classList.contains("aliveCell")) {
// тоже самое, только наоборот
// убиваем клетку
obj.classList.add("deathCell")
obj.classList.remove("aliveCell")
}
}
Теперь мы можем оживлять и убивать клетки
Пишем JS скрипт:
Для начала стоит получить все наши клетки:
cellBoxes = document.querySelectorAll(".cellBox") // получаем всех через класс
Теперь сделаем главную функцию обновления кадров, чтобы мы могли управлять скоростью всей симуляции
function framesUpdate() {
setTimeout(function () { // цикличная функция
framesUpdate() // вызываем ее вновь
}, 1000) // задержка 1-секунда
}
framesUpdate() // Вызов нашей функции при запуске. Вставляем в конце кода!
Теперь самое интересное.Создаем функцию для определения соседских клеток и заодно в нее засунем правила
function neighborCheck() {}
Задаем универсальный цикл для проверки всех клеток
function neighborCheck() {
for (var i = 0; i < Object.keys(cellBoxes).length; i++) { // сравниваем i с общим кол-вом наших клеток
}
}
Т.к. наша переменная cellBoxes является многомерным массивом, мы можем обратиться в ее каждую клетку и работать с ними
Сейчас мы зададим еще одну переменную в каждой клетке используя цикл
cellBoxes[i].alivedNeighbor = 0
// вначале мы задаем ей значение 0, но в следующие разы просто обновляем ее
Проверяем соседей.Для этого просто будем использовать вычитание
if (i - 17 >= 0) { //Проверка, чтобы мы не проверяли если у блока нет соседей выше
if (cellBoxes[i - 17].classList.contains("aliveCell")) // проверяем жива ли клетка {
cellBoxes[i].alivedNeighbor += 1 // добавляем +1 к кол-ву живых соседей нашей клетки
}
}
if (i - 16 >= 0) { // у нас клетки 16х16 размером, поэтому чтобы проверить верхнюю левую, надо вычислить 17 клеток назад, чтобы верхнюю 16
if (cellBoxes[i - 16].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 15 >= 0) {// тоже самое тут, но уже 15 и т.д.
if (cellBoxes[i - 15].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 1 >= 0) { // чтобы полностью понять как это работает, попробуйте посмотреть соседей клетки через консоль введя cellBoxes[номер клетки - 17]
if (cellBoxes[i - 1].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 1 <= 255) { //тут уже мы смотрим на соседей после самой клетки
if (cellBoxes[i + 1].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 15 <= 255) {
if (cellBoxes[i + 15].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 16 <= 255) {
if (cellBoxes[i + 16].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 17 <= 255) {
if (cellBoxes[i + 17].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
Проверку живых соседей мы сделали, теперь зададим правила
Задаем еще один такой же цикл, чтобы правила работали только после обнаружения у всех клеток, их соседей
for (i = 0; i < Object.keys(cellBoxes).length; i++) { // наш цикл, такой же как и прошлый
if (cellBoxes[i].alivedNeighbor === 3) { // проверяем, если живы 3 соседа
if (cellBoxes[i].classList.contains("deathCell")) { // если клетка уже мертва
cellBoxes[i].classList.add("aliveCell") // оживляем ее
cellBoxes[i].classList.remove("deathCell")
}
} else if (cellBoxes[i].classList.contains("aliveCell")) { // или же если клетка уже жива
if (cellBoxes[i].alivedNeighbor === 2) { // если у нее есть 2 живых соседа
cellBoxes[i].classList.add("aliveCell") // оставляем ее живой
cellBoxes[i].classList.remove("deathCell")
} else { // если у нее не 2 соседа, тогда она умирает
cellBoxes[i].classList.add("deathCell")
cellBoxes[i].classList.remove("aliveCell")
}
} else { // в любых других случаях
if (cellBoxes[i].classList.contains("aliveCell")) { // если клетка жива
cellBoxes[i].classList.add("deathCell") // убиваем ее
cellBoxes[i].classList.remove("aliveCell")
}
}
}
В нашу функцию framesUpdate() добавляем нашу проверку соседей
function framesUpdate() {
setTimeout(function () {
neighborCheck() // вот и проверка соседей
framesUpdate()
}, 1000)
}
Весь код должен выглядить примерно таким:
cellBoxes = document.querySelectorAll(".cellBox")
function aliveButtons(obj) {
if (obj.classList.contains("deathCell")) {
obj.classList.add("aliveCell")
obj.classList.remove("deathCell")
} else if (obj.classList.contains("aliveCell")) {
obj.classList.add("deathCell")
obj.classList.remove("aliveCell")
}
}
function neighborCheck() {
for (var i = 0; i < Object.keys(cellBoxes).length; i++) {
cellBoxes[i].alivedNeighbor = 0
if (i - 17 >= 0) {
if (cellBoxes[i - 17].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 16 >= 0) {
if (cellBoxes[i - 16].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 15 >= 0) {
if (cellBoxes[i - 15].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 1 >= 0) {
if (cellBoxes[i - 1].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 1 <= 255) {
if (cellBoxes[i + 1].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 15 <= 255) {
if (cellBoxes[i + 15].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 16 <= 255) {
if (cellBoxes[i + 16].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 17 <= 255) {
if (cellBoxes[i + 17].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
}
for (i = 0; i < Object.keys(cellBoxes).length; i++) {
if (cellBoxes[i].alivedNeighbor === 3) {
if (cellBoxes[i].classList.contains("deathCell")) {
cellBoxes[i].classList.add("aliveCell")
cellBoxes[i].classList.remove("deathCell")
}
} else if (cellBoxes[i].classList.contains("aliveCell")) {
if (cellBoxes[i].alivedNeighbor === 2) {
cellBoxes[i].classList.add("aliveCell")
cellBoxes[i].classList.remove("deathCell")
} else {
cellBoxes[i].classList.add("deathCell")
cellBoxes[i].classList.remove("aliveCell")
}
} else {
if (cellBoxes[i].classList.contains("aliveCell")) {
cellBoxes[i].classList.add("deathCell")
cellBoxes[i].classList.remove("aliveCell")
}
}
}
}
function framesUpdate() {
setTimeout(function () {
neighborCheck()
framesUpdate()
}, 1000)
}
Основной код мы написали, но без интерфейса мы не можем им управлять
В HTML добавляем следующее (выше mainBox):
<div class="mainInterface"> <!-- главный блок интерфейса -->
<button onclick="startAnim()" class="interfaceBtn">Start</button> <!-- кнопка старта -->
<button onclick="resetToDefault()" class="interfaceBtn">Reset</button> <!-- кнопка для убийства всех блоков -->
<input type="range" min="1" max="255" step="1" value="128" class="interfaceRange" id="genSpeedInput" oninput="setSpeedInput()"> <!-- Ползунок для управления скоростью -->
<p class="interfaceTxt" id="genBySec">Поколений в секунду: 128</p> <!-- текст с нынешней скоростью -->
<p class="interfaceTxt" id="genereationNumber">Поколение: 0</p> <!-- нынешнее поколение -->
</div>
Стили для них:
.mainInterface { /* главный блок интерфейса */
position: fixed; /* Фиксация в левой верхнем углу */
left: 0;
top: 0;
background-color: rgba(73, 73, 73, 0.26);
width: 11%;
height: 25%;
border-radius: 10px;
padding: 20px; /* Чтобы блоки держались чуть дальше от границ */
}
.interfaceBtn { /* Кнопки интерфейса */
width: 90%;
margin: 10px auto; /* центрирование */
display: block;
}
.interfaceRange { /* Ползунок */
margin: 0 auto; /* центрирование */
display: block;
}
Теперь у нас есть интерфейс в левом верхнем углу, но он не рабочий.
Переходим в JS
// просто framesUpdate(), заменяем на:
function startAnim() {
framesUpdate()
}
Теперь у нас рабочий старт по кнопке
Добавляем следующие переменные вначале кода:
genNumberId = document.getElementById("genereationNumber") // По айди получаем текст с номером поколения
genNumber = 0 // сам номер который будет изменяться
genSpeedId = document.getElementById("genBySec") // получаем также по айди текст с текующей скоростью
genBySec = 0 // значение скорости которое будет изменяться
Добавим ресет чтобы убить всех клеток:
function resetToDefault() {
for (var i = 0; i < Object.keys(cellBoxes).length; i++) { // цикл обращается ко всем клеткам
if (cellBoxes[i].classList.contains("aliveCell")) { // если клетка жива, то убивает ее
cellBoxes[i].classList.add("deathCell")
cellBoxes[i].classList.remove("aliveCell")
}
}
}
Добавим управление скоростью:
function setSpeedInput() {
genBySec = document.getElementById("genSpeedInput").value // Получаем значение с ползунка
genSpeedId.innerHTML = "Поколений в секунду: " + genBySec // изменяем текст текущей скорости в интерфейсе
}
Теперь нужно чтобы скорость изменялась, поэтому редактируем функцию framesUpdate()
function framesUpdate() {
setTimeout(function () {
neighborCheck()
framesUpdate()
}, 1000 / genBySec) // Делим секунду на выбранную скорость.Тоесть делим секунду на выбранное кол-во поколений
}
Добавляем подсчет поколений в интерфейсе
В конце функции neighborCheck (вне циклов) добавляем следующее:
genNumber += 1 // изменяем значение текущего поколения
genNumberId.innerHTML = "Поколение: " + genNumber // заменяем текст в интерфейсе
Мы закончили работать с интерфейсом
Весь код:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Game Of Life</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<div class="mainInterface">
<button onclick="startAnim()" class="interfaceBtn">Start</button>
<button onclick="resetToDefault()" class="interfaceBtn">Reset</button>
<input type="range" min="1" max="255" step="1" value="128" class="interfaceRange" id="genSpeedInput" oninput="setSpeedInput()">
<p class="interfaceTxt" id="genBySec">Поколений в секунду: 128</p>
<p class="interfaceTxt" id="genereationNumber">Поколение: 0</p>
</div>
<div class="mainBox">
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
<div class="cellBox deathCell" onclick="aliveButtons(this)"></div>
</div>
</main>
<script src="script.js"></script>
</body>
</html>
CSS
* {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
body {
margin: 0;
}
.mainInterface {
position: fixed;
background-color: rgba(73, 73, 73, 0.26);
width: 11%;
height: 25%;
border-radius: 10px;
padding: 20px;
}
.interfaceBtn {
width: 90%;
margin: 10px auto;
display: block;
}
.interfaceRange {
margin: 0 auto;
display: block;
}
.mainBox {
border: solid 3px #000000;
display: flex;
flex-wrap: wrap;
width: 45%;
height: 83%;
margin: 4% 26%;
position: fixed;
justify-content: flex-start;
}
.cellBox {
display: block;
width: 5.77%;
height: 5.75%;
border: solid 2px #808080;
background-color: #ffffff;
}
.cellBox:hover {
background-color: #000000;
cursor: pointer;
}
.deathCell {
background-color: #ffffff;
}
.aliveCell {
background-color: #2c2c2c;
}
JS
cellBoxes = document.querySelectorAll(".cellBox")
genNumberId = document.getElementById("genereationNumber")
genNumber = 0
genSpeedId = document.getElementById("genBySec")
genBySec = 0
function aliveButtons(obj) {
if (obj.classList.contains("deathCell")) {
obj.classList.add("aliveCell")
obj.classList.remove("deathCell")
} else if (obj.classList.contains("aliveCell")) {
obj.classList.add("deathCell")
obj.classList.remove("aliveCell")
}
}
function resetToDefault() {
for (var i = 0; i < Object.keys(cellBoxes).length; i++) {
if (cellBoxes[i].classList.contains("aliveCell")) {
cellBoxes[i].classList.add("deathCell")
cellBoxes[i].classList.remove("aliveCell")
}
}
}
function setSpeedInput() {
genBySec = document.getElementById("genSpeedInput").value
genSpeedId.innerHTML = "Поколений в секунду: " + genBySec
}
function neighborCheck() {
for (var i = 0; i < Object.keys(cellBoxes).length; i++) {
cellBoxes[i].alivedNeighbor = 0
if (i - 17 >= 0) {
if (cellBoxes[i - 17].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 16 >= 0) {
if (cellBoxes[i - 16].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 15 >= 0) {
if (cellBoxes[i - 15].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i - 1 >= 0) {
if (cellBoxes[i - 1].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 1 <= 255) {
if (cellBoxes[i + 1].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 15 <= 255) {
if (cellBoxes[i + 15].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 16 <= 255) {
if (cellBoxes[i + 16].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
if (i + 17 <= 255) {
if (cellBoxes[i + 17].classList.contains("aliveCell")) {
cellBoxes[i].alivedNeighbor += 1
}
}
}
for (i = 0; i < Object.keys(cellBoxes).length; i++) {
if (cellBoxes[i].alivedNeighbor === 3) {
if (cellBoxes[i].classList.contains("deathCell")) {
cellBoxes[i].classList.add("aliveCell")
cellBoxes[i].classList.remove("deathCell")
}
} else if (cellBoxes[i].classList.contains("aliveCell")) {
if (cellBoxes[i].alivedNeighbor === 2) {
cellBoxes[i].classList.add("aliveCell")
cellBoxes[i].classList.remove("deathCell")
} else {
cellBoxes[i].classList.add("deathCell")
cellBoxes[i].classList.remove("aliveCell")
}
} else {
if (cellBoxes[i].classList.contains("aliveCell")) {
cellBoxes[i].classList.add("deathCell")
cellBoxes[i].classList.remove("aliveCell")
}
}
}
genNumber += 1
genNumberId.innerHTML = "Поколение: " + genNumber
}
function framesUpdate() {
setTimeout(function () {
neighborCheck()
framesUpdate()
}, 1000 / genBySec)
}
function startAnim() {
framesUpdate()
}
Спасибо за прочтение данной статьи.
Буду очень благодарен если заглянете на мой телеграм канал: https://t.me/blg_projects