Учебное пособие по JavaScript: создание тетриса с помощью современного JavaScript

создание тетриса с помощью современного JavaScript Изучение

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

Создание проектов помогает понять, как и зачем использовать фундаментальные концепции в различных приложениях, особенно для интуитивно понятных языков, таких как JavaScript. Это также помогает составить ваше резюме, потому что вы можете показать рекрутерам коллекцию потрясающих проектов, чтобы продемонстрировать свой драйв и навыки разработчика.

Сегодня мы поможем вам начать проект по разработке игр на JavaScript для создания тетриса. К концу статьи у вас будут все основные элементы, необходимые для самостоятельного строительства.

Что такое тетрис?

Тетрис — классическая аркада, созданная в 1984 году Алексеем Пажитновым. Игра требует, чтобы игроки вращали и перемещали падающие части тетриса. Игроки очищают линии, заполняя горизонтальные ряды блоков без пустых ячеек. Если фигуры достигают вершины, игра окончена.

Тетрис — популярный проект, который позволяет начинающим разработчикам игр практиковать свои навыки в простой среде. Например, вы получите практическую практику с основными концепциями игрового дизайна, такими как дизайн цикла геймплея, и реализуете общие игровые механизмы, такие как пользовательское управление, отслеживание результатов и обнаружение столкновений. В отличие от более сложных игр, поведение и визуальные эффекты в Тетрисе очень просты. Это позволяет вам практиковаться в применении основ JavaScript для разработки игр, а не разбираться в анимации или сложных блок-схемах поведения игрока.

В этом примере мы начнем с использования простейших инструментов и в конце будем усложнять.

Чтобы сделать тетрис, вам нужно знать:

  • HTML / CSS стили
  • Классы, переменные и область видимости JavaScript
  • Стрелочные функции
  • Литералы шаблона
  • Спред против отдыха
  • Деструктуризация
Читайте также:  10 лучших плагинов WordPress, которые стоит рассмотреть в 2021 году

Стиль игры

Во-первых, давайте настроим основные элементы пользовательского интерфейса: игровую область, кнопку запуска и индикаторы для отслеживания очков, линий и уровня. Мы будем использовать Flexbox и CSS Grid, чтобы правильно расположить элементы.

index.html

<!— index.html —>
<div class=»grid»>
  <canvas id=»board» class=»game-board»></canvas>
  <div class=»right-column»>
    <div>
      <h1>TETRIS</h1>
      <p>Score: <span id=»score»>0</span></p>
      <p>Lines: <span id=»lines»>0</span></p>
      <p>Level: <span id=»level»>0</span></p>
      <canvas id=»next» class=»next»></canvas>
    </div>
    <button onclick=»play()» class=»play-button»>Play</button>
  </div>
</div>

styles.css

