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/sr/6-space-game/2-drawing-to-canvas
softchris bde9da6dad
🌐 Update translations via Co-op Translator
1 month ago
..
README.md 🌐 Update translations via Co-op Translator 1 month ago
assignment.md 🌐 Update translations via Co-op Translator 1 month ago

README.md

Направите свемирску игру, део 2: Цртање хероја и чудовишта на платну

Canvas API је једна од најмоћнијих функција веб развоја за креирање динамичке, интерактивне графике директно у вашем претраживачу. У овој лекцији, трансформисаћемо празан HTML <canvas> елемент у свет игре испуњен херојима и чудовиштима. Замислите платно као вашу дигиталну таблу за цртање где код постаје визуелан.

Надовезујемо се на оно што сте научили у претходној лекцији, а сада ћемо се упустити у визуелне аспекте. Научићете како да учитате и прикажете спрајтове игре, прецизно позиционирате елементе и креирате визуелну основу за вашу свемирску игру. Ово премошћује јаз између статичних веб страница и динамичких, интерактивних искустава.

На крају ове лекције, имаћете комплетну сцену игре са вашим херојским бродом који је правилно позициониран и формацијама непријатеља спремним за битку. Разумећете како модерне игре рендерују графику у претраживачима и стекнућете вештине за креирање сопствених интерактивних визуелних искустава. Хајде да истражимо графику на платну и оживимо вашу свемирску игру!

Квиз пре предавања

Квиз пре предавања

Платно

Шта је тачно <canvas> елемент? То је HTML5 решење за креирање динамичке графике и анимација у веб претраживачима. За разлику од обичних слика или видео записа који су статични, платно вам даје контролу над пикселима за све што се појављује на екрану. Ово га чини савршеним за игре, визуализацију података и интерактивну уметност. Замислите га као програмску површину за цртање где JavaScript постаје ваша четкица.

Подразумевано, елемент платна изгледа као празан, транспарентан правоугаоник на вашој страници. Али ту лежи његов потенцијал! Његова права моћ се појављује када користите JavaScript за цртање облика, учитавање слика, креирање анимација и омогућавање интеракције са корисником. Слично је начину на који су пионири рачунарске графике у Bell Labs-у 1960-их морали да програмирају сваки пиксел како би креирали прве дигиталне анимације.

Прочитајте више о Canvas API-ју на MDN.

Ево како се обично декларише, као део тела странице:

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

Шта овај код ради:

  • Поставља id атрибут како бисте могли да се позовете на овај специфичан елемент платна у JavaScript-у
  • Дефинише ширину у пикселима за контролу хоризонталне величине платна
  • Утврђује висину у пикселима за одређивање вертикалних димензија платна

Цртање једноставне геометрије

Сада када знате шта је елемент платна, хајде да истражимо како заправо цртати на њему! Платно користи координатни систем који вам може бити познат из математике, али постоји један важан заокрет специфичан за рачунарску графику.

Платно користи Картецијански координатни систем са x-осом (хоризонталном) и y-осом (вертикалном) за позиционирање свега што цртате. Али ево кључне разлике: за разлику од координатног система из математике, тачка порекла (0,0) почиње у горњем левом углу, са x-вредностима које расту како се крећете удесно и y-вредностима које расту како се крећете надоле. Овај приступ потиче из раних рачунарских дисплеја где су електронски зраци скенирали одозго надоле, чинећи горњи леви угао природном почетном тачком.

мрежа платна

Слика са MDN

Да бисте цртали на елементу платна, следићете исти тростепени процес који чини основу свих графика на платну. Када ово урадите неколико пута, постаје природно:

  1. Добијте референцу на ваш Canvas елемент из DOM-а (као и било који други HTML елемент)
  2. Добијте 2D контекст рендеровања ово пружа све методе за цртање
  3. Почните да цртате! Користите уграђене методе контекста за креирање ваше графике

Ево како то изгледа у коду:

