În acest articol vă voi arăta cum să construiți un joc de șarpe cu JavaScript.

Un joc de șarpe este un joc simplu în care un șarpe se mișcă în jurul unei cutii încercând să mănânce un măr. Odată ce mănâncă cu succes mărul, lungimea șarpelui crește și mișcarea devine mai rapidă.

Apoi, jocul s-a terminat când șarpele intră în sine sau în oricare dintre cei patru pereți ai cutiei.

Bine, să începem cu HTML și CSS (scheletul jocului nostru).

HTML


<h1>Nokia 3310 snake</h1>
<div class="scoreDisplay"></div>
<div class="grid"></div>
<div class="button">
    <button class="top">top</button>
    <button class="bottom">bottom</button>
    <button class="left">left</button>
    <button class="right">right</button>
</div>
<div class="popup">
    <button class="playAgain">play Again</button>     
</div>

HTML-ul de mai sus este destul de simplu.

  • Avem o clasă div scoreDisplay care va afișa scorurile noastre.
  • Există o divizare de clasă grid care va găzdui jocul (aceasta va fi o grilă de 10 pe 10)
  • Clasa button conține practic un buton pentru utilizatorii care joacă jocul pe un telefon (îl vom automatiza cu tastatura pentru utilizatorul desktop).
  • Si popup clasa va ține butonul de redare.

Acum să adăugăm câteva stiluri cu CSS.

CSS

      body {
        background: rgb(212, 211, 211);
      }
     .grid {
        width: 200px;
        height: 200px;
        border: 1px solid red;
        margin: 0 auto;
        display: flex;
        flex-wrap: wrap;
      }
      .grid div {
        width: 20px;
        height: 20px;
        /*border:1px black solid;
box-sizing:border-box*/
      }
      .snake {
        background: blue;
      }
      .apple {
        background: yellow;
        border-radius: 20px;
      }
      .popup {
        background: rgb(32, 31, 31);
        width: 100px;
        height: 100px;
        position: fixed;
        top: 100px;
        left: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
      }

În CSS, grid care este tabloul de joc are o dimensiune stabilită și un afișaj de flex. Acest lucru permite conținutului (div) al acestei grile să se alinieze într-o manieră orizontală ca și cum ar fi elemente în linie în loc de afișarea blocului normal pe care o posedă.

flex wrap Proprietatea pur și simplu mută divurile pe linia următoare, împiedicându-le să treacă peste dimensiunea stabilită a elementului părinte (grilă)

Vom crea dinamic conținutul plăcii de joc de la JS, dar putem da o lățime și o înălțime aici (cu .grid div). Am inclus comentariile aici pentru a vă ajuta să vedeți efectiv divs-urile, așa că, odată cu trecerea timpului, vom descomenta codul.

snake și Apple cursurile trebuie să ne arate unde este șarpele și bonusul în joc, în timp ce popup class este un div fix care găzduiește replay div.

În acest moment, ar trebui să aveți așa ceva:

Cum sa construiesti un joc de sarpe in JavaScript
Structură cu HTML și CSS

Acum suntem pregătiți pentru JavaScript.

JavaScript

Primul lucru pe care trebuie să-l facem este să ne definim variabilele:

let grid = document.querySelector(".grid") 
let popup = document.querySelector(".popup"); 
let playAgain = document.querySelector(".playAgain"); 
let scoreDisplay = document.querySelector(".scoreDisplay") 
let left = document.querySelector(".left") 
let bottom = document.querySelector(".bottom") 
let right = document.querySelector(".right") 
let up = document.querySelector(".top") 
let width=10; 
let currentIndex = 0 
let appleIndex=0 
let currentSnake=[2,1,0] 
let direction =1 
let score = 0 
let speed = 0.8 
let intervalTime =0 
let interval =0

Lățimea variabilă este exact ceea ce este (lățimea grilei, adică 10). Alte variabile vor avea mai mult sens pe măsură ce continuăm – dar credem sau nu șarpele nostru este de fapt o matrice numită currentSnake.

Acum să începem cu funcțiile:

document.addEventListener("DOMContentLoaded",function(){ 
document.addEventListener("keyup",control) 
createBoard() 
startGame() 
playAgain.addEventListener("click", replay); 
})

