Рубрики
Без рубрики

Как кодировать «игру жизни» с реагированием в течение часа

Charlee Li, как комировать «Игра жизни» с реагированием в почетном порядке, я смотрел на знаменитое видео, которое создает змеиную игру менее чем за 5 минут (на YouTube). Похоже, это выглядело довольно интересно, чтобы сделать этот тип быстрого кодирования, поэтому я решил сделать один

Автор оригинала: FreeCodeCamp Community Member.

Charlee Li

Недавно я наблюдал за известным видео, которое создает змею игру менее чем за 5 минут (на YouTube ). Он выглядел довольно интересным, чтобы сделать этот тип быстрого кодирования, поэтому я решил сделать один сам.

Когда я начал изучать программирование в детстве, я узнал игру « Игра жизни ». Это отличный пример сотовой автоматизации и насколько простые правила могут привести к сложным узорам. Представьте себе какой-то вид жизни, живущую в мире. На каждом ходу они следуют за несколькими простыми правилами, чтобы решить, жива ли жизнь или мертвая.

Игра Conway’s Life – Wikipedia С момента его публикации игра в жизни в Конгэве привлекла большой интерес, из-за удивительных способов, в которых … en.wikipedia.org.

Поэтому я решил кодировать эту игру. Поскольку он не включает слишком много графики – просто сетка и несколько блоков – я решил, что отреагировал бы хороший выбор, и его можно использовать в качестве быстрого руководства для реагирования. Давайте начнем!

Настройка реагирования

Сначала нам нужно настроить реагирование. Удивительно Create-React-App Инструмент очень удобно для начала нового проекта реагирования:

$ npm install -g create-react-app$ create-react-app react-gameoflife

После менее одной минуты React-GameofLife будь готов. Теперь все, что нам нужно сделать, это начать:

$ cd react-gameoflife$ npm start

Это начнется сервер Dev на http://localhost: 3000 И окно браузера будет открыто на этом адресе.

Выбор дизайна

Последний экран мы хотим сделать так:

Это просто доска с сеткой, а некоторые белые плитки («клетки»), которые могут быть размещены или удалены, нажав сетку. Кнопка «RUN» начнет итерации в данном интервале.

Выглядит довольно просто, а? Давайте подумаем о том, как это сделать в реакции. Прежде всего, Rect Is не Графическая структура, поэтому мы не будем думать об использовании холста. (Вы можете посмотреть на Pixi или Phaser Если вы заинтересованы в использовании Canvas.)

Доска может быть компонентом и может быть отображена одним IV>. Как насчет сетки? Это не осуществимо нарисовать сетки с

s, и поскольку сетка статична, это также ненужно. Действительно, мы с Использование CSS3 LIN Ухо-градиент для сетки.

Что касается клеток, мы можем использовать IV> нарисовать каждую клетку. Мы сделаем это отдельным компонентом. Этот компонент AC C . EP T S X, Y в качестве входных данных, так что доска может указать его положение.

Первый шаг: доска

Давайте сначала создадим доску. Создайте файл под названием Game.js под SRC каталог и введите следующий код:

import React from 'react';import './Game.css';
const CELL_SIZE = 20;const WIDTH = 800;const HEIGHT = 600;
class Game extends React.Component {  render() {    return (      
); }}
export default Game;

Мы также нуждаются в Game.css Файл, чтобы определить стили:

.Board {  position: relative;  margin: 0 auto;  background-color: #000;}

Обновить App.js импортировать наши Game.js и поместите Игра Компонент на экране. Теперь мы можем увидеть совершенно черную игровую доску.

Наш следующий шаг – создать сетку. Сетка может быть создана только с одной строкой Линейный градиент (Добавьте это в game.css ):

background-image:    linear-gradient(#333 1px, transparent 1px),    linear-gradient(90deg, #333 1px, transparent 1px);

На самом деле, нам нужно указать Размер фона стиль, чтобы сделать это работать. Но так как Cell_size Константа определена в Game.js Мы будем указывать размер фона с встроенным стилем напрямую. Изменить Стиль линия в Game.js :

Обновите браузер, и вы увидите хорошую сетку.

Создать клетки

Следующим шагом является разрешение пользователю взаимодействовать с доской для создания ячейки. Мы будем использовать 2D Array Это. доски Чтобы сохранить состояние доски и списком мобильных устройств this.state.cells сохранить положение клеток. Как только государство Совет обновляется, метод this.makeCells () Будут вызвать для генерации списка ячейки из состояния платы.

Добавьте эти методы к Игра класс:

class Game extends React.Component {  constructor() {    super();    this.rows = HEIGHT / CELL_SIZE;    this.cols = WIDTH / CELL_SIZE;    this.board = this.makeEmptyBoard();  }
  state = {    cells: [],  }
  // Create an empty board  makeEmptyBoard() {    let board = [];    for (let y = 0; y < this.rows; y++) {      board[y] = [];      for (let x = 0; x < this.cols; x++) {        board[y][x] = false;      }    }    return board;  }
  // Create cells from this.board  makeCells() {    let cells = [];    for (let y = 0; y < this.rows; y++) {      for (let x = 0; x < this.cols; x++) {        if (this.board[y][x]) {          cells.push({ x, y });        }      }    }    return cells;  }  ...}

Далее мы позвольте пользователю нажать на доску на место или удалить ячейку. В реакции, IV> можно прикрепить Wi a o Обработчик событий NClick, который может получить координату щелчка через событие Click. Однако координата относится к клиентской области (видимая область браузера), поэтому нам нужен дополнительный код для преобразования его в координату, которая относится к доске.

Добавьте обработчик событий в Render () метод. Здесь мы также сохраняем ссылку на элемент платы, чтобы получить местоположение доски позже.

render() {  return (    
{ this.boardRef = n; }}>
);}

А вот еще несколько методов. Здесь getelementoffset () рассчитает позицию элемента платы. Handleclick () Извлеките положение Click, затем преобразуйте его в относительное положение и рассчитайте кольца и строки щелчки клеток. Тогда состояние клеток возвращается.

class Game extends React.Component {  ...  getElementOffset() {    const rect = this.boardRef.getBoundingClientRect();    const doc = document.documentElement;
    return {      x: (rect.left + window.pageXOffset) - doc.clientLeft,      y: (rect.top + window.pageYOffset) - doc.clientTop,    };  }
  handleClick = (event) => {    const elemOffset = this.getElementOffset();    const offsetX = event.clientX - elemOffset.x;    const offsetY = event.clientY - elemOffset.y;        const x = Math.floor(offsetX / CELL_SIZE);    const y = Math.floor(offsetY / CELL_SIZE);
    if (x >= 0 && x <= this.cols && y >= 0 && y <= this.rows) {      this.board[y][x] = !this.board[y][x];    }
    this.setState({ cells: this.makeCells() });  }  ...}

Как последний шаг, мы оказываем клетки this.state.cells до доски:

class Cell extends React.Component {  render() {    const { x, y } = this.props;    return (      
); }}
class Game extends React.Component {  ...  render() {    const { cells } = this.state;    return (      
{ this.boardRef = n; }}> {cells.map(cell => ( ))}
); } ...}

И не забудьте добавить стили для Клетки Компонент (в game.css ):

.Cell {  background: #ccc;  position: absolute;}

Обновите браузер и попробуйте нажать на доску. Клетки могут быть размещены или удалены сейчас!

Запустите игру

Теперь нам нужны помощники, чтобы запустить игру. Сначала давайте добавим некоторые контроллеры.

class Game extends React.Component {  state = {    cells: [],    interval: 100,    isRunning: false,  }  ...
  runGame = () => {    this.setState({ isRunning: true });  }
  stopGame = () => {    this.setState({ isRunning: false });  }
  handleIntervalChange = (event) => {    this.setState({ interval: event.target.value });  }
  render() {    return (      ...        
Update every msec {isRunning ? : }
... ); }}

Этот код добавит один интервал ввода и одну кнопку на нижнюю часть экрана.

Обратите внимание, что щелчок Run не имеет никакого эффекта, потому что мы ничего не написали, чтобы запустить игру. Так что давайте сделаем это сейчас.

В этой игре государство Совета обновляется в каждой итерации. Таким образом, нам нужен метод Runiteration () быть названным каждой итерацией, скажем, 100 мс. Это может быть достигнуто с помощью window.settimeout () Отказ

Когда кнопка запуска нажала, Runiteration () будет называться До того как это заканчивается, это позвонит window.settimeout () организовать другую итерацию после 100msec. Таким образом, Runiteration () будет называться неоднократно. Когда нажата кнопка Стоп, мы отменим устроенный тайм-аут, позвонив window.ClearTimeout () Так что итерации могут быть остановлены.

class Game extends React.Component {  ...  runGame = () => {    this.setState({ isRunning: true });    this.runIteration();  }
  stopGame = () => {    this.setState({ isRunning: false });    if (this.timeoutHandler) {      window.clearTimeout(this.timeoutHandler);      this.timeoutHandler = null;    }  }
  runIteration() {    console.log('running iteration');    let newBoard = this.makeEmptyBoard();
    // TODO: Add logic for each iteration here.
    this.board = newBoard;    this.setState({ cells: this.makeCells() });
    this.timeoutHandler = window.setTimeout(() => {      this.runIteration();    }, this.state.interval);  }  ...}

Перезагрузите браузер и нажмите кнопку «Запустить». Мы увидим журнальное сообщение «Управляющая итерация» в консоли. (Если вы не знаете, как показать консоль, попробуйте нажать Ctrl-Shift-I.)

Теперь нам нужно добавить правила игры в Runiteration () метод. По словам Википедии, игра в жизни имеет четыре правила:

Мы можем добавить метод Callateleighbors () вычислить количество соседей данного (х, у) Отказ (Исходный код Calcualteightighbors () будет опущен в этом посте, но вы можете найти его здесь .) Затем мы можем реализовать правила простым способом:

for (let y = 0; y < this.rows; y++) {  for (let x = 0; x < this.cols; x++) {    let neighbors = this.calculateNeighbors(this.board, x, y);    if (this.board[y][x]) {      if (neighbors === 2 || neighbors === 3) {        newBoard[y][x] = true;      } else {        newBoard[y][x] = false;      }    } else {      if (!this.board[y][x] && neighbors === 3) {        newBoard[y][x] = true;      }    }  }}

Перезагрузить браузер, поместите несколько исходных ячеек, затем нажмите кнопку «Запустить». Вы можете увидеть некоторые удивительные анимации!

Заключение

Чтобы сделать игру более развлеченным, я также добавил случайную кнопку и четкую кнопку, чтобы помочь с размещением ячеек. Полный исходный код можно найти на моем Github Отказ

Спасибо за ваше чтение! Если вы найдете этот пост интересно, пожалуйста, поделитесь этим с большим количеством людей, рекомендуем это.