Это пошаговое руководство по простой игре на развитие памяти с использованием ванильного JavaScript, HTML и CSS. Я сделал с фрагментами кода и своими пояснениями. Я надеюсь, что это поможет начинающим программистам вроде меня, а также послужит обзором моего собственного обучения.

Вы также можете найти код моего проекта здесь: https://github.com/sydteo/memoryGame

Настройка проекта

  1. В выбранном вами редакторе создайте html-файл и назовите его index.html. Вы можете назвать файл как угодно, но это просто соглашение об именах файлов html. Тем не менее, вы должны включить расширение .html, так как оно сообщает нашему редактору тип файла. Вот почему вы всегда замечаете, что все файлы заканчиваются на .js, .html или .css.
  2. Я решил использовать Visual Studio Code, так как это один из самых популярных редакторов.
  3. Я создал папку с именем src, которая будет включать в себя папку с изображениями, файл styles.css и файл app.js. Это также необходимо для аккуратного именования и организации наших файлов и папок.

HTML

  1. HTML — это «основной» файл, который связывает файлы CSS и JavaScript. Это и должен быть первый файл, который читает редактор.

Совет. Введите !, а затем tab в HTML-файле, чтобы сгенерировать HTML-шаблон по умолчанию

2. Свяжите файл CSS.

Примечание. Связывание выполняется в заголовке html-файлов

<link rel="stylesheet" href="src/styles.css"/>

3. Свяжите файл JavaScript.

<script src="src/app.js"></script>

4. Тело — это место, где расположены все видимые компоненты. У меня есть 2 дочерних компонента — счет и сетка в родительском компоненте — теле.

<body>    
   <h1 class="score">Score: <span id="result"></span></h1>    
   <div class="grid"></div>    
   <button class="restart">Restart</button>
</body>

CSS

Часть CSS отвечает за стиль и форматирование вашей игры. Это зависит от вашего воображения, так что пробуйте и ошибайтесь на свой вкус. Вот как я украсил свой.

  1. Flexbox — это широко используемый способ стилизации вашей страницы. Я настоятельно рекомендую эту страницу, чтобы лучше понять различные способы использования flexbox. Как уже упоминалось, body является родителем сетки и оценки, и я хочу, чтобы мой класс оценки находился над сетками, поэтому я использую flex-direction: column. Зачем нам флексбокс? По умолчанию все ваши элементы и классы будут складываться вместе. Итак, мы используем display: flex для инициализации flexbox, чтобы мы могли расположить наши сетки рядом.
body {  
   display: flex;  
   flex-direction: column;  
   align-items: center;  
   background-color: black;
}

2. Чтобы мои сетки для игры на память обвивались друг вокруг друга, как змея, мы используем flex-wrap: wrap.

.grid {  
   display: flex;  
   flex-wrap: wrap;  
   width: 400px;  
   height: 300px;
}

3. Я оформил свою партитуру просто, оставив немного места вверху с помощью margin-top.

.score {  
   margin-top: 150px;  
   color: white;  
   font-family: "Gill Sans", "Gill Sans MT", Calibri;
}

4. Чтобы оформить кнопку перезапуска, я добавил вокруг нее отступы и настроил шрифт по своему вкусу.

.restart {  
   margin-top: 30px;  
   padding: 10px;  
   font-family: "Gill Sans", "Gill Sans MT", Calibri;
}

5. Чтобы добавить некоторые детали к кнопкам, мы можем использовать курсор: указатель. Это помогает изменить курсор, когда он зависает вокруг кнопки перезапуска.

.restart:hover {  
   cursor: pointer;
}

JavaScript

  1. По соглашению мы называем файл JavaScript app.js. Весь ваш код JavaScript должен находиться внутри функции addEventListener(‘DOMContentLoaded’, ()). Это говорит коду запустить основной файл index.html перед чтением файла app.js.