Există o eventListener pe obiectul document numit DomContentLoaded iar acest eveniment este declanșat imediat după ce conținutul HTML este încărcat pe ecranul nostru.

Odată ce acest lucru se întâmplă, setăm un evenimentListener pe document pentru a urmări clicurile de pe tastatură (mai multe despre acest lucru mai târziu). După aceea, vrem să creăm gameBoard, începe jocul și fii atent la clicuri pe butonul nostru de reluare.

Funcția createBoard

function createBoard(){ 
popup.style.display = "none"; 
for(let i=0;i<100;i++){
let div =document.createElement("div") 
grid.appendChild(div) 
}
} 

Așa cum am spus mai devreme, aceasta este o grilă de 10 pe 10, ceea ce înseamnă că vom avea nevoie de 100 de divs. Deci, de sus, închidem pop-ul div și trecem la 100 de fiecare dată când creăm un div nou și îl adăugăm la grilă (joc).

Acest lucru va adăuga imediat o parte din stilul pe care l-am creat de sus (div .grid). Puteți decomenta stilurile CSS și veți vedea divs-urile create (decomentați-le înapoi).

Funcția startGame

function startGame(){ 
let squares =document.querySelectorAll(".grid div") 
randomApple(squares) 
//random apple 
direction =1 
scoreDisplay.innerHTML=score 
intervalTime=1000 
currentSnake =[2,1,0] 
currentIndex = 0 
currentSnake.forEach(index=>squares[index].classList.add("snake")) 
interval = setInterval(moveOutcome,intervalTime) 
} 

startGame funcția primește mai întâi toate divurile (deoarece creăm divurile în timpul rulării, nu le putem obține în partea de sus a codului).

Apoi selectăm un loc pentru mărul nostru. Vom face asta mai jos în randomApple funcţie. direction se referă la locul în care se îndreaptă șarpele – 1 pentru dreapta, -1 pentru stânga și așa mai departe.

intervalTime stabilește timpul necesar șarpelui pentru a se deplasa, în timp ce currentSnake definește locul exact în care va fi șarpele (rețineți că șarpele este practic câteva divs având un anumit tip de culoare).

Pentru a afișa șarpele pe ecran, vom face o buclă currentSnake cu forEach. Cu fiecare valoare pe care o obținem, o vom folosi cu pătrate. Amintiți-vă că am accesat divs-urile cu grila querySelectorAll, și le putem accesa apoi ca o matrice, adică folosind numere. În cazul nostru, acestea sunt valorile currentSnake.

După aceasta, adăugăm pur și simplu un setInterval apel (cu funcție mutare Outcome și un timp de intervalTime, pe care l-am setat mai sus) la variabilă interval. Asta pentru a putea apela cu ușurință clearInterval pe acea variabilă.

moveOutcome rulează la fiecare 1000ms (1s) și definește practic ce se întâmplă atunci când mutați șarpele.

Funcția moveOutcome

function moveOutcome (){ 
let squares =document.querySelectorAll(".grid div") 
if(checkForHits(squares)){
alert("you hit something") 
popup.style.display="flex" 
return clearInterval(interval) 
}else{ 
moveSnake(squares) 
}
} 

La fel ca startGame funcția de mai sus, primim mai întâi toate grid divs și apoi verificăm dacă checkForHits funcția returnează adevărat.

Dacă da, înseamnă că am lovit ceva și apoi afișează butonul de redare și șterge intervalul. Dacă se întoarce fals, aceasta înseamnă că nu am lovit nimic și mutăm șarpele cu moveSnake funcţie.

Deci, practic, la fiecare 1 secunde jocul fie se încheie dacă checkForHits este adevărat sau mutăm șarpele cu un pas înainte dacă checkForHits este fals. Voi vorbi despre moveSnake funcționează mai întâi.

Funcția moveSnake

function moveSnake(squares){
let tail = currentSnake.pop()  
squares[tail].classList.remove("snake") 
currentSnake.unshift(currentSnake[0]+direction)  
// movement ends here  
eatApple(squares,tail)  
squares[currentSnake[0]].classList.add("snake")  
} 