// 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

Хајде да ово разложимо корак по корак:

  • Ми узимамо наш елемент платна користећи његов ID и чувамо га у променљивој
  • Ми добијамо 2D контекст рендеровања ово је наш алат пун метода за цртање
  • Ми кажемо платну да желимо да попунимо ствари црвеном бојом користећи fillStyle својство
  • Ми цртамо правоугаоник који почиње у горњем левом углу (0,0) и који је широк и висок 200 пиксела

Canvas API се углавном фокусира на 2D облике, али можете такође цртати 3D елементе на веб страници; за то можете користити WebGL API.

Можете цртати разне ствари са Canvas API-јем као што су:

  • Геометријски облици, већ смо показали како да нацртате правоугаоник, али постоји много више што можете да нацртате.
  • Текст, можете нацртати текст са било којим фонтом и бојом коју желите.
  • Слике, можете нацртати слику на основу сликовног ресурса као што је .jpg или .png, на пример.

Пробајте! Знате како да нацртате правоугаоник, можете ли нацртати круг на страници? Погледајте неке занимљиве цртеже на платну на CodePen. Ево посебно импресивног примера.

Учитавање и цртање сликовног ресурса

Цртање основних облика је корисно за почетак, али већини игара су потребне стварне слике! Спрајтови, позадине и текстуре су оно што даје играма њихову визуелну привлачност. Учитавање и приказивање слика на платну функционише другачије од цртања геометријских облика, али је једноставно када разумете процес.

Потребно је да креирамо Image објекат, учитамо нашу сликовну датотеку (ово се дешава асинхроно, што значи "у позадини"), а затим да је нацртамо на платну када буде спремна. Овај приступ осигурава да се ваше слике правилно приказују без блокирања апликације током учитавања.

Основно учитавање слике

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!');
};

Шта се дешава у овом коду:

  • Ми креирамо потпуно нови Image објекат за чување нашег спрајта или текстуре
  • Ми кажемо којој сликовној датотеци да приступи постављањем путање извора
  • Ми слушамо догађај учитавања како бисмо знали тачно када је слика спремна за употребу

Бољи начин за учитавање слика

Ево робуснијег начина за руковање учитавањем слика који професионални програмери често користе. Увешћемо логику учитавања слика у функцију засновану на Promise-у овај приступ, који је постао популаран када су JavaScript Promises постали стандард у ES6, чини ваш код организованијим и елегантно решава грешке:

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);
  }
}

Шта смо овде урадили:

  • Увели сву ту логику учитавања слика у Promise како бисмо боље управљали њом
  • Додали руковање грешкама које нам заправо говори када нешто крене наопако
  • Користили савремени async/await синтакс јер је много читљивији
  • Укључили try/catch блокове за елегантно руковање било којим проблемима током учитавања

Када се ваше слике учитају, њихово цртање на платну је заправо прилично једноставно:

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);
  }
}

Хајде да ово разложимо корак по корак:

  • Ми учитавамо и слике хероја и чудовишта у позадини користећи await
  • Ми узимамо наш елемент платна и добијамо тај 2D контекст рендеровања који нам је потребан
  • Ми позиционирамо слику хероја тачно у центар користећи брзу математику координата
  • Ми постављамо слику чудовишта у горњи леви угао да започнемо формацију непријатеља
  • Ми хватамо било какве грешке које се могу догодити током учитавања или рендеровања

Сада је време да почнете са изградњом ваше игре

Сада ћемо све спојити како бисмо креирали визуелну основу ваше свемирске игре. Имате солидно разумевање основа платна и техника учитавања слика, па ће вас овај практични део водити кроз изградњу комплетног екрана игре са правилно позиционираним спрајтовима.

Шта да направите

Направићете веб страницу са Canvas елементом. Требало би да приказује црни екран 1024*768. Обезбедили смо вам две слике:

  • Херојски брод

    Херојски брод

  • 5*5 чудовишта

    Брод чудовишта