document.addEventListener('DOMContentLoaded', ()  => {
     ...
     ...
}

2. Создайте папку с именем images в папке src. Здесь вы загружаете все свои активы. Активы — это просто еще одно причудливое название для изображений и значков. Они могут быть в формате png, jpg или svg. Вы можете загрузить активы из моего репозитория Github.

3. Мы создаем массив объектов и сохраняем их как константу, поскольку они фиксированы и неизменяемы. Константы не могут быть изменены после их объявления. Поскольку это игра на память, в которой игроки должны сопоставить две одинаковые карты, каждого предмета должно быть по 2. Например, 2 бургера, 2 картофеля фри, 2 хот-дога и так далее.

const cardArray = [        
   {name: 'burger',
    img: 'src/images/burger.png'},
   {name: 'fries',
    img: 'src/images/fries.png'},
   {name: 'hotdog',
    img: 'src/images/hotdog.png'},
   ...
]

4. Произвольно отсортируйте наш массив, используя этот трюк.

cardArray.sort(() => 0.5 - Math.random())

5. Эта игра требует только 3 основные функции. Конечно, вы можете добавить больше сложности по своему желанию, например, уровень сложности! Во-первых, давайте напишем функцию для создания нашей доски 4x3 и назовем ее. Рекомендуется использовать верблюжий регистр для именования функций, здесь мы называем нашу функцию createBoard.

Мы используем метод .createElement для создания элемента для каждой сетки и сохранения их в константе, называемой картой.

Мы используем .setAttribute, чтобы установить для каждой карты пустую карту. Каждая карта изначально имеет пустую версию. Мы также используем .setAttribute, чтобы присвоить каждой карте уникальный идентификатор, что означает, что первая карта будет иметь идентификатор 0, а последняя карта будет иметь идентификатор 11.

После создания элемента используйте метод element.appendChild(), чтобы вставить карточки в документ/сетку.

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

function createBoard() {        
   for (let i = 0; i < cardArray.length; i++){            
      const card = document.createElement('img') 
      card.setAttribute('src', 'src/images/blank.png')
      card.setAttribute('data-id', i) 
      card.addEventListener('click', flipCard)
      grid.appendChild(card)}
}

6. Создайте пустой массив с именемcardsChosen для хранения карточек, на которые мы нажали.

let cardsChosen = []

7. Имена функций должны быть простыми. flipCard(), по сути, помогает нам переворачивать карту всякий раз, когда игрок нажимает на нее.

Всякий раз, когда в массивеcardsChosen есть 2 карты, мы хотим сравнить их и сбросить массив. Это делается с помощью setTimeout(checkForMatch, 500)

function flipCard() {        
   let cardId = this.getAttribute('data-id')
   cardsChosen.push(cardArray[cardId].name)
   cardsChosenId.push(cardId)
   // flip the card back to a blank card after clicking
   this.setAttribute('src', cardArray[cardId].img)
   if(cardsChosen.length === 2) {
      setTimeout(checkForMatch, 500)
    }
}

7. Функция checkForMatch() выглядит довольно интимно, но на самом деле она проста.

function checkForMatch() {
   const cards = document.querySelectorAll('img')
   const optionOneId = cardsChosenId[0]
   const optionTwoId = cardsChosenId[1]
   if(optionOneId == optionTwoId { 
      cards[optionOneId].setAttribute('src', 'src/images/blank.png')
      cards[optionTwoId].setAttribute('src', 'src/images/blank.png')
      alert('You have clicked the same image!')
   }else if (cardsChosen[0] === cardsChosen[1]) {
      alert('You found a match!')
      cards[optionOneId].setAttribute('src', 'src/images/white.png')
      cards[optionTwoId].setAttribute('src', 'src/images/white.png')
      cards[optionOneId].removeEventListener('click', flipCard)
      cards[optionTwoId].removeEventListener('click', flipCard)
      cardsWon.push(cardsChosen)        
     } else {
      cards[optionOneId].setAttribute('src', 'src/images/blank.png')
      cards[optionTwoId].setAttribute('src', 'src/images/blank.png')
      alert('Sorry, try again!')        
      }
   cardsChosen = []        
   cardsChosenId = []
   resultDisplay.textContent = cardsWon.length
   if  (cardsWon.length === cardArray.length/2) {
      resultDisplay.textContent = 'Congratulations!'
   }
}

8. Функция перезагрузки, которая перезагружает страницу и, следовательно, перезапускает игру при нажатии кнопки перезагрузки.

document.querySelector('.restart').addEventListener('click',
   function(){
      window.location.reload();
      return false;
   }
);

Вывод

Это было частью проекта в рамках 12-часового БЕСПЛАТНОГО буткемпа Ани Кубоу. Мне было очень весело, и я узнал много нового об основах веб-разработки и разработки игр. Это послужит основой для моих будущих проектов. А пока следите за обновлениями!