moveSnake funcția primește un argument numit squares astfel încât să nu trebuiască să obținem .grid div din nou în această funcție.

Primul lucru pe care trebuie să-l facem este să eliminăm ultimul element al fișierului currentSnake matrice prin pop (aceasta este coada și primul element este întotdeauna capul). Practic, șarpele mișcă un pas înainte lăsând poziția anterioară în care se afla. După aceasta, adăugăm pur și simplu o nouă valoare la începutul matricei cu unShift.

Să presupunem că șarpele nostru tocmai a început să se miște și este orientat spre dreapta (adică direcția = 1). Această direcție va fi adăugată la currentSnakecapul și suma vor fi împinse ca nou snakeHead.

De exemplu, dacă șarpele era în poziție [2,1,0], eliminăm ultimul element lăsându-l în poziție [2,1]. Apoi luăm capul care este 2 și adăugați direcția care este 1 și faceți din această valoare noua valoare [3,2,1] care ne mișcă șarpele cu un pas înainte spre dreapta după o secundă.

Dacă vrem să mutăm șarpele în jos, direcția va fi setată la lățime (care este 10) și adăugată la primul element (adică 12 și împins) [12,2,1].

După aceea, verificăm pur și simplu dacă șarpele a mâncat un măr și afișăm noul cap de șarpe pe DOM.

Funcția checkForHits

function checkForHits(squares){  
if(  
(currentSnake[0] + width >=(width*width) && direction === width) ||
(currentSnake[0] % width ===width -1 && direction ===1) ||   
(currentSnake[0] % width === 0 && direction === -1) ||   
(currentSnake[0] - width <= 0 && direction === -width) ||
squares[currentSnake[0] + direction].classList.contains("snake")   
){ 
return true  
}else{  
return false 
}
}   

checkForHits funcția are o instrucțiune if. În funcție de condiția definită, ar putea fie să revină adevărat (adică să lovim ceva), fie fals.

Prima condiție este dacă currentSnake [0] (capul șarpelui) + lățimea (10) este egală cu aria totală a lățimii (adică lățimea * lățimea = 100) și direcția este egală cu lățimea.

Deci, practic, să presupunem că capul șarpelui se află în poziția 97, care este ultimul strat al rețelei noastre. Dacă ar fi să adăugați 10 la 97 (= 107), aceasta este mai mare decât întreaga rețea, care este 100. Dacă direcția șarpelui este încă îndreptată în jos, atunci șarpele a lovit marginea de jos.

Dacă șarpele era la 97, 97 + 10 = 107, dar jucătorul a reușit să schimbe direcția în, să zicem, 1 (cum ar fi, au apăsat tasta stângă), atunci nu ar fi lovit nimic.

Sau (||) dacă restul când capul șarpelui împărțit la lățimea = lățimea-1 (de exemplu, 9) și direcția este 1. Fiecare ultim div pe partea dreaptă are o valoare de 9, 19, 29 si asa mai departe. Deci, practic va rămâne întotdeauna 9 când împărțiți la 10.

Dacă capul șarpelui nostru este în poziția 39 și direcția este încă 1 (adică șarpele se mișcă în continuare către perete), atunci a lovit ceva (peretele din dreapta).

Orice altă condiție este exact opusul celor două de mai sus. Condiția finală permite ca, dacă capul de șarpe să se îndrepte către un loc care conține deja un șarpe de clasă, aceasta înseamnă pur și simplu că șarpele se mușcă singur.

Deci … dacă oricare dintre condițiile de mai sus este adevărată, șarpele a lovit ceva și Adevărat va fi returnat (altfel fals). Și dacă acesta este cazul, jocul s-a terminat. Dar dacă este fals, mutați șarpele cu un pas înainte moveSnake.

Funcția eatApple

function eatApple(squares,tail){ 
if(squares[currentSnake[0]].classList.contains("apple")){ 
squares[currentSnake[0]].classList.remove("apple") 
squares[tail].classList.add("snake") 
currentSnake.push(tail)
randomApple(squares) 
score++ 
scoreDisplay.textContent = score 
clearInterval(interval) 
intervalTime = intervalTime *speed 
interval = setInterval(moveOutcome,intervalTime) 
}
} 