Препоручени кораци за почетак развоја

Пронађите почетне датотеке које су креиране за вас у подфолдеру your-work. Структура вашег пројекта треба да садржи:

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

Шта имате на располагању:

  • Спрајтови игре се налазе у фолдеру assets/ како би све било организовано
  • Ваш главни HTML фајл поставља Canvas елемент и припрема све
  • JavaScript фајл где ћете написати сву магију рендеровања игре
  • package.json који поставља развојни сервер како бисте могли да тестирате локално

Отворите овај фолдер у Visual Studio Code-у да започнете развој. Биће вам потребно локално развојно окружење са Visual Studio Code-ом, NPM-ом и Node.js-ом инсталираним. Ако немате подешен npm на вашем рачунару, овде је објашњено како да га инсталирате.

Покрените ваш развојни сервер тако што ћете отићи у фолдер your-work:

cd your-work
npm start

Ова команда ради неке прилично занимљиве ствари:

  • Покреће локални сервер на http://localhost:5000 како бисте тестирали вашу игру
  • Сервира све ваше фајлове правилно како би их ваш претраживач учитао
  • Прати промене у вашим фајловима како бисте могли несметано да развијате
  • Пружа вам професионално развојно окружење за тестирање свега

💡 Напомена: Ваш претраживач ће у почетку приказати празну страницу то је очекивано! Како будете додавали код, освежите ваш претраживач да видите промене. Овај приступ итеративног развоја је сличан начину на који је НАСА изградила компјутер за навигацију Аполо мисије тестирајући сваки компонент пре интеграције у већи систем.

Додајте код

Додајте потребан код у your-work/app.js да бисте завршили следеће задатке:

  1. Нацртајте платно са црном позадином

    💡 Ево како: Пронађите TODO у /app.js и додајте само две линије. Поставите ctx.fillStyle на црно, а затим користите ctx.fillRect() почевши од (0,0) са димензијама вашег платна. Лако!

  2. Учитајте текстуре игре

    💡 Ево како: Користите await loadAsset() за учитавање ваших слика играча и непријатеља. Сачувајте их у променљиве како бисте их касније могли користити. Запамтите неће се приказати док их заправо не нацртате!

  3. Нацртајте херојски брод у централној доњој позицији

    💡 Ево како: Користите ctx.drawImage() за позиционирање вашег хероја. За x-координату, пробајте canvas.width / 2 - 45 да га центрирате, а за y-координату користите canvas.height - canvas.height / 4 да га поставите у доњи део.

  4. Нацртајте формацију од 5×5 непријатељских бродова

    💡 Ево како: Пронађите функцију createEnemies и поставите угњеждену петљу. Биће вам потребна нека математика за размак и позиционирање, али не брините показаћу вам тачно како!

Прво, утврдите константе за правилан распоред формације непријатеља:

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;

Хајде да разложимо шта ове константе раде:

  • Ми постављамо 5 непријатеља по реду и колони (лепа 5×5 мрежа)
  • Ми дефинишемо колико простора треба оставити између непријатеља како не би изгледали скучено
  • Ми рачунамо колико ће широка бити цела формација
  • Ми утврђујемо где да почнемо и завршимо како би формација изгледала центрирано

Затим, креирајте угњеждене петље за цртање формације непријатеља:

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);
  }
}

Шта ова угњеждена петља ради:

  • Спољашња петља помера се с лева на десно кроз нашу формацију
  • Унутрашња петља иде одозго надоле да креира уредне редове
  • Ми цртамо сваки спрајт непријатеља на тачним x,y координатама које смо израчунали
  • Све остаје равномерно распоређено како би изгледало професионално и организовано

Резултат

Завршени резултат би требало да изгледа овако:

Црни екран са херојем и 5×5 чудовишта

Решење

Молимо вас да прво покушате


Одрицање од одговорности:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције Co-op Translator. Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.