You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/hr/6-space-game/2-drawing-to-canvas/README.md

16 KiB

Izgradnja svemirske igre, dio 2: Crtanje heroja i čudovišta na platno

Canvas API jedna je od najmoćnijih značajki web razvoja za stvaranje dinamičnih, interaktivnih grafika direktno u vašem pregledniku. U ovoj lekciji pretvorit ćemo taj prazan HTML <canvas> element u svijet igre ispunjen herojima i čudovištima. Zamislite platno kao svoju digitalnu umjetničku ploču gdje kod postaje vizualan.

Nadovezujemo se na ono što ste naučili u prethodnoj lekciji, a sada ćemo se posvetiti vizualnim aspektima. Naučit ćete kako učitati i prikazati spriteove igre, precizno pozicionirati elemente i stvoriti vizualne temelje za svoju svemirsku igru. Ovo je most između statičnih web stranica i dinamičnih, interaktivnih iskustava.

Na kraju ove lekcije imat ćete kompletan prizor igre s vašim herojskim brodom pravilno pozicioniranim i formacijama neprijatelja spremnim za bitku. Razumjet ćete kako moderne igre renderiraju grafiku u preglednicima i steći vještine za stvaranje vlastitih interaktivnih vizualnih iskustava. Istražimo grafiku na platnu i oživimo vašu svemirsku igru!

Kviz prije predavanja

Kviz prije predavanja

Canvas

Što je točno <canvas> element? To je HTML5 rješenje za stvaranje dinamičnih grafika i animacija u web preglednicima. Za razliku od običnih slika ili videa koji su statični, canvas vam daje kontrolu nad svakim pikselom na ekranu. To ga čini savršenim za igre, vizualizaciju podataka i interaktivnu umjetnost. Zamislite ga kao programabilnu površinu za crtanje gdje JavaScript postaje vaš kist.

Po defaultu, canvas element izgleda kao prazan, transparentan pravokutnik na vašoj stranici. Ali tu leži njegov potencijal! Njegova prava moć dolazi do izražaja kada koristite JavaScript za crtanje oblika, učitavanje slika, stvaranje animacija i omogućavanje interakcije s korisnicima. Slično je tome kako su pioniri računalne grafike u Bell Labsu 1960-ih morali programirati svaki piksel kako bi stvorili prve digitalne animacije.

Pročitajte više o Canvas API-ju na MDN-u.

Evo kako se obično deklarira, kao dio tijela stranice:

<canvas id="myCanvas" width="200" height="100"></canvas>

Što ovaj kod radi:

  • Postavlja atribut id kako biste mogli referencirati ovaj specifični canvas element u JavaScriptu
  • Definira širinu u pikselima za kontrolu horizontalne veličine platna
  • Postavlja visinu u pikselima za određivanje vertikalnih dimenzija platna

Crtanje jednostavne geometrije

Sada kada znate što je canvas element, istražimo kako zapravo crtati na njemu! Canvas koristi koordinatni sustav koji vam može biti poznat iz matematike, ali postoji jedna važna razlika specifična za računalnu grafiku.

Canvas koristi kartezijanski koordinatni sustav s x-osom (horizontalno) i y-osom (vertikalno) za pozicioniranje svega što crtate. Ali evo ključne razlike: za razliku od koordinatnog sustava iz matematike, početna točka (0,0) počinje u gornjem lijevom kutu, pri čemu se vrijednosti x povećavaju kako se pomičete desno, a vrijednosti y povećavaju kako se pomičete dolje. Ovaj pristup datira iz ranih računalnih zaslona gdje su elektronske zrake skenirale od vrha prema dolje, čineći gornji lijevi kut prirodnom početnom točkom.

mreža platna

Slika s MDN

Za crtanje na canvas elementu slijedit ćete isti trostupanjski proces koji čini temelj svih grafika na platnu. Nakon što to učinite nekoliko puta, postaje prirodno:

  1. Dobijte referencu na svoj Canvas element iz DOM-a (kao i za bilo koji drugi HTML element)
  2. Dobijte 2D kontekst za renderiranje on pruža sve metode za crtanje
  3. Počnite crtati! Koristite ugrađene metode konteksta za stvaranje grafike