eatApple funcția se numește din moveSnake funcționează de fiecare dată când șarpele mișcă un pas.

Primește două pătrate de argumente, .grid div și coadă (practic valoarea care a apărut de pe șarpe moveOutcome). Apoi verifică dacă următoarea poziție pe care ne mută șarpele conține un măr.

Dacă da, adaugă pur și simplu acea coadă pe care am revenit la matrice. Acest lucru se datorează faptului că de fiecare dată când șarpele nostru mănâncă un măr, dorim să mărim lungimea șarpelui cu o valoare – și ce modalitate mai bună decât să adăugăm coada care a fost scoasă când s-a mișcat?

Apoi selectăm pur și simplu o nouă poziție pentru mărul nostru cu randomApple (Vezi mai jos). După aceea adăugăm o valoare de unu la scorul nostru și afișați-l utilizatorului, ștergeți timeInterval (astfel încât să putem crește viteza șarpelui, acesta este momentul în care se întâmplă fiecare mișcare) și apoi setăm pur și simplu intervalul înapoi.

Funcția randomApple

function randomApple(squares){ 
do{ 
appleIndex =Math.floor(Math.random() * squares.length) 
}while(squares[appleIndex].classList.contains("snake")) 
squares[appleIndex].classList.add("apple") 
} 

randomApple pur și simplu alege un loc pentru a plasa mărul nostru folosind un face în timp ce buclă. Mai întâi alege o poziție aleatorie cu Math.random() în bucla do și verifică dacă locul pe care l-a ales conține deja o clasă de șarpe.

Acest lucru înseamnă că condiția din instrucțiunea do va continua să ruleze până când va găsi un loc care nu conține un șarpe (continuați să faceți acest lucru cât timp este adevărat) Odată ce găsește un loc, îi oferă pur și simplu acel loc o clasă de măr.

Configurați controalele

Acum trebuie să ne configurăm comenzile. Vom începe cu utilizatorii de tastatură.

function control(e){ 
if (e.keycode===39){
direction = 1 // right 
}else if (e.keycode===38){ 
direction = -width //if we press the up arrow, the snake will go ten divs up
}else if (e.keycode===37){ 
direction = -1 // left, the snake will go left one div
}else if (e.keycode===40){
direction = +width // down the snake head will instantly appear 10 divs below from the current div 
} 
} 

Amintiți-vă de sus am stabilit un eventListener pentru keyup. Această funcție se declanșează imediat după apăsarea mâinii și. lasă o tastă pe o tastatură.

Acum fiecare buton de pe tastatură are o valoare numită keycode (numere) la care avem acces și ne anunță ce număr a fost făcut clic. Practic, vom urmări tastele săgeți cu codurile lor cheie respective. Cu aceasta, de exemplu, modificăm direcția -1, 10 si asa mai departe.

Bine, sper să înțelegi cum putem muta șarpele acum.

În continuare, acest set de butoane este destinat dispozitivelor mobile și practicăm același lucru:

up.addEventListener("click",()=>direction= -width ) 
bottom.addEventListener("click",()=>direction= +width ) 
left.addEventListener("click",()=>direction= -1 ) 
right.addEventListener("click",()=>direction= 1 ) 

Ultimul lucru pe care trebuie să-l facem este să creăm replay div care va apărea când șarpele lovește ceva. Butonul ne ajută să resetăm jocul.

Funcția de redare

 function replay() { 
 grid.innerHTML="" 
 createBoard()   
 startGame()  
 popup.style.display = "none"; 
 }  

De sus, practic ștergem grila (tabla de joc) și rulăm funcțiile anterioare.

Felicitări – ai ajuns până la capăt! Iată rezultatul final:

1611760508 96 Cum sa construiesti un joc de sarpe in JavaScript
Joc final

Sper că ai reușit să codezi și ți-a plăcut.

În acest tutorial, am învățat cum să creăm propriul nostru joc de șarpe cu JavaScript. Alte câteva concepte importante pe care le-am acoperit includ push, pop, setInterval, clearInterval și EventListener.

Puteți verifica jocul final aici: https://codepen.io/Fako29/pen/dyppXZG.

Mulțumesc că ai citit. Urmăriți-mă pe Twitter aici: https://twitter.com/fakoredeDami