// styles.css
.grid {
  display: grid;
  grid-template-columns: 320px 200px;
}
.right-column {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.game-board {
  border: solid 2px;
}
.play-button {
  background-color: #4caf50;
  font-size: 16px;
  padding: 15px 30px;
  cursor: pointer;
}

Фундаментальной частью игр 80-х был хорошо узнаваемый растровый шрифт. Press start 2P — бесплатный шрифт от Google, который мы можем использовать для имитации ощущений.

Чтобы добавить шрифт, нам нужно сделать ссылку на него в разделе нашего HTML-документа и установить для него желаемый шрифт в таблице стилей CSS.

<!--index.html-->
<link
href="https://fonts.googleapis.com/css?family=Press+Start+2P"
rel="stylesheet"
/>

 

// styles.css
* {
  font-family: 'Press Start 2P', cursive;
}

Наконец, запрограммируйте инфраструктуру игрового поля с помощью JavaScript. Вам нужно будет добавить <script>элементы в конец нашего HTML-документа, чтобы импортировать наш JavaScript.

Нижняя часть вашего HTML-документа должна выглядеть так:

    <script type="text/javascript" src="constants.js"></script>
    <script type="text/javascript" src="board.js"></script>
    <script type="text/javascript" src="piece.js"></script>
    <script type="text/javascript" src="main.js"></script>
  </body>
</html>

constants.js будет содержать код для нашей статической игровой доски. Эти значения никогда не изменятся независимо от действий игрока. Игровая доска будет состоять из 10 столбцов и 20 строк с размером блока 30.

//constants.js
const COLS = 10;
const ROWS = 20;
const BLOCK_SIZE = 30;

Затем в main.jsфайл мы включим некоторый код для управления документом object, который предоставляет программируемый интерфейс для документа HTML. Этот тип документа называется объектной моделью документа (DOM).

Мы можем использовать DOM для вызова, getElementByIDчтобы мы могли нацеливаться на определенные элементы и автоматически масштабировать нашу игру в соответствии с размером окна браузера пользователя. Здесь используется canvasновый элемент HTML5, который позволяет нам с легкостью создавать и использовать 2D-формы.

main.js Файл должен выглядеть следующим образом :

//main.js
const canvas = document.getElementById('board');
const ctx = canvas.getContext('2d');

// Calculate size of canvas from constants.
ctx.canvas.width = COLS * BLOCK_SIZE;
ctx.canvas.height = ROWS * BLOCK_SIZE;

// Scale blocks
ctx.scale(BLOCK_SIZE, BLOCK_SIZE);

К концу у вас будут следующие файлы:

index.html

<!—index.html—>
<html>
<head>
  <link
href=»https://fonts.googleapis.com/css?family=Press+Start+2P»
rel=»stylesheet»
/>
</head>
<body>
  <div class=»grid»>
    <canvas id=»board» class=»game-board»></canvas>
    <div class=»right-column»>
      <div>
        <h1>TETRIS</h1>
        <p>Score: <span id=»score»>0</span></p>
        <p>Lines: <span id=»lines»>0</span></p>
        <p>Level: <span id=»level»>0</span></p>
        <canvas id=»next» class=»next»></canvas>
      </div>
      <button onclick=»play()» class=»play-button»>Play</button>
    </div>
  </div>
</body>

main.js

//main.js
const canvas = document.getElementById(‘board’);
const ctx = canvas.getContext(‘2d’);
// Calculate size of canvas from constants.
ctx.canvas.width = COLS * BLOCK_SIZE;
ctx.canvas.height = ROWS * BLOCK_SIZE;
// Scale blocks
ctx.scale(BLOCK_SIZE, BLOCK_SIZE);

constants.js

//constants.js
const COLS = 10;
const ROWS = 20;
const BLOCK_SIZE = 30;

styles.css

//styles.css
* {
  font-family: ‘Press Start 2P’, cursive;
}
.grid {
  display: grid;
  grid-template-columns: 320px 200px;
}
.right-column {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.game-board {
  border: solid 2px;
}
.play-button {
  background-color: #4caf50;
  font-size: 16px;
  padding: 15px 30px;
  cursor: pointer;
}

Завершенный интерфейс

Designing the board

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

Доска и фигуры — хорошие кандидаты для класса. Мы можем создать новый экземпляр Boardпри запуске новой игры и новый экземпляр Pieceкаждый раз, когда в игру входит новая часть.

Для Boardкласса создадим новый board.jsфайл. Мы хотим, чтобы доска ссылалась на холст каждый раз при запуске игры, поэтому мы включим его ctxв Boardконструктор. Мы также добавим thisключевое слово, чтобы позволить нам устанавливать и получать доступ к свойствам внутри ctx.

//board.js
class Board { 
  constructor(ctx) {
    this.ctx = ctx;    
  } 
}

Доски тетриса состоят из множества отдельных ячеек, которые либо пусты, либо заняты. Мы представим пустые ячейки с помощью 0и занятые ячейки с целыми числами 1-7для представления цветов.

Чтобы представить строки и столбцы доски, мы будем использовать 2D-массив (матрицу). У нас будут массивы целых чисел для представления строки и массив строк для представления всей доски.

Поскольку все игры начинаются с пустой доски, нам понадобится метод, возвращающий пустую доску. Мы можем использовать встроенный fill()метод массива, чтобы заполнить все элементы каждой строки 0. Конструктор вызовет этот метод, поэтому все игры начнутся пустыми.

board.js Теперь наш файл будет выглядеть так:

//board.js
class Board { 
  constructor(ctx) {
    this.ctx = ctx;
    this.grid = this.getEmptyBoard();
  }
 
  getEmptyBoard() {
    return Array.from(
      {length: ROWS}, () => Array(COLS).fill(0)
    );
  }
}

Наконец, мы вернемся к, main.jsчтобы добавить эту новую игровую функциональность к кнопке воспроизведения.

function play() {
  board = new Board(ctx);
  console.table(board.grid);
}

Теперь наша игровая доска настроена! Вы можете использовать, console.table()чтобы увидеть матрицу, которая управляет доской.

Матрица платы отображается через консоль

Матрица платы отображается через консоль

Создание холста

Теперь убедимся, что наш canvasэлемент готов к использованию. Холст представляет собой чистый холст для нашей игры.

Мы также можем добавить контекст 2D-рисования поверх холста для рисования фигур, текста, изображений и других объектов. Он работает аналогично программам, подобным MS Paint, в том, что вы можете выбрать тип кисти и цвет, а затем рисовать с помощью кода.

Во-первых, мы хотим убедиться, что холст подходящего размера. По умолчанию это 300×150 пикселей, но мы хотим масштабировать его с помощью кода, который мы добавили выше.

Для этого мы добавляем canvasэлемент в наш index.html:

<canvas id="canvas"></canvas>

Затем добавьте ссылку на <canvas>элемент HTML- элемента в DOM (объектной модели документа) с помощью этого getElementByIdметода.

let canvas = document.getElementById('canvas');

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

Мы можем использовать этот HTMLCanvasElement.getContext()метод для получения контекста холста, в котором мы визуализируем графику. Этому методу нужен аргумент, поэтому мы передадим ‘2d’ему контекст 2D-рендеринга.

let ctx = canvas.getContext('2d');

Прежде чем мы сможем рисовать, нам нужно выбрать цвет с помощью этого fillStyle()метода.

ctx.fillStyle = 'red';

Затем мы можем использовать fillRect()метод из контекстного API, чтобы нарисовать простой прямоугольник, залитый выбранным нами красным цветом. fillRect()принимает 4 аргумента: координаты x и y, где должна начинаться форма, и ширина / высота прямоугольника.

ctx.fillRect(x, y, width, height);

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

Анимации

Теперь, когда у нас есть инструменты для рисования нашей графики, мы можем перемещать их.

Canvas использует немедленную визуализацию : нарисованные фигуры немедленно отображаются на экране, но не сохраняются как объекты формы. Вместо этого холст распознает фигуру только как заполненные пиксели, что означает, что мы не можем перемещать фигуру за одно целое.

Чтобы показать движущуюся фигуру, мы должны удалить старую фигуру с помощью clearRect() и перерисовать ее в новом положении с помощью fillRect(). Анимация холста по сути похожа на покадровую анимацию, потому что она немного перемещается в каждом кадре.

Взгляните на этот пример:

const {width, height} = this.ctx.canvas;
ctx.fillStyle = 'blue';
ctx.fillRect(0, 0, 10, 10);
ctx.clearRect(0, 0, width, height);
ctx.fillRect(1, 1, 10, 10);

Здесь мы выбираем синий в качестве цвета, затем заливаем прямоугольник в точке 0,0. Затем мы очищаем весь холст, используя clearRect()и передавая ширину и высоту всего холста. Наконец, мы рисуем новый прямоугольник того же размера и цвета в точке 1,1.

С точки зрения пользователя, прямоугольник перемещался вниз и вправо на экране.

С точки зрения пользователя, прямоугольник перемещался вниз и вправо на экране

С точки зрения пользователя, прямоугольник перемещался вниз

Теперь, когда у вас настроены холст и инструменты для рисования, у вас есть все инструменты, необходимые для программирования игрового процесса, и коллекция игровых элементов!

Следующие шаги для вашей игры

Это отличное начало для вашего следующего портфолио-проекта. Теперь, когда вы заложили основу игры, ваш следующий шаг — создать объекты, которые рисуют каждый уникальный элемент игры Тетрис своим цветом.

Каждый тип элемента будет представлен матрицей 3×3, где элемент представляет собой заполненные ячейки, а окружающее пустое пространство помогает вращаться вокруг центральной ячейки.

[2, 0, 0],  
[2, 2, 2],  
[0, 0, 0];

Лучше всего это сделать с помощью Pieceкласса.

Вам также придется добавить поддержку клавиатуры, чтобы пользователь мог управлять элементами. Лучший способ сделать это — использовать поддержку событий клавиатуры, встроенную в современные браузеры. Вы можете установить программу для прослушивания для событий клавиатуры, как keydown, keyupи так далее на уровне документа с использованием addEventListener()методы.

После этих шагов вы перейдете к добавлению более продвинутых функций, таких как:

  • Добавить обнаружение столкновений и рандомизатор частей
  • Добавить очистку строки, если строка заполнена
  • Отслеживайте счет, уровень и прошлые рекорды
  • Увеличьте скорость отклика с помощью асинхронного JavaScript
Оцените статью
bestprogrammer.ru
Добавить комментарий