Evo kako to izgleda u kodu:

// Step 1: Get the canvas element
const canvas = document.getElementById("myCanvas");

// Step 2: Get the 2D rendering context
const ctx = canvas.getContext("2d");

// Step 3: Set fill color and draw a rectangle
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 200, 200); // x, y, width, height

Razložimo ovo korak po korak:

  • Uzimamo naš canvas element koristeći njegov ID i spremamo ga u varijablu
  • Dobivamo 2D kontekst za renderiranje to je naš alat pun metoda za crtanje
  • Kažemo canvasu da želimo ispuniti stvari crvenom bojom koristeći svojstvo fillStyle
  • Crtamo pravokutnik koji počinje u gornjem lijevom kutu (0,0) i širok je 200 piksela i visok 200 piksela

Canvas API uglavnom se fokusira na 2D oblike, ali možete crtati i 3D elemente na web stranici; za to biste mogli koristiti WebGL API.

Možete crtati razne stvari s Canvas API-jem, kao što su:

  • Geometrijski oblici, već smo pokazali kako nacrtati pravokutnik, ali postoji mnogo više što možete nacrtati.
  • Tekst, možete nacrtati tekst s bilo kojim fontom i bojom koju želite.
  • Slike, možete nacrtati sliku na temelju slike kao što je .jpg ili .png, na primjer.

Isprobajte! Znate kako nacrtati pravokutnik, možete li nacrtati krug na stranici? Pogledajte neke zanimljive crteže na Canvasu na CodePenu. Evo posebno impresivnog primjera.

Učitavanje i crtanje slike

Crtanje osnovnih oblika korisno je za početak, ali većina igara treba stvarne slike! Spriteovi, pozadine i teksture ono su što daje igrama vizualnu privlačnost. Učitavanje i prikazivanje slika na platnu funkcionira drugačije od crtanja geometrijskih oblika, ali je jednostavno kad shvatite proces.

Moramo stvoriti objekt Image, učitati našu datoteku slike (to se događa asinkrono, što znači "u pozadini") i zatim je nacrtati na platno kad bude spremna. Ovaj pristup osigurava da se vaše slike pravilno prikazuju bez blokiranja aplikacije dok se učitavaju.

Osnovno učitavanje slike

const img = new Image();
img.src = 'path/to/my/image.png';
img.onload = () => {
  // Image loaded and ready to be used
  console.log('Image loaded successfully!');
};

Što se događa u ovom kodu:

  • Stvaramo potpuno novi objekt slike za pohranu našeg spritea ili teksture
  • Kažemo mu koju datoteku slike treba učitati postavljanjem putanje izvora
  • Slušamo događaj učitavanja kako bismo točno znali kada je slika spremna za upotrebu

Bolji način za učitavanje slika

Evo robusnijeg načina za rukovanje učitavanjem slika koji profesionalni programeri često koriste. Učitavanje slika ćemo omotati u funkciju temeljenu na Promisima ovaj pristup, populariziran kada su JavaScript Promises postali standard u ES6, čini vaš kod organiziranijim i elegantno rješava greške:

function loadAsset(path) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.src = path;
    img.onload = () => {
      resolve(img);
    };
    img.onerror = () => {
      reject(new Error(`Failed to load image: ${path}`));
    };
  });
}

// Modern usage with async/await
async function initializeGame() {
  try {
    const heroImg = await loadAsset('hero.png');
    const monsterImg = await loadAsset('monster.png');
    // Images are now ready to use
  } catch (error) {
    console.error('Failed to load game assets:', error);
  }
}

Što smo ovdje učinili:

  • Omotali svu logiku učitavanja slika u Promise kako bismo njime bolje upravljali
  • Dodali rukovanje greškama koje nam zapravo govori kada nešto pođe po zlu
  • Koristili modernu async/await sintaksu jer je puno čišća za čitanje
  • Uključili try/catch blokove za elegantno rukovanje bilo kakvim problemima pri učitavanju

Kad su vaše slike učitane, njihovo crtanje na platno zapravo je prilično jednostavno:

async function renderGameScreen() {
  try {
    // Load game assets
    const heroImg = await loadAsset('hero.png');
    const monsterImg = await loadAsset('monster.png');

    // Get canvas and context
    const canvas = document.getElementById("myCanvas");
    const ctx = canvas.getContext("2d");

    // Draw images to specific positions
    ctx.drawImage(heroImg, canvas.width / 2, canvas.height / 2);
    ctx.drawImage(monsterImg, 0, 0);
  } catch (error) {
    console.error('Failed to render game screen:', error);
  }
}

Razložimo ovo korak po korak:

  • Učitavamo slike heroja i čudovišta u pozadini koristeći await
  • Uzimamo naš canvas element i dobivamo taj 2D kontekst za renderiranje koji nam treba
  • Pozicioniramo sliku heroja točno u sredinu koristeći malo brze matematike za koordinate
  • Postavljamo sliku čudovišta u gornji lijevi kut kako bismo započeli formaciju neprijatelja
  • Hvatamo sve greške koje se mogu dogoditi tijekom učitavanja ili renderiranja

Vrijeme je da počnete graditi svoju igru

Sada ćemo sve spojiti kako bismo stvorili vizualne temelje vaše svemirske igre. Imate solidno razumijevanje osnova platna i tehnika učitavanja slika, pa će vas ovaj praktični dio voditi kroz izradu kompletnog ekrana igre s pravilno pozicioniranim spriteovima.

Što izgraditi

Izradit ćete web stranicu s Canvas elementom. Trebala bi prikazivati crni ekran 1024*768. Dostavili smo vam dvije slike:

  • Herojski brod

    Herojski brod

  • 5*5 čudovišta

    Brod čudovišta

Preporučeni koraci za početak razvoja

Pronađite početne datoteke koje su stvorene za vas u podmapi your-work. Struktura vašeg projekta trebala bi sadržavati:

your-work/
├── assets/
│   ├── enemyShip.png
│   └── player.png
├── index.html
├── app.js
└── package.json

Što imate na raspolaganju:

  • Spriteovi igre nalaze se u mapi assets/ kako bi sve ostalo organizirano
  • Vaša glavna HTML datoteka postavlja canvas element i priprema sve
  • JavaScript datoteka u kojoj ćete napisati svu magiju za renderiranje igre
  • package.json koji postavlja razvojni server kako biste mogli testirati lokalno

Otvorite ovu mapu u Visual Studio Codeu kako biste započeli razvoj. Trebat će vam lokalno razvojno okruženje s instaliranim Visual Studio Codeom, NPM-om i Node.js-om. Ako nemate postavljen npm na svom računalu, evo kako ga instalirati.

Pokrenite svoj razvojni server tako da odete u mapu your-work:

cd your-work
npm start

Ova naredba radi nekoliko prilično zanimljivih stvari:

  • Pokreće lokalni server na http://localhost:5000 kako biste mogli testirati svoju igru
  • Poslužuje sve vaše datoteke kako bi ih vaš preglednik mogao ispravno učitati
  • Prati promjene u vašim datotekama kako biste mogli glatko razvijati
  • Pruža vam profesionalno razvojno okruženje za testiranje svega

💡 Napomena: Vaš preglednik će isprva prikazivati praznu stranicu to je očekivano! Kako dodajete kod, osvježite preglednik da biste vidjeli promjene. Ovaj iterativni pristup razvoju sličan je načinu na koji je NASA izgradila Apollo računalni sustav za navođenje testirajući svaki komponent prije integracije u veći sustav.

Dodajte kod

Dodajte potrebni kod u your-work/app.js kako biste dovršili sljedeće zadatke:

  1. Nacrtajte platno s crnom pozadinom

    💡 Kako: Pronađite TODO u /app.js i dodajte samo dvije linije. Postavite ctx.fillStyle na crno, zatim koristite ctx.fillRect() počevši od (0,0) s dimenzijama vašeg platna. Jednostavno!

  2. Učitajte teksture igre

    💡 Kako: Koristite await loadAsset() za učitavanje slika igrača i neprijatelja. Spremite ih u varijable kako biste ih kasnije mogli koristiti. Zapamtite neće se prikazati dok ih zapravo ne nacrtate!

  3. Nacrtajte herojski brod u sredini-donjoj poziciji

    💡 Kako: Koristite ctx.drawImage() za pozicioniranje heroja. Za x-koordinatu pokušajte canvas.width / 2 - 45 za centriranje, a za y-koordinatu koristite canvas.height - canvas.height / 4 za postavljanje u donji dio.

  4. Nacrtajte formaciju neprijateljskih brodova 5×5

    💡 Kako: Pronađite funkciju createEnemies i postavite ugniježđenu petlju. Trebat ćete malo matematike za razmak i pozicioniranje, ali ne brinite pokazat ću vam točno kako!

Prvo, postavite konstante za pravilni raspored formacije neprijatelja:

const ENEMY_TOTAL = 5;
const ENEMY_SPACING = 98;
const FORMATION_WIDTH = ENEMY_TOTAL * ENEMY_SPACING;
const START_X = (canvas.width - FORMATION_WIDTH) / 2;
const STOP_X = START_X + FORMATION_WIDTH;

Razložimo što ove konstante rade:

  • Postavljamo 5 neprijatelja po redu i stupcu (lijepa mreža 5×5)
  • Definiramo koliko prostora treba biti između neprijatelja kako ne bi izgledali zbijeno
  • Izračunavamo koliko će široka biti cijela formacija
  • Određujemo gdje početi i završiti kako bi formacija izgledala centrirano

Zatim, stvorite ugniježđene petlje za crtanje formacije neprijatelja:

for (let x = START_X; x < STOP_X; x += ENEMY_SPACING) {
  for (let y = 0; y < 50 * 5; y += 50) {
    ctx.drawImage(enemyImg, x, y);
  }
}

Što ova ugniježđena petlja radi:

  • Vanjska petlja pomjera se s lijeva na desno kroz našu formaciju
  • Unutarnja petlja ide od vrha prema dolje kako bi stvorila uredne redove
  • Crtamo svaki sprite neprijatelja na točno izračunatim x,y koordinatama
  • Sve ostaje ravnomjerno raspoređeno kako bi izgledalo profesionalno i organizirano

Rezultat

Završni rezultat trebao bi izgledati ovako:

Crni ekran s herojem i 5*5 čudovišta

Rješenje

Pokušajte prvo sami riješiti, ali ako zapnete, pogledajte rješenje


Izazov GitHub Copilot Agent 🚀

Koristite Agent način rada za dovršavanje sljedećeg izazova:

Opis: Poboljšajte svoje platno svemirske igre dodavanjem vizualnih efekata i interaktivnih elemenata koristeći tehnike Canvas API-ja koje ste naučili.

Zadatak: Napravite novu datoteku pod nazivom enhanced-canvas.html s platnom koje prikazuje animirane zvijezde u pozadini, pulsirajuću traku zdravlja za herojski brod i neprijateljske brodove koji se polako spuštaju. Uključite JavaScript kod koji crta treperave zvijezde koristeći nasumične pozicije i prozirnost, implementira traku zdravlja koja mijenja boju ovisno o razini zdravlja (zelena > žuta > crvena) i animira neprijateljske brodove da se spuštaju niz ekran različitim brzinama.

Saznajte više o agent načinu rada ovdje.

🚀 Izazov

Naučili ste o crtanju s 2D-fokusiranim Canvas API-jem; pogledajte WebGL API i pokušajte nacrtati 3D objekt.

Kviz nakon predavanja

Kviz nakon predavanja

Pregled i samostalno učenje

Saznajte više o Canvas API-ju čitajući o njemu.

Zadatak

Isprobajte Canvas API


Izjava o odricanju odgovornosti:
Ovaj dokument je preveden pomoću AI usluge za prevođenje Co-op Translator. Iako nastojimo osigurati točnost, imajte na umu da automatski prijevodi mogu sadržavati pogreške ili netočnosti. Izvorni dokument na izvornom jeziku treba smatrati autoritativnim izvorom. Za ključne informacije preporučuje se profesionalni prijevod od strane ljudskog prevoditelja. Ne preuzimamo odgovornost za nesporazume ili pogrešna tumačenja koja mogu proizaći iz korištenja ovog prijevoda.