chore(i18n): sync translations with latest source changes (chunk 12/20, 100 files)

pull/1668/head
localizeflow[bot] 2 weeks ago
parent 9f4fafece3
commit 04a4b14ca0

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@ -1,31 +1,76 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "84053695dca714e16ed064366503ebd5",
"translation_date": "2025-10-24T23:39:30+00:00",
"original_hash": "7994743c5b21fdcceb36307916ef249a",
"translation_date": "2026-01-07T07:55:37+00:00",
"source_file": "6-space-game/2-drawing-to-canvas/README.md",
"language_code": "sr"
}
-->
# Направите свемирску игру, део 2: Цртање хероја и чудовишта на платну
Canvas API је једна од најмоћнијих функција веб развоја за креирање динамичке, интерактивне графике директно у вашем претраживачу. У овој лекцији, трансформисаћемо празан HTML `<canvas>` елемент у свет игре испуњен херојима и чудовиштима. Замислите платно као вашу дигиталну таблу за цртање где код постаје визуелан.
Надовезујемо се на оно што сте научили у претходној лекцији, а сада ћемо се упустити у визуелне аспекте. Научићете како да учитате и прикажете спрајтове игре, прецизно позиционирате елементе и креирате визуелну основу за вашу свемирску игру. Ово премошћује јаз између статичних веб страница и динамичких, интерактивних искустава.
На крају ове лекције, имаћете комплетну сцену игре са вашим херојским бродом који је правилно позициониран и формацијама непријатеља спремним за битку. Разумећете како модерне игре рендерују графику у претраживачима и стекнућете вештине за креирање сопствених интерактивних визуелних искустава. Хајде да истражимо графику на платну и оживимо вашу свемирску игру!
## Квиз пре предавања
# Направи просторну игру део 2: Исцртај јунака и чудовишта на Canvas
```mermaid
journey
title Ваш пут графике Canvas
section Основа
Разумевање Canvas API-ја: 3: Student
Учите координатни систем: 4: Student
Цртај основне облике: 4: Student
section Рад са сликама
Учитај игре ресурсе: 4: Student
Руковање асинхроним учитавањем: 5: Student
Позиционирање спрајтова: 5: Student
section Рендеровање игре
Креирај екран игре: 5: Student
Прави формације: 5: Student
Оптимизуј перформансе: 4: Student
```
Canvas API је једна од најмоћнијих функција веб развоја за креирање динамичке, интерактивне графике директно у вашем претраживачу. У овом часу, претворићемо тај празни HTML `<canvas>` елемент у свет игре пун јунака и чудовишта. Размислите о canvas-у као о вашој дигиталној уметничкој дасци где код постаје визуелни приказ.
Настављамо тамо где сте стали у претходном часу, а сада ћемо заронити у визуелне аспекте. Научићете како да учитате и прикажете спрајтове игре, прецизно позиционирате елементе и направите визуелну основу за вашу свемирску игру. Ово превазилази разлику између статичних веб страница и динамичких, интерактивних искустава.
На крају овог часа имаћете комплетну сцену игре са вашим јуначким бродом постављеним на право место и формацијама непријатеља спремним за битку. Разумете како модерне игре рендерују графику у претраживачима и стичете вештине за креирање својих интерактивних визуелних искустава. Хајде да истражимо canvas графику и оживимо вашу свемирску игру!
```mermaid
mindmap
root((Графика на платну))
Canvas Element
HTML5 Карактеристика
2D Контекст
Координатни систем
Контрола пиксела
Drawing Operations
Основни облици
Приказ текста
Приказ слика
Цртање путање
Asset Management
Учитавање слика
Асинхрона операција
Рад са грешкама
Перформансе
Game Rendering
Позиционирање спрајта
Распоред формације
Композиција сцене
Ажурирање фрејмова
Visual Effects
Боје и стилови
Трансформације
Анимације
Слојевање
```
## Предпредавачки квиз
[Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/31)
[Предпредавачки квиз](https://ff-quizzes.netlify.app/web/quiz/31)
## Платно
## Canvas
Шта је тачно `<canvas>` елемент? То је HTML5 решење за креирање динамичке графике и анимација у веб претраживачима. За разлику од обичних слика или видео записа који су статични, платно вам даје контролу над пикселима за све што се појављује на екрану. Ово га чини савршеним за игре, визуализацију података и интерактивну уметност. Замислите га као програмску површину за цртање где JavaScript постаје ваша четкица.
Шта је тачно овај `<canvas>` елемент? То је HTML5 решење за креирање динамичке графике и анимација у веб претраживачима. За разлику од обичних слика или видео снимака који су статични, canvas вам даје контролу на нивоу пиксела над свим што се приказује на екрану. Ово га чини савршеним за игре, визуализације података и интерактивну уметност. Размислите о њему као о програмабилној површини за цртање где JavaScript постаје ваш четкица.
Подразумевано, елемент платна изгледа као празан, транспарентан правоугаоник на вашој страници. Али ту лежи његов потенцијал! Његова права моћ се појављује када користите JavaScript за цртање облика, учитавање слика, креирање анимација и омогућавање интеракције са корисником. Слично је начину на који су пионири рачунарске графике у Bell Labs-у 1960-их морали да програмирају сваки пиксел како би креирали прве дигиталне анимације.
По дифолту, canvas елемент изгледа као празан, транспарентан правоугаоник на вашој страници. Али ту лежи његова потенцијална снага! Његова права моћ се појављује када користите JavaScript да нацртате облике, учитате слике, креирате анимације и учините да ствари реагују на корисничке интеракције. Ово је слично ономе како су рани рачунарски графички проналазачи у Bell Labs-у шездесетих година морали да програмирају сваки пиксел да створе прве дигиталне анимације.
✅ Прочитајте [више о Canvas API-ју](https://developer.mozilla.org/docs/Web/API/Canvas_API) на MDN.
✅ Прочитајте [више о Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) на MDN.
Ево како се обично декларише, као део тела странице:
@ -33,81 +78,155 @@ Canvas API је једна од најмоћнијих функција веб
<canvas id="myCanvas" width="200" height="100"></canvas>
```
**Шта овај код ради:**
- **Поставља** `id` атрибут како бисте могли да се позовете на овај специфичан елемент платна у JavaScript-у
- **Дефинише** ширину у пикселима за контролу хоризонталне величине платна
- **Утврђује** висину у пикселима за одређивање вертикалних димензија платна
**Ево шта овај код ради:**
- **Поставља** атрибут `id` како бисте могли да позивате овај специфични canvas елемент у JavaScript-у
- **Дефинише** `width` у пикселима ради контроле хоризонталне величине canvas-а
- **Успоставља** `height` у пикселима да одреди вертикалне димензије canvas-а
## Цртање једноставне геометрије
Сада када знате шта је елемент платна, хајде да истражимо како заправо цртати на њему! Платно користи координатни систем који вам може бити познат из математике, али постоји један важан заокрет специфичан за рачунарску графику.
Платно користи Картецијански координатни систем са x-осом (хоризонталном) и y-осом (вертикалном) за позиционирање свега што цртате. Али ево кључне разлике: за разлику од координатног система из математике, тачка порекла `(0,0)` почиње у горњем левом углу, са x-вредностима које расту како се крећете удесно и y-вредностима које расту како се крећете надоле. Овај приступ потиче из раних рачунарских дисплеја где су електронски зраци скенирали одозго надоле, чинећи горњи леви угао природном почетном тачком.
![мрежа платна](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.sr.png)
Сада када знате шта је canvas елемент, хајде да истражимо како се заправо на њему црта! Canvas користи координатни систем који може бити познат из математике, али постоји једна важна промена карактеристична за рачунарску графику.
Canvas користи Картезијански систем координата са x-осом (хоризонтално) и y-осом (вертикално) за позиционирање свега што нацртате. Али ево главне разлике: за разлику од математичког система координата, координатни почетак `(0,0)` почиње у горњем левом углу, са x-вредностима које расту када идете удесно, а y-вредностима које расту када идете надоле. Овај приступ потиче од раних рачунарских екрана где су електронски зраци скенировали од врха према дну, чинећи горњи леви угао природном тачком почетка.
```mermaid
quadrantChart
title Систем координата платна
x-axis Лево --> Десно
y-axis Горње --> Доље
quadrant-1 Квадрант 1
quadrant-2 Квадрант 2
quadrant-3 Квадрант 3
quadrant-4 Квадрант 4
Origin Point: [0.1, 0.1]
Hero Center: [0.5, 0.8]
Enemy Formation: [0.3, 0.2]
Power-up: [0.7, 0.6]
UI Elements: [0.9, 0.1]
```
![mрежа canvas-а](../../../../translated_images/canvas_grid.5f209da785ded492.sr.png)
> Слика са [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
Да бисте цртали на елементу платна, следићете исти тростепени процес који чини основу свих графика на платну. Када ово урадите неколико пута, постаје природно:
1. **Добијте референцу** на ваш Canvas елемент из DOM-а (као и било који други HTML елемент)
2. **Добијте 2D контекст рендеровања** ово пружа све методе за цртање
3. **Почните да цртате!** Користите уграђене методе контекста за креирање ваше графике
Да бисте цртали на canvas елементу, пратите исти тростепени поступак који чини основу целе canvas графике. Када то урадите неколико пута, постаје друга природа:
```mermaid
flowchart LR
A[HTML Canvas елемент] --> B[Добијте референцу канваса]
B --> C[Добијте 2D контекст]
C --> D[Операције цртања]
D --> E[Цртајте облике]
D --> F[Цртајте текст]
D --> G[Цртајте слике]
D --> H[Примените стилове]
E --> I[Прикажи на екрану]
F --> I
G --> I
H --> I
style A fill:#e1f5fe
style C fill:#e8f5e8
style I fill:#fff3e0
```
1. **Узмите референцу** на ваш Canvas елемент из DOM-а (као за било који други HTML елемент)
2. **Узмите 2D рендеринг контекст** он пружа све методе за цртање
3. **Почните са цртањем!** Користите уграђене методе конекста да направите своју графику
Ево како то изгледа у коду:
```javascript
// Step 1: Get the canvas element
// Корак 1: Узмите канвас елемент
const canvas = document.getElementById("myCanvas");
// Step 2: Get the 2D rendering context
// Корак 2: Узмите 2D контекст за цртање
const ctx = canvas.getContext("2d");
// Step 3: Set fill color and draw a rectangle
// Корак 3: Поставите боју пуњења и нацртајте правоугаоник
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 200, 200); // x, y, width, height
ctx.fillRect(0, 0, 200, 200); // x, y, ширина, висина
```
**Хајде да ово разложимо корак по корак:**
- Ми **узимамо** наш елемент платна користећи његов ID и чувамо га у променљивој
- Ми **добијамо** 2D контекст рендеровања ово је наш алат пун метода за цртање
- Ми **кажемо** платну да желимо да попунимо ствари црвеном бојом користећи `fillStyle` својство
- Ми **цртамо** правоугаоник који почиње у горњем левом углу (0,0) и који је широк и висок 200 пиксела
✅ Canvas API се углавном фокусира на 2D облике, али можете такође цртати 3D елементе на веб страници; за то можете користити [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API).
**Разложимо ово корак по корак:**
- Ми **узимамо** наш canvas елемент помоћу његовог ID и чувамо га у варијаблу
- Ми **узимамо** 2D рендеринг контекст овај је наш сет алата са методама за цртање
- Ми **кажемо** canvas-у да желимо да испунимо бојом црвеном користећи `fillStyle` својство
- Ми **нацртамо** правоугаоник почевши од горњег левог угла (0,0) који је широк и висок 200 пиксела
Можете цртати разне ствари са Canvas API-јем као што су:
✅ Canvas API се највише фокусира на 2D облике, али можете цртати и 3D елементе на веб сајту; за то можете користити [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API).
- **Геометријски облици**, већ смо показали како да нацртате правоугаоник, али постоји много више што можете да нацртате.
- **Текст**, можете нацртати текст са било којим фонтом и бојом коју желите.
- **Слике**, можете нацртати слику на основу сликовног ресурса као што је .jpg или .png, на пример.
Можете цртати све врсте ствари помоћу Canvas API као што су:
✅ Пробајте! Знате како да нацртате правоугаоник, можете ли нацртати круг на страници? Погледајте неке занимљиве цртеже на платну на CodePen. Ево [посебно импресивног примера](https://codepen.io/dissimulate/pen/KrAwx).
- **Геометријски облици**, већ смо показали како се црта правоугаоник, али има још много тога што можете цртати.
- **Текст**, можете цртати текст са било којим фонтом и бојом коју желите.
- **Слике**, можете цртати слику засновану на сликовном ресурсу као што је .jpg или .png на пример.
## Учитавање и цртање сликовног ресурса
✅ Испробајте! Знате како да нацртате правоугаоник, можете ли нацртати круг на страници? Погледајте неке интересантне Canvas цртеже на CodePen-у. Ево [нарочито импресивног примера](https://codepen.io/dissimulate/pen/KrAwx).
Цртање основних облика је корисно за почетак, али већини игара су потребне стварне слике! Спрајтови, позадине и текстуре су оно што даје играма њихову визуелну привлачност. Учитавање и приказивање слика на платну функционише другачије од цртања геометријских облика, али је једноставно када разумете процес.
### 🔄 **Педагошки преглед**
**Разумевање основа Canvas-а**: Пре него што пређете на учитавање слика, уверите се да можете:
- ✅ Објаснити како се координатни систем canvas-а разликује од математичког система координата
- ✅ Разумети тростепени процес цртања на canvas-у
- ✅ Идентификовати шта пружа 2D рендеринг контекст
- ✅ Описати како fillStyle и fillRect раде заједно
Потребно је да креирамо `Image` објекат, учитамо нашу сликовну датотеку (ово се дешава асинхроно, што значи "у позадини"), а затим да је нацртамо на платну када буде спремна. Овај приступ осигурава да се ваше слике правилно приказују без блокирања апликације током учитавања.
**Брзи самотест**: Како бисте нацртали плави круг на позицији (100, 50) радијусa 25?
```javascript
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(100, 50, 25, 0, 2 * Math.PI);
ctx.fill();
```
**Методе цртања на Canvas-у које сада знате**:
- **fillRect()**: Црта испуњене правоугаонике
- **fillStyle**: Поставља боје и узорке
- **beginPath()**: Започиње нове путање цртања
- **arc()**: Креира кругове и кривине
## Учитај и нацртај сликовни ресурс
Цртање основних облика је корисно за почетак, али већина игара треба праве слике! Спрајтови, позадине и текстуре су оно што играма даје визуелни карактер. Учитавање и приказивање слика на canvas-у ради другачије него цртање геометријских облика, али је једноставно када разумете процес.
Морамо да креирамо `Image` објекат, учитамо нашу слику (ово се дешава асинхроно, што значи „у позадини“), и онда је нацртамо на canvas када је спремна. Овај приступ осигурава да ваше слике буду правилно приказане без блокирања ваше апликације током учитавања.
```mermaid
sequenceDiagram
participant JS as JavaScript
participant Img as Објекат слике
participant Server as Фајл сервер
participant Canvas as Контекст платна
JS->>Img: new Image()
JS->>Img: Постави src својство
Img->>Server: Захтевај фајл слике
Server->>Img: Враћа податке слике
Img->>JS: Покреће onload догађај
JS->>Canvas: drawImage(img, x, y)
Canvas->>Canvas: Прикажи на екрану
Note over JS,Canvas: Асинхроно учитавање спречава блокаду корисничког интерфејса
```
### Основно учитавање слике
```javascript
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 објекат за чување нашег спрајта или текстуре
- Ми **кажемо** којој сликовној датотеци да приступи постављањем путање извора
- Ми **слушамо** догађај учитавања како бисмо знали тачно када је слика спремна за употребу
**Ево шта се дешава у овом коду:**
- Ми **креирамо** нови Image објекат који ће чувати наш спрајт или текстуру
- Ми **кажемо** који сликовни фајл треба да учита подешавајући изворну путању
- Ми **слушамо** load догађај да знамо тачно када је слика спремна за употребу
### Бољи начин за учитавање слика
Ево робуснијег начина за руковање учитавањем слика који професионални програмери често користе. Увешћемо логику учитавања слика у функцију засновану на Promise-у овај приступ, који је постао популаран када су JavaScript Promises постали стандард у ES6, чини ваш код организованијим и елегантно решава грешке:
Ево робуснијег начина да се реши учитавање слика који професионални програмери често користе. Увити ћемо учитавање слика у функцију засновану на Promise-у овај приступ, популаран од када су JavaScript Promises постали стандард у ES6, чини код организованијим и омогућава лепо руковање грешкама:
```javascript
function loadAsset(path) {
@ -123,12 +242,12 @@ function loadAsset(path) {
});
}
// Modern usage with async/await
// Савремена употреба са 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);
}
@ -136,25 +255,25 @@ async function initializeGame() {
```
**Шта смо овде урадили:**
- **Увели** сву ту логику учитавања слика у Promise како бисмо боље управљали њом
- **Додали** руковање грешкама које нам заправо говори када нешто крене наопако
- **Користили** савремени async/await синтакс јер је много читљивији
- **Укључили** try/catch блокове за елегантно руковање било којим проблемима током учитавања
- **Увили** смо сву ту логику учитавања слика у Promise ради боље контроле
- **Додали** руковање грешкама које нас стварно обавештава када нешто пође по злу
- **Користили** модеран async/await синтаксис јер је много читљивији
- **Укључили** try/catch блокове за глатко руковање било каквим проблемима током учитавања
Када се ваше слике учитају, њихово цртање на платну је заправо прилично једноставно:
Када су ваше слике учитане, њихово цртање на canvas је заправо прилично једноставно:
```javascript
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) {
@ -163,32 +282,56 @@ async function renderGameScreen() {
}
```
**Хајде да ово разложимо корак по корак:**
- Ми **учитавамо** и слике хероја и чудовишта у позадини користећи await
- Ми **узимамо** наш елемент платна и добијамо тај 2D контекст рендеровања који нам је потребан
- Ми **позиционирамо** слику хероја тачно у центар користећи брзу математику координата
- Ми **постављамо** слику чудовишта у горњи леви угао да започнемо формацију непријатеља
- Ми **хватамо** било какве грешке које се могу догодити током учитавања или рендеровања
## Сада је време да почнете са изградњом ваше игре
**Прођимо корак по корак:**
- Ми **учитавамо** и хероја и чудовиште у позадини користећи await
- Ми **узимамо** наш canvas елемент и добијамо тај 2D рендеринг контекст који нам треба
- Ми **позиционирамо** херојску слику управо у центар помоћу једноставне математике координата
- Ми **постављамо** слику чудовишта у горњи леви угао као почетак формације непријатеља
- Ми **хватамо** све грешке које се могу појавити током учитавања или рендеровања
```mermaid
flowchart TD
A[Учитај Ресурсе] --> B{Све Слике Учитанe?}
B -->|Не| C[Прикажи Учитавање]
B -->|Да| D[Добити Контекст Платна]
C --> B
D --> E[Очисти Екран]
E --> F[Исцртај Позадину]
F --> G[Исцртај Формирање Непријатеља]
G --> H[Исцртај Херојски Брод]
H --> I[Примени Визуелне Ефекте]
I --> J[Рендеруј Фрејм]
subgraph "Rendering Pipeline"
K[Asset Management]
L[Scene Composition]
M[Drawing Operations]
N[Frame Output]
end
style A fill:#e1f5fe
style J fill:#e8f5e8
style I fill:#fff3e0
```
## Сада је време да почнете правити своју игру
Сада ћемо све спојити како бисмо креирали визуелну основу ваше свемирске игре. Имате солидно разумевање основа платна и техника учитавања слика, па ће вас овај практични део водити кроз изградњу комплетног екрана игре са правилно позиционираним спрајтовима.
Сада ћемо све спојити да направимо визуелну основу ваше просторске игре. Имате солидно разумевање основа canvas-а и техника учитавања слика, па ће овај практични део водити кроз креирање комплетног екрана игре са исправно позиционираним спрајтовима.
### Шта да направите
### Шта правити
Направићете веб страницу са Canvas елементом. Требало би да приказује црни екран `1024*768`. Обезбедили смо вам две слике:
Направићете веб страницу са Canvas елементом. Требало би да приказује црни екран димензија `1024*768`. Доставили смо вам две слике:
- Херојски брод
![Херојски брод](../../../../translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.sr.png)
![Hero ship](../../../../translated_images/player.dd24c1afa8c71e9b.sr.png)
- 5*5 чудовишта
![Брод чудовишта](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.sr.png)
![Monster ship](../../../../translated_images/enemyShip.5df2a822c16650c2.sr.png)
### Препоручени кораци за почетак развоја
Пронађите почетне датотеке које су креиране за вас у подфолдеру `your-work`. Структура вашег пројекта треба да садржи:
Пронађите почетне фајлове који су направљени за вас у потфолдеру `your-work`. Структура вашег пројекта треба да садржи:
```bash
your-work/
@ -200,46 +343,46 @@ your-work/
└── package.json
```
**Шта имате на располагању:**
- **Спрајтови игре** се налазе у фолдеру `assets/` како би све било организовано
- **Ваш главни HTML фајл** поставља Canvas елемент и припрема све
- **JavaScript фајл** где ћете написати сву магију рендеровања игре
- **package.json** који поставља развојни сервер како бисте могли да тестирате локално
**Ево са чим радите:**
- **Спрајтови игре** се налазе у фолдеру `assets/` да све буде организовано
- **Главни HTML фајл** подешава canvas елемент и припрема све
- **JavaScript фајл** у ком ћете писати сву магију рендеровања игре
- **package.json** који подешава развојни сервер за локално тестирање
Отворите овај фолдер у Visual Studio Code-у да започнете развој. Биће вам потребно локално развојно окружење са Visual Studio Code-ом, NPM-ом и Node.js-ом инсталираним. Ако немате подешен `npm` на вашем рачунару, [овде је објашњено како да га инсталирате](https://www.npmjs.com/get-npm).
Отворите овај фасциклу у Visual Studio Code да почнете развој. Требаће вам локално развојно окружење са Visual Studio Code-ом, NPM-ом и Node.js-ом инсталираним. Ако немате `npm` подешен на рачунару, [овде је како га инсталирати](https://www.npmjs.com/get-npm).
Покрените ваш развојни сервер тако што ћете отићи у фолдер `your-work`:
Покрените развојни сервер тако што ћете отићи у фасциклу `your-work`:
```bash
cd your-work
npm start
```
**Ова команда ради неке прилично занимљиве ствари:**
- **Покреће** локални сервер на `http://localhost:5000` како бисте тестирали вашу игру
- **Сервира** све ваше фајлове правилно како би их ваш претраживач учитао
- **Прати** промене у вашим фајловима како бисте могли несметано да развијате
- **Пружа вам** професионално развојно окружење за тестирање свега
**Ова команда ради неке јако корисне ствари:**
- **Покреће** локални сервер на `http://localhost:5000` да бисте могли тестирати игру
- **Сервира** све ваше фајлове како ваш претраживач правилно учитава садржај
- **Прати** промене у вашим фајловима за глатки развој
- **Пружа** вам професионално окружење за развој и тестирање
> 💡 **Напомена**: Ваш претраживач ће у почетку приказати празну страницу то је очекивано! Како будете додавали код, освежите ваш претраживач да видите промене. Овај приступ итеративног развоја је сличан начину на који је НАСА изградила компјутер за навигацију Аполо мисије тестирајући сваки компонент пре интеграције у већи систем.
> 💡 **Напомена**: Ваш претраживач ће у почетку приказати празну страницу то је очекивано! Како додајете код, освежите страницу да видите измене. Овај инкрементални приступ развоју сличан је ономе како је NASA градила Apоло рачунар тестирајући сваки део пре интеграције у већи систем.
### Додајте код
Додајте потребан код у `your-work/app.js` да бисте завршили следеће задатке:
Додајте потребан код у `your-work/app.js` да завршите следеће задатке:
1. **Нацртајте платно са црном позадином**
> 💡 **Ево како**: Пронађите TODO у `/app.js` и додајте само две линије. Поставите `ctx.fillStyle` на црно, а затим користите `ctx.fillRect()` почевши од (0,0) са димензијама вашег платна. Лако!
1. **Исцртај canvas са црном позадином**
> 💡 **Ево како**: Пронађите TODO у `/app.js` и додајте само две линије. Подесите `ctx.fillStyle` на црну, затим користите `ctx.fillRect()` почевши од (0,0) са димензијама canvas-а. Једноставно!
2. **Учитајте текстуре игре**
> 💡 **Ево како**: Користите `await loadAsset()` за учитавање ваших слика играча и непријатеља. Сачувајте их у променљиве како бисте их касније могли користити. Запамтите неће се приказати док их заправо не нацртате!
2. **Учитај текстуре игре**
> 💡 **Ево како**: Користите `await loadAsset()` да учитате слике играча и непријатеља. Сачувајте их у варијабле да бисте их касније користили. Запамтите неће се појавити док их заиста не нацртате!
3. **Нацртајте херојски брод у централној доњој позицији**
> 💡 **Ево како**: Користите `ctx.drawImage()` за позиционирање вашег хероја. За x-координату, пробајте `canvas.width / 2 - 45` да га центрирате, а за y-координату користите `canvas.height - canvas.height / 4` да га поставите у доњи део.
3. **Исцртај јуначки брод у центру на дну**
> 💡 **Ево како**: Користите `ctx.drawImage()` да позиционирате вашег јунака. За x координату, пробајте `canvas.width / 2 - 45` да га центрирате, а за y координату користите `canvas.height - canvas.height / 4` да га ставите у доњу зону.
4. **Нацртајте формацију од 5×5 непријатељских бродова**
> 💡 **Ево како**: Пронађите функцију `createEnemies` и поставите угњеждену петљу. Биће вам потребна нека математика за размак и позиционирање, али не брините показаћу вам тачно како!
4. **Исцртај формацију непријатељских бродова 5×5**
> 💡 **Ево како**: Пронађите функцију `createEnemies` и направите угнежђене петље. Мораћете урадити неке рачуне за размаке и позиције, али не брините показаћу вам како!
Прво, утврдите константе за правилан распоред формације непријатеља:
Прво, дефинишите константе за правилан распоред непријатеља:
```javascript
const ENEMY_TOTAL = 5;
@ -249,13 +392,39 @@ const START_X = (canvas.width - FORMATION_WIDTH) / 2;
const STOP_X = START_X + FORMATION_WIDTH;
```
**Хајде да разложимо шта ове константе раде:**
- Ми **постављамо** 5 непријатеља по реду и колони (лепа 5×5 мрежа)
- Ми **дефинишемо** колико простора треба оставити између непријатеља како не би изгледали скучено
- Ми **рачунамо** колико ће широка бити цела формација
- Ми **утврђујемо** где да почнемо и завршимо како би формација изгледала центрирано
Затим, креирајте угњеждене петље за цртање формације непријатеља:
**Ево шта ове константе раде:**
- Постављамо 5 непријатеља по реду и колони (лепа 5×5 мрежа)
- Дефинишемо колико простора има између непријатеља да не буду гужвани
- Израчунавамо ширину целе формације
- Одређујемо где да почнемо и где да завршимо да формација изгледа центрирано
```mermaid
flowchart LR
A["Ширина платна: 1024пкс"] --> B["Ширина формације: 490пкс"]
B --> C["Почетак X: 267пкс"]
C --> D["Размак непријатеља: 98пкс"]
subgraph "5x5 Формација непријатеља"
E["Ред 1: Y=0"]
F["Ред 2: Y=50"]
G["Ред 3: Y=100"]
H["Ред 4: Y=150"]
I["Ред 5: Y=200"]
end
subgraph "Размак колона"
J["Колона 1: X=267"]
K["Колона 2: X=365"]
L["Колона 3: X=463"]
M["Колона 4: X=561"]
N["Колона 5: X=659"]
end
style A fill:#e1f5fe
style B fill:#e8f5e8
style C fill:#fff3e0
```
Затим, направите угнежђене петље да исцртате формацију непријатеља:
```javascript
for (let x = START_X; x < STOP_X; x += ENEMY_SPACING) {
@ -265,23 +434,191 @@ for (let x = START_X; x < STOP_X; x += ENEMY_SPACING) {
}
```
**Шта ова угњеждена петља ради:**
- Спољашња петља **помера се** с лева на десно кроз нашу формацију
- Унутрашња петља **иде** одозго надоле да креира уредне редове
- Ми **цртамо** сваки спрајт непријатеља на тачним x,y координатама које смо израчунали
- Све остаје **равномерно распоређено** како би изгледало професионално и организовано
**Ево шта ова угнежђена петља ради:**
- Спољашња петља **креће се** с лева на десно кроз формацију
- Унутрашња петља **помера се** од врха према дну да направи редове
- Цртамо сваког непријатеља на тачним x,y координатама које смо израчунали
- Све је **равномјерно размакнуто** да изгледа професионално и организовано
### 🔄 **Педагошки преглед**
**Вештина рендеровања игре**: Потврдите разумевање комплетног рендеринг система:
- ✅ Како асинхроно учитавање слика спречава блокирање UI током покретања игре?
- ✅ Зашто позиције формације непријатеља рачунамо коришћењем константи уместо тврдог кода?
- ✅ Коју улогу игра 2D рендеринг контекст у цртачким операцијама?
- ✅ Како угнежђене петље креирају организоване формације спрајтова?
**Перформансе**: Ваша игра сада демонстрира:
- **Ефикасно учитавање ресурса**: управљање сликама засновано на Promise
- **Организовано рендеровање**: структурисане операције цртања
- **Математичко позиционирање**: израчунато место спрајтова
- **Руковање грешкама**: глатко управљање пропустима
**Концепти визуелног програмирања**: Научили сте:
- **Системи координата**: Превођење математике у позиције на екрану
- **Управљање спрајтовима**: Учитавање и приказивање графике игре
- **Алгоритми формирања**: Математички обрасци за организоване распореде
- **Асинхроне операције**: Модерни JavaScript за глатко корисничко искуство
## Резултат
Завршени резултат би требало да изгледа овако:
Потпун резултат треба да изгледа овако:
![Црни екран са херојем и 5×5 чудовишта](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.sr.png)
![Црни екран са херојем и 5*5 чудовишта](../../../../translated_images/partI-solution.36c53b48c9ffae2a.sr.png)
## Решење
Молимо вас да прво покушате
Молимо вас да прво покушате сами да решите, али ако запнете, погледајте [решење](../../../../6-space-game/2-drawing-to-canvas/solution/app.js)
---
## GitHub Copilot Agent изазов 🚀
Користите Agent режим да бисте решили следећи изазов:
**Опис:** Унапређујте ваш свемирски канвас додавањем визуелних ефеката и интерактивних елемената користећи Canvas API технике које сте научили.
**Задатак:** Креирајте нови фајл под називом `enhanced-canvas.html` са канвасом који приказује анимиране звезде у позадини, пулсирајућу траку здравља за хероја и непријатељске бродове који спорије се крећу надоле. Укључите JavaScript код који црта трепћуће звезде користећи случајне позиције и провидност, имплементира траку здравља која мења боју у зависности од нивоа здравља (зелена > жута > црвена), и анимира непријатељске бродове који се крећу надоле различитим брзинама.
Сазнајте више о [agent режиму](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
## 🚀 Изазов
Нaučili сте цртање са Canvas API фокусираним на 2D; погледајте [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) и покушајте да нацртате 3D објекат.
## Квиз после предавања
[Квиз после предавања](https://ff-quizzes.netlify.app/web/quiz/32)
## Преглед и Самосталан Рад
Сазнајте више о Canvas API-ју [читајући о њему](https://developer.mozilla.org/docs/Web/API/Canvas_API).
### ⚡ **Шта можете урадити у наредних 5 минута**
- [ ] Отворите конзолу прегледача и креирајте елемент канваса са `document.createElement('canvas')`
- [ ] Покушајте да нацртате правоугаоник користећи `fillRect()` на контексту канваса
- [ ] Експериментишите са различитим бојама користећи својство `fillStyle`
- [ ] Нацртајте једноставан круг користећи методу `arc()`
### 🎯 **Шта можете постићи овог сата**
- [ ] Завршити квиз после часа и разумети основе канваса
- [ ] Креирати апликацију за цртање на канвасу са више облика и боја
- [ ] Имплементирати учитавање слика и приказивање спрајтова за вашу игру
- [ ] Направити једноставну анимацију која помера објекте по канвасу
- [ ] Вежбати трансформације на канвасу као што су скалирање, ротација и транслација
### 📅 **Ваш недељни курс путовања кроз Canvas**
- [ ] Завршити свемирску игру са довршеном графиком и анимацијама спрајтова
- [ ] Савладати напредне технике канваса као што су градијенти, узорци и комопозити
- [ ] Креирати интерактивне визуелизације користећи канвас за представљање података
- [ ] Савладати оптимизацију канваса за глатке перформансе
- [ ] Направити апликацију за цртање или сликање са разноврсним алатима
- [ ] Истражити креативне кодинг патерне и генеративну уметност са канвасом
### 🌟 **Ваш месечни мајсторски курс графике**
- [ ] Направити сложене визуелне апликације користећи Canvas 2D и WebGL
- [ ] Научити концепте графичког програмирања и основе шейдера
- [ ] Доприносити отвореним графичким библиотекама и алатима за визуализацију
- [ ] Савладати оптимизацију перформанси за графички захтевне апликације
- [ ] Креирати образовни садржај о програмирању канваса и рачунарској графици
- [ ] Постати експерт за графичко програмирање који помаже другима да креирају визуелна искуства
## 🎯 Ваш план за савладавање графике на Canvas-у
```mermaid
timeline
title Напредак у учењу Canvas API-ја
section Основе Canvas-а (15 минута)
Основне операције: Референца елемената
: Приступ 2D контексту
: Координатни систем
: Цртање једноставних облика
section Технике цртања (20 минута)
Графички примитиви: Правоугаоници и кругови
: Боје и стилови
: Приказ текста
: Операције путање
section Рад са сликама (25 минута)
Управљање ресурсима: Креирање Image објекта
: Асинхрони обрасци учитавања
: Руковање грешкама
: Оптимизација перформанси
section Графика за игре (30 минута)
Рендеровање спрајтова: Алгоритми позиционирања
: Израчунавање формација
: Компоновање сцене
: Рендеровање фрејмова
section Напредне технике (40 минута)
Визуелни ефекти: Трансформације
: Анимације
: Слојевање
: Управљање стањем
section Перформансе (35 минута)
Оптимизација: Ефикасно цртање
: Управљање меморијом
: Контрола фреквенције фрејмова
: Кеширање ресурса
section Професионалне вештине (1 недеља)
Производна графика: Интеграција WebGL-а
: Canvas библиотеке
: Игрећи енџини
: Разматрања крос-платформености
section Напредна графика (1 месец)
Специјализоване апликације: Визуализација података
: Интерактивна уметност
: Ефекти у реалном времену
: 3D графика
```
### 🛠️ Резиме вашег алата за Canvas графику
Након завршетка овог часа, сада имате:
- **Мастерство Canvas API-ја**: Потпуно разумевање 2D графичког програмирања
- **Математика координата**: Прецизно позиционирање и алгоритми распоређивања
- **Управљање ресурсима**: Професионално учитавање слика и руковање грешкама
- **Рендеринг процес**: Структурисан приступ састављању сцена
- **Играчка графика**: Позиционирање спрајтова и рачунање форми
- **Асинхроно програмирање**: Модерни JavaScript обрасци за глатке перформансе
- **Визуелно програмирање**: Превођење математичких концепата у екранску графику
**Применa у реалном свету**: Вештине са Canvas-ом се директно примењују на:
- **Визуализацију података**: Графиконе, дијаграме и интерактивне табле
- **Развој игара**: 2D игре, симулације и интерактивна искуства
- **Дигиталну уметност**: Креативно кодирање и генеративне уметничке пројекте
- **Дизајн интерфејса**: Прилагођену графику и интерактивне елементе
- **Образовни софтвер**: Визуелне алате за учење и симулације
- **Веб апликације**: Динамичку графику и визуализацију у реалном времену
**Професионалне вештине које сте стекли**: Сада можете:
- **Креирати** прилагођена графичка решења без спољних библиотека
- **Оптимизовати** перформансе рендеровања за глатко корисничко искуство
- **Отлањати грешке** у сложеним визуелним проблемима коришћењем алата прегледача
- **Дизајнирати** скалабилне графичке системе користећи математичке принципе
- **Интегрисати** Canvas графику са модерним веб апликационим фрејмворковима
**Методе Canvas API-ја које сте савладали**:
- **Управљање елементима**: getElementById, getContext
- **Операције цртања**: fillRect, drawImage, fillStyle
- **Учитавање ресурса**: Објекти Image, шаблони Promise
- **Математско позиционирање**: Израчунавање координата, алгоритми формирања
**Следећи ниво**: Спремни сте да додате анимацију, интеракцију корисника, детекцију судара, или да истражите WebGL за 3D графику!
🌟 **Остварили сте успех**: Направили сте комплетан систем за рендеровање игре користећи основне технике Canvas API-ја!
## Задатак
[Играјте се са Canvas API-јем](assignment.md)
---
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Изјава о одрицању одговорности**:
Овај документ је преведен помоћу АИ сервиса за превођење [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде што прецизнији, имајте у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати званичним и ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било какве неспоразуме или погрешне интерпретације настале употребом овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -1,103 +1,186 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "022bbb5c869091b98f19e408e0c51d5d",
"translation_date": "2025-10-24T23:38:39+00:00",
"original_hash": "8c55a2bd4bc0ebe4c88198fd563a9e09",
"translation_date": "2026-01-07T08:01:47+00:00",
"source_file": "6-space-game/3-moving-elements-around/README.md",
"language_code": "sr"
}
-->
# Изградња свемирске игре, део 3: Додавање кретања
Размислите о вашим омиљеним играма оно што их чини привлачним нису само лепа графика, већ начин на који се све креће и реагује на ваше акције. Тренутно, ваша свемирска игра је као лепа слика, али сада ћемо додати кретање које ће је оживети.
Када су НАСА-ини инжењери програмирали рачунар за навигацију за мисије Аполо, суочили су се са сличним изазовом: како учинити да свемирски брод реагује на команде пилота, а истовремено аутоматски одржава корекције курса? Принципи које ћемо данас научити одражавају те исте концепте управљање кретањем које контролише играч уз аутоматско понашање система.
У овом лекцији, научићете како да свемирски бродови клизе преко екрана, реагују на команде играча и стварају глатке обрасце кретања. Разложићемо све на разумљиве концепте који се природно надовезују један на други.
На крају, играчи ће моћи да управљају својим херојским бродом по екрану, док ће непријатељски бродови патролирати изнад. Још важније, разумећете основне принципе који покрећу системе кретања у играма.
## Квиз пре предавања
# Направи Свемирску Игру део 3: Додавање Покрета
```mermaid
journey
title Ваш пут анимације игре
section Основе кретања
Разумети принципе кретања: 3: Student
Научити ажурирање координата: 4: Student
Имплементирати основно кретање: 4: Student
section Контроле играча
Обрадити догађаје са тастатуре: 4: Student
Спречити подразумевано понашање: 5: Student
Креирати одзивне контроле: 5: Student
section Системи игре
Изградити петљу игре: 5: Student
Управљати животним циклусом објекта: 5: Student
Имплементирати pub/sub образац: 5: Student
```
Размислите о вашим омиљеним играма оно што их чини привлачним није само лепа графика, већ начин на који све се помера и реагује на ваше акције. Тренутно, ваша свемирска игра је као прелепа слика, али управо ћемо додати кретање које је оживљава.
Када су инжењери НАСА-е програмирали управљачки рачунар за Аполо мисије, суочили су се са сличним изазовом: како натерати свемирски брод да реагује на улаз пилота, а при том аутоматски одржава корекције курса? Принципи које ћемо данас научити одражавају те исте концепте управљање кретањем које контролише играч заједно са аутоматским системским понашањима.
У овој лекцији научићете како да свемирски бродови клизе преко екрана, реагују на команде играча и креирају глатке покретне образце. Разложићемо све на разумљиве концепте који се природно надовезују један на други.
До краја ћете морати да омогућите играчима да лете својим јунаком по екрану, док непријатељски бродови патролирају изнад. Још важније, разумећете основне принципе који покрећу системе кретања у играма.
```mermaid
mindmap
root((Игра анимација))
Movement Types
Player Controlled
Automatic Motion
Physics Based
Scripted Paths
Event Handling
Унос са тастатуре
Миш догађаји
Контроле додира
Превенција подразумеваног
Game Loop
Логика ажурирања
Прикажи фрејм
Чисти платно
Контрола брзине фрејмова
Object Management
Ажурирања позиције
Детекција судара
Управљање животним циклусом
Праћење стања
Communication
Pub/Sub Pattern
Event Emitters
Пренос порука
Лоше повезивање
```
## Прекидачки тест пре предавања
[Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/33)
[Прексидачки тест](https://ff-quizzes.netlify.app/web/quiz/33)
## Разумевање кретања у игри
Игре оживљавају када се ствари почну кретати, а постоје два основна начина на која се то дешава:
Игре оживљавају када се ствари почну кретати, а постоје у основи два начина да се то деси:
- **Кретање које контролише играч**: Када притиснете тастер или кликнете мишем, нешто се помера. Ово је директна веза између вас и света игре.
- **Аутоматско кретање**: Када сама игра одлучује да помера ствари попут оних непријатељских бродова који морају патролирати екраном без обзира на ваше акције.
- **Кретање под контролом играча**: Када притиснете тастер или кликнете мишем, нешто се помера. Ово је директна веза између вас и света игре.
- **Аутоматско кретање**: Када игра сама одлучи да нешто помери као што су непријатељски бродови који морају да патролирају екраном без обзира шта ви радите.
Померање објеката на екрану рачунара је једноставније него што мислите. Сећате се оних x и y координата из математике? Управо са тим радимо овде. Када је Галилео пратио Јупитерове месеце 1610. године, он је у суштини радио исто цртао је позиције током времена да би разумео обрасце кретања.
Померање објеката на рачунарском екрану је једноставније него што мислите. Сећате ли се оних x и y координата из математике? Управо са тим радимо овде. Када је Галилео 1610. пратио Јупитерове месеце, суштински је радио исту ствар цртао положаје током времена да разуме обрасце кретања.
Померање ствари на екрану је као стварање анимације у стилу флипбука потребно је следити ова три једноставна корака:
Померање ствари на екрану је као прављење анимације у стрипу треба пратити ова три једноставна корака:
1. **Ажурирајте позицију** Промените где ваш објекат треба да буде (можда га померите 5 пиксела удесно)
2. **Обришите стари кадар** Очистите екран како не бисте видели трагове
3. **Нацртајте нови кадар** Поставите ваш објекат на нову позицију
```mermaid
flowchart LR
A["Фрејм N"] --> B["Ажурирај положаје"]
B --> C["Обриши платно"]
C --> D["Нарисати објекте"]
D --> E["Фрејм N+1"]
E --> F{Наставити?}
F -->|Да| B
F -->|Не| G["Крај игре"]
subgraph "Циклус анимације"
H["1. Израчунај нове положаје"]
I["2. Обриши претходни фрејм"]
J["3. Прикажи нови фрејм"]
end
style B fill:#e1f5fe
style C fill:#ffebee
style D fill:#e8f5e8
```
1. **Ажурирај положај** Промени где би објекат требало да буде (на пример, помери га 5 пиксела удесно)
2. **Обриши стари кадар** Очисти екран да не видиш никакве духолове трагове
3. **Нацртај нови кадар** Постави објекат на ново место
Радите ово довољно брзо, и ето! Добијате глатко кретање које изгледа природно играчима.
Уради ово довољно брзо и бум! Имаш глатко кретање које делује природно играчима.
Ево како то може изгледати у коду:
```javascript
// Set the hero's location
// Постави локацију хероја
hero.x += 5;
// Clear the rectangle that hosts the hero
// Очисти правоугаоник у којем се налази херој
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Redraw the game background and hero
// Пресликај позадину игре и херојa
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
```
**Шта овај код ради:**
- **Ажурира** x-координату хероја за 5 пиксела како би се померао хоризонтално
- **Брише** целу област платна како би уклонио претходни кадар
**Ово код ради:**
- **Ажурира** x-координату јунака за 5 пиксела да се помери хоризонтално
- **Брише** цело платно да уклони претходни кадар
- **Попуњава** платно црном бојом позадине
- **Поново црта** слику хероја на новој позицији
- **Поново црта** слику јунака на новом месту
✅ Можете ли смислити разлог зашто поновно цртање вашег хероја много пута у секунди може довести до трошкова перформанси? Прочитајте о [алтернативама овом обрасцу](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
✅ Можете ли да погодите зашто би поновно цртање јунака много пута у секунди могло да повећа трошкове перформанси? Прочитајте о [алтернативама овог обрасца](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
## Обрада догађаја са тастатуре
## Руковање догађајима са тастатуре
Овде повезујемо унос играча са акцијом у игри. Када неко притисне тастер за пуцање ласером или стрелицу за избегавање астероида, ваша игра мора да детектује и одговори на тај унос.
Овде повезујемо улаз играча са акцијом у игри. Када неко притисне размак да опали ласер или додирне тастер са стрелицом да се избегне астероид, игра мора да детектује и одговори на тај улаз.
Догађаји са тастатуре се дешавају на нивоу прозора, што значи да цео прозор вашег претраживача слуша те притиске тастера. Кликови мишем, с друге стране, могу бити везани за одређене елементе (као што је кликање на дугме). За нашу свемирску игру, фокусираћемо се на контроле тастатуре јер оне дају играчима тај класичан аркадни осећај.
Догађаји тастатуре се дешавају на нивоу прозора, што значи да цела ваша прегледачка прозор слуша за те притиске тастера. Кликови мишем, с друге стране, могу бити везани за одређене елементе (као што је клик на дугме). За нашу свемирску игру фокусираћемо се на тастатуру јер то даје играчима класичан аркадни осећај.
Ово ме подсећа на то како су телеграфисти у 19. веку морали да преводе унос Морзеове азбуке у смислене поруке ми радимо нешто слично, преводимо притиске тастера у команде игре.
Ово ме подсећа на то како су телеграфски оператери у 1800-им морали да преводе морзеове кодове у смислене поруке ми радимо нешто слично, преводећи притиске тастера у команде за игру.
Да бисте обрадили догађај, потребно је да користите метод `addEventListener()` прозора и да му дате два улазна параметра. Први параметар је назив догађаја, на пример `keyup`. Други параметар је функција која треба да се позове као резултат догађаја.
Да бисте руковали догађајем, треба да користите метод window `addEventListener()` и дате му два улазна параметра. Први параметар је име догађаја, на пример `keyup`. Други параметар је функција која треба да се позове као резултат догађаја.
Ево примера:
```javascript
window.addEventListener('keyup', (evt) => {
// evt.key = string representation of the key
// evt.key = стринг репрезентација тастера
if (evt.key === 'ArrowUp') {
// do something
// уради нешто
}
});
```
**Објашњење шта се овде дешава:**
- **Слуша** догађаје са тастатуре на целом прозору
- **Хвата** објекат догађаја који садржи информације о томе који је тастер притиснут
- **Проверава** да ли притиснути тастер одговара одређеном тастеру (у овом случају, горе стрелица)
**Разлагање онога што се овде дешава:**
- **Слуша** догађаје тастатуре на целом прозору
- **Хвата** објекат догађаја који садржи информације о том који је тастер притиснут
- **Проверава** да ли притиснути тастер одговара одређеном тастеру (у овом случају, стрелицa нагоре)
- **Извршава** код када је услов испуњен
За догађаје са тастатуре постоје два својства на објекту догађаја која можете користити да бисте видели који је тастер притиснут:
За догађаје тастатуре постоје две особине догађаја које можете користити да видите који је тастер притиснут:
- `key` - ово је стринг репрезентација притиснутог тастера, на пример `'ArrowUp'`
- `keyCode` - ово је нумеричка репрезентација, на пример `37`, што одговара `ArrowLeft`
- `key` - ово је низа знакова који представља притиснути тастер, на пример `'ArrowUp'`
- `keyCode` - ово је бројчана вредност, на пример `37`, што одговара `ArrowLeft`
✅ Манипулација догађајима са тастатуре је корисна и ван развоја игара. Које друге примене можете замислити за ову технику?
✅ Манипулација догађајима тастатуре је корисна и ван развоја игара. На шта све још можете помислити као коришћење ове технике?
### Посебни тастери: упозорење!
```mermaid
sequenceDiagram
participant User
participant Browser
participant EventSystem
participant GameLogic
participant Hero
User->>Browser: Притиска тастер ArrowUp
Browser->>EventSystem: keydown догађај
EventSystem->>EventSystem: preventDefault()
EventSystem->>GameLogic: emit('KEY_EVENT_UP')
GameLogic->>Hero: hero.y -= 5
Hero->>Hero: Ажурира положај
Note over Browser,GameLogic: Проток догађаја спречава подразумеване радње прегледача
Note over GameLogic,Hero: Pub/sub образац омогућава чисту комуникацију
```
### Специјални тастери: упозорење!
Неки тастери имају уграђене функције претраживача које могу ометати вашу игру. Стрелице померају страницу, а размак скаче надоле понашања која не желите када неко покушава да управља својим свемирским бродом.
Неки тастери имају уграђено понашање прегледача које може ометати вашу игру. Стрелице скролују страницу, а размак помера страницу надоле понашања која не желите када неко покушава да управља свемирским бродом.
Можемо спречити ова подразумевана понашања и дозволити нашој игри да обради унос. Ово је слично томе како су рани програмери рачунара морали да прекину системске интерупције како би креирали прилагођена понашања ми то радимо на нивоу претраживача. Ево како:
Можемо спречити ова подразумевана понашања и пустити игру да обради улаз уместо тога. Ово је слично као што су рани компјутерски програмери морали да надјачају системске прекиде да би направили прилагођена понашања овде то радимо на нивоу прегледача. Ево како:
```javascript
const onKeyDown = function (e) {
@ -106,53 +189,93 @@ const onKeyDown = function (e) {
case 37:
case 39:
case 38:
case 40: // Arrow keys
case 40: // Тастери са стрелицама
case 32:
e.preventDefault();
break; // Space
break; // Размак
default:
break; // do not block other keys
break; // не блокирај друге тастере
}
};
window.addEventListener('keydown', onKeyDown);
```
**Објашњење овог кода за спречавање:**
- **Проверава** одређене кодове тастера који могу изазвати нежељено понашање претраживача
- **Спречава** подразумевану акцију претраживача за стрелице и размакницу
- **Дозвољава** другим тастерима да нормално функционишу
- **Користи** `e.preventDefault()` да заустави уграђено понашање претраживача
**Разумевање кода за спречавање:**
- **Проверава** одређене кодове тастера који могу изазвати непожељно понашање прегледача
- **Спречава** подразумевану акцију прегледача за тастере са стрелицама и размак
- **Дозвољава** другим тастерима да раде нормално
- **Користи** `e.preventDefault()` да заустави уграђено понашање прегледача
## Кретање изазвано игром
### 🔄 **Педагошки провера**
**Разумевање руковања догађајима**: Пре него што пређемо на аутоматско кретање, уверите се да можете:
- ✅ Објаснити разлику између `keydown` и `keyup` догађаја
- ✅ Разумети зашто спречавамо подразумевано понашање прегледача
- ✅ Описати како слушаоци догађаја повезују улаз корисника са логиком игре
- ✅ Препознати који тастери могу ометати контроле игре
Сада ћемо говорити о објектима који се крећу без уноса играча. Размислите о непријатељским бродовима који круже екраном, мецима који лете праволинијски или облацима који се крећу у позадини. Ово аутономно кретање чини ваш свет игре живим чак и када нико не додирује контроле.
**Брзи самотест**: Шта би се десило ако не бисте спречили подразумевано понашање за тастере са стрелицама?
*Одговор: Прегледач би скроловао страницу, ометајући кретање у игри*
Користимо уграђене JavaScript тајмере за ажурирање позиција у редовним интервалима. Овај концепт је сличан начину на који раде клатна у часовницима редовни механизам који покреће доследне, временски одређене акције. Ево како то може изгледати:
**Архитектура догађајног система**: Сада разумете:
- **Слушање на нивоу прозора**: хватање догађаја на нивоу прегледача
- **Особине објекта догађаја**: `key` као низови у односу на `keyCode` бројеве
- **Спречавање подразумеваног**: заустављање непожељних понашања прегледача
- **Условна логика**: реаговање на специфичне комбинације тастера
## Кретање које игра изазива
Хајде сада да причамо о објектима који се крећу без уноса играча. Помислите на непријатељске бродове који крузирају преко екрана, метке који лете право или облаке који плове у позадини. Ово аутономно кретање даје вашем свету у игри осећај живота чак и када нико не дира контроле.
Користимо уграђене JavaScript тајмере да ажурирамо положаје у равномерним интервалима. Овај концепт је сличан како делују точкови на часовницима редован механизам који покреће конзистентне, временски дефинисане акције. Ево колико је једноставно:
```javascript
const id = setInterval(() => {
// Move the enemy on the y axis
// Померите непријатеља по y оси
enemy.y += 10;
}, 100);
```
**Шта овај код за кретање ради:**
**Ово код кретања ради:**
- **Креира** тајмер који се покреће сваких 100 милисекунди
- **Ажурира** y-координату непријатеља за 10 пиксела сваки пут
- **Чува** ID интервала како бисмо га могли зауставити касније ако је потребно
- **Помера** непријатеља надоле на екрану аутоматски
- **Чува** ИД интервала да бисмо могли да га зауставимо касније ако треба
- **Помера** непријатеља надоле по екрану аутоматски
## Петља игре
Ево концепта који све повезује петља игре. Ако би ваша игра била филм, петља игре би била пројектор филма, приказујући кадар за кадром тако брзо да све изгледа као да се глатко креће.
Ево концепта који све повезује петља игре. Ако је ваша игра филм, петља игре би била пројектор који приказује кадар за кадром тако брзо да све изгледа глатко померено.
Свака игра има једну од ових петљи која ради у позадини. То је функција која ажурира све објекте игре, поново црта екран и континуирано понавља овај процес. Ово прати вашег хероја, све непријатеље, било које ласере који лете около целокупно стање игре.
Свакој игри је потребна таква петља која ради у позадини. То је функција која ажурира све објекте игре, поново црта екран и непрестано понавља овај процес. Ово прати вашег јунака, све непријатеље, све ласере који лете целокупно стање игре.
Овај концепт ме подсећа на то како су рани филмски аниматори попут Волта Дизнија морали да поново цртају ликове кадар по кадар како би створили илузију кретања. Ми радимо исто, само кодом уместо оловкама.
Овај концепт ме подсећа на ране филмске аниматоре као Валт Дизнија који су морали да поново цртају ликове кадар по кадар да би створили илузију кретања. Ми радимо исто, само са кодом уместо оловки.
Ево како типична петља игре може изгледати у коду:
Ево како петља игре обично може изгледати у коду:
```mermaid
flowchart TD
A["Почни петљу игре"] --> B["Очисти платно"]
B --> C["Попуни позадину"]
C --> D["Ажурирај објекте игре"]
D --> E["Нацртај хероја"]
E --> F["Нацртај непријатеље"]
F --> G["Нацртај елементе интерфејса"]
G --> H["Чекај следећи фрејм"]
H --> I{Игра ради?}
I -->|Да| B
I -->|Не| J["Заврши игру"]
subgraph "Контрола брзине фрејмова"
K["60 FPS = 16.67ms"]
L["30 FPS = 33.33ms"]
M["10 FPS = 100ms"]
end
style B fill:#ffebee
style D fill:#e1f5fe
style E fill:#e8f5e8
style F fill:#e8f5e8
```
```javascript
const gameLoopId = setInterval(() => {
function gameLoop() {
@ -168,27 +291,27 @@ const gameLoopId = setInterval(() => {
```
**Разумевање структуре петље игре:**
- **Брише** цело платно како би уклонио претходни кадар
- **Попуњава** позадину чврстом бојом
- **Брише** цело платно да уклони претходни кадар
- **Попуњава** позадину једнобојом
- **Црта** све објекте игре на њиховим тренутним позицијама
- **Понавља** овај процес сваких 200 милисекунди како би створио глатку анимацију
- **Управља** брзином кадрова контролишући временске интервале
- **Понавља** овај процес сваких 200 милисекунди да би створио глатку анимацију
- **Управља** брзином кадрова контролом временског интервала
## Наставак свемирске игре
Сада ћемо додати кретање у статичну сцену коју сте претходно направили. Претворићемо је из снимка екрана у интерактивно искуство. Проћи ћемо кроз ово корак по корак како бисмо осигурали да се сваки део надовезује на претходни.
Сада ћемо додати кретање у статичну сцену коју сте претходно изградили. Претворићемо је из снимка екрана у интерактивно искуство. Проћи ћемо корак по корак да би сваки део природно надовезао претходни.
Пребаците код са места где смо стали у претходној лекцији (или започните са кодом из [Почетни код за део II](../../../../6-space-game/3-moving-elements-around/your-work) фасцикле ако вам је потребан нови почетак).
Преузмите код са места где сте стали у претходној лекцији (или почните од [Part II- starter](../../../../6-space-game/3-moving-elements-around/your-work) фолдера ако желите свеж почетак).
**Ево шта данас градимо:**
- **Контроле хероја**: Стрелице ће управљати вашим свемирским бродом по екрану
- **Кретање непријатеља**: Ти ванземаљски бродови ће почети да напредују
**Ово данас градимо:**
- **Контроле јунака**: Тастери са стрелицама ће управљати свемирским бродом по екрану
- **Кретање непријатеља**: Ови ванземаљски бродови ће почети своју офанзиву
Хајде да почнемо са имплементацијом ових функција.
Хајде да почнемо имплементирати ове функције.
## Препоручени кораци
Пронађите датотеке које су креиране за вас у `your-work` подфасцикли. Требало би да садрже следеће:
Пронађите фајлове који су вам направљени у подфолдеру `your-work`. Требало би да садржи следеће:
```bash
-| assets
@ -199,27 +322,27 @@ const gameLoopId = setInterval(() => {
-| package.json
```
Започните свој пројекат у `your-work` фасцикли тако што ћете укуцати:
Започните пројекат у `your-work` фолдеру тако што ћете откуцати:
```bash
cd your-work
npm start
```
**Шта ова команда ради:**
- **Прелази** у директоријум вашег пројекта
**Ово наређење ради:**
- **Превасходи** у вашу радну фасциклу пројекта
- **Покреће** HTTP сервер на адреси `http://localhost:5000`
- **Сервира** ваше датотеке игре како бисте их могли тестирати у претраживачу
- **Сервира** фајлове ваше игре да бисте их тестирали у прегледачу
Горенаведено ће покренути HTTP сервер на адреси `http://localhost:5000`. Отворите претраживач и унесите ту адресу, тренутно би требало да се приказују херој и сви непријатељи; ништа се још не помера!
Горенаведено ће покренути HTTP сервер на адреси `http://localhost:5000`. Отворите прегледач и унесите ту адресу, тренутно би требало да прикаже јунака и све непријатеље; још ништа не помера још увек!
### Додајте код
1. **Додајте посебне објекте** за `hero`, `enemy` и `game object`, они би требало да имају својства `x` и `y`. (Сетите се дела о [Наслеђивању или композицији](../README.md)).
1. **Додајте посебне објекте** за `hero`, `enemy` и `game object`, требало би да имају `x` и `y` особине. (Сетите се дела о [Наслеђивању или композицији](../README.md)).
*САВЕТ* `game object` би требало да буде онај са `x` и `y` и способношћу да се нацрта на платну.
*САВЕТ* `game object` треба да буде онај који има `x` и `y` и могућност да црта себе на платну.
> **Савет**: Почните додавањем нове класе `GameObject` са њеним конструктором дефинисаним као у наставку, а затим је нацртајте на платну:
> **Савет**: Почните са додавањем нове класе `GameObject` са конструктором дефинисаним као испод, и онда је нацртајте на платну:
```javascript
class GameObject {
@ -240,12 +363,48 @@ npm start
```
**Разумевање ове основне класе:**
- **Дефинише** заједничка својства која деле сви објекти игре (позиција, величина, слика)
- **Укључује** заставицу `dead` за праћење да ли објекат треба уклонити
- **Обезбеђује** метод `draw()` који приказује објекат на платну
- **Поставља** подразумеване вредности за сва својства која подкласе могу заменити
- **Дефинише** заједничке особине које деле сви објекти игре (положај, величину, слику)
- **Укључује** речник `dead` који прати да ли објекат треба бити уклоњен
- **Обезбеђује** методу `draw()` која приказује објекат на платну
- **Поставља** подразумеване вредности свих особина које потомци могу да преуређују
Сада, проширите ову `GameObject` класу да бисте креирали `Hero` и `Enemy`:
```mermaid
classDiagram
class GameObject {
+x: number
+y: number
+dead: boolean
+type: string
+width: number
+height: number
+img: Image
+draw(ctx)
}
class Hero {
+speed: number
+type: "Херој"
+width: 98
+height: 75
}
class Enemy {
+type: "Непријатељ"
+width: 98
+height: 50
+setInterval()
}
GameObject <|-- Hero
GameObject <|-- Enemy
class EventEmitter {
+listeners: object
+on(message, listener)
+emit(message, payload)
}
```
Сада проширите ову `GameObject` класу да направите `Hero` и `Enemy`:
```javascript
class Hero extends GameObject {
@ -280,51 +439,51 @@ npm start
**Кључни концепти у овим класама:**
- **Наслеђује** од `GameObject` користећи кључну реч `extends`
- **Позива** родитељски конструктор са `super(x, y)`
- **Поставља** специфичне димензије и својства за сваки тип објекта
- **Позива** родитељски конструктор помоћу `super(x, y)`
- **Поставља** специфичне димензије и особине за сваки тип објекта
- **Имплементира** аутоматско кретање за непријатеље користећи `setInterval()`
2. **Додајте обрађиваче догађаја са тастатуре** за навигацију тастерима (померање хероја горе/доле, лево/десно)
2. **Додајте руковаоце догађаја тастатуре** да управљате навигацијом тастера (померајте јунака горе/доле лево/десно)
*ЗАПАМТИТЕ* то је картезијски систем, горњи леви угао је `0,0`. Такође запамтите да додате код за заустављање *подразумеваног понашања*.
*СЕТИТЕ СЕ* да ради на картезијанском систему, горњи леви угао је `0,0`. Такође сетите се да додате код да зауставите *подразумевано понашање*.
> **Савет**: Направите своју функцију `onKeyDown` и повежите је са прозором:
> **Савет**: Направите функцију `onKeyDown` и прикачите је на прозор:
```javascript
const onKeyDown = function (e) {
console.log(e.keyCode);
// Add the code from the lesson above to stop default behavior
// Додајте код из горње лекције да бисте зауставили подразумевано понашање
switch (e.keyCode) {
case 37:
case 39:
case 38:
case 40: // Arrow keys
case 40: // Стрелице на тастерима
case 32:
e.preventDefault();
break; // Space
break; // Размак
default:
break; // do not block other keys
break; // не блокирајте друге тастере
}
};
window.addEventListener("keydown", onKeyDown);
```
**Шта овај обрађивач догађаја ради:**
- **Слуша** догађаје притискања тастера на целом прозору
- **Бележи** код тастера како би вам помогао да откријете који тастери се притискају
- **Спречава** подразумевано понашање претраживача за стрелице и размакницу
- **Дозвољава** другим тастерима да нормално функционишу
**Ово руковање догађајем ради:**
- **Слуша** `keydown` догађаје на целом прозору
- **Логира** код тастера да вам помогне у отклањању грешака који тастери се притискају
- **Спречава** подразумевано понашање прегледача за тастере са стрелицама и размак
- **Дозвољава** другим тастерима да раде нормално
Проверите конзолу вашег претраживача у овом тренутку и посматрајте притиске тастера који се бележе.
Погледајте конзолу у претраживачу у овом тренутку и пратите који тастери се региструју.
3. **Имплементирајте** [Pub sub pattern](../README.md), ово ће одржати ваш код чистим док настављате са преосталим деловима.
3. **Имплементирајте** [Pub sub образац](../README.md), ово ће вам помоћи да ваш код буде чист док пратите остатак делова.
Образац објављивања-претплате помаже у организовању вашег кода раздвајањем детекције догађаја од обраде догађаја. Ово чини ваш код модуларнијим и лакшим за одржавање.
Publish-Subscribe образац помаже организовати код тако што одваја детекцију догађаја од руковања догађајима. Ово чини код модуларнијим и лакшим за одржавање.
Да бисте урадили овај последњи део, можете:
За овај последњи део можете:
1. **Додајте слушач догађаја** на прозор:
1. **Додати слушаоца догађаја** на прозор:
```javascript
window.addEventListener("keyup", (evt) => {
@ -340,15 +499,152 @@ npm start
});
```
**Шта овај систем догађаја ради:**
- **Детектује** унос са тастатуре и претвара га у прилагођене догађаје игре
- **Одваја** детекцију уноса од лог
- **Креира** мрежу непријатеља користећи угнеждене петље
- **Додељује** слику непријатеља сваком објекту непријатеља
- **Додаје** сваког непријатеља у глобални низ објеката игре
**Овај систем догађаја ради:**
- **Детектује** унос тастатуре и претвара га у прилагођене догађаје игре
- **Раздваја** детекцију уноса од логике игре
- **Олакшава** промену контрола касније без утицаја на код игре
- **Пружа могућност** више система да реагују на исти унос
```mermaid
flowchart TD
A["Унос са тастатуре"] --> B["Слушалац догађаја прозора"]
B --> C["Предајник догађаја"]
C --> D["ДОГАЂАЈУГЕМОРЕ"]
C --> E["ДОГАЂАЈУГМЕОЛЕ"]
C --> F["ДОГАЂАЈУГМЕЕВО"]
C --> G["ДОГАЂАЈУГМЕЕСНО"]
D --> H["Покрет хероја"]
D --> I["Звучни систем"]
D --> J["Визуелни ефекти"]
E --> H
F --> H
G --> H
style A fill:#e1f5fe
style C fill:#e8f5e8
style H fill:#fff3e0
```
2. **Направите класу EventEmitter** да бисте објављивали и примијали поруке:
и додајте функцију `createHero()` да уради сличан процес за хероја.
```javascript
class EventEmitter {
constructor() {
this.listeners = {};
}
on(message, listener) {
if (!this.listeners[message]) {
this.listeners[message] = [];
}
this.listeners[message].push(listener);
}
3. **Додајте константе** и подесите EventEmitter:
```javascript
const Messages = {
KEY_EVENT_UP: "KEY_EVENT_UP",
KEY_EVENT_DOWN: "KEY_EVENT_DOWN",
KEY_EVENT_LEFT: "KEY_EVENT_LEFT",
KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT",
};
let heroImg,
enemyImg,
laserImg,
canvas, ctx,
gameObjects = [],
hero,
eventEmitter = new EventEmitter();
```
**Разумевање ове поставке:**
- **Дефинише** константе порука да би се избегле грешке и олакшала промена кода
- **Декларије** променљиве за слике, контекст платна и стање игре
- **Креира** глобални емитер догађаја за pub-sub систем
- **Иницијализује** низ који садржи све игрове објекте
4. **Иницијализуј игру**
```javascript
function initGame() {
gameObjects = [];
createEnemies();
createHero();
eventEmitter.on(Messages.KEY_EVENT_UP, () => {
hero.y -= 5;
});
eventEmitter.on(Messages.KEY_EVENT_DOWN, () => {
hero.y += 5;
});
eventEmitter.on(Messages.KEY_EVENT_LEFT, () => {
hero.x -= 5;
});
4. **Постави игру петљу**
Рефакториши функцију `window.onload` да иницијализује игру и подеси игру петљу на добар интервал. Такође ћеш додати ласерски зрак:
```javascript
window.onload = async () => {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
heroImg = await loadTexture("assets/player.png");
enemyImg = await loadTexture("assets/enemyShip.png");
laserImg = await loadTexture("assets/laserRed.png");
initGame();
const gameLoopId = setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawGameObjects(ctx);
}, 100);
};
```
**Разумевање подешавања игре:**
- **Чека** да се страница потпуно учита пре него што почне
- **Проналази** canvas елемент и његов 2D рендеринг контекст
- **Учитава** све атрибуте слике асинхроно користећи `await`
- **Покреће** игру петљу која ради на интервалу од 100мс (10 FPS)
- **Брише** и поново црта целу сцену сваки фрејм
5. **Додај код** за померање непријатеља на одређеном интервалу
Рефакториши функцију `createEnemies()` да креира непријатеље и гурне их у нови низ gameObjects класе:
```javascript
function createEnemies() {
const MONSTER_TOTAL = 5;
const MONSTER_WIDTH = MONSTER_TOTAL * 98;
const START_X = (canvas.width - MONSTER_WIDTH) / 2;
const STOP_X = START_X + MONSTER_WIDTH;
for (let x = START_X; x < STOP_X; x += 98) {
for (let y = 0; y < 50 * 5; y += 50) {
const enemy = new Enemy(x, y);
enemy.img = enemyImg;
gameObjects.push(enemy);
}
}
}
```
**Шта креирање непријатеља ради:**
- **Израчунава** позиције да центрира непријатеље на екрану
- **Креира** мрежу непријатеља користећи угнежђене петље
- **Додељује** слику непријатеља сваком објекту непријатеља
- **Додаје** сваког непријатеља у глобални низ game objects
и додај функцију `createHero()` која ради сличан процес за хероја.
```javascript
function createHero() {
hero = new Hero(
@ -359,28 +655,48 @@ npm start
gameObjects.push(hero);
}
```
**Шта ради креирање хероја:**
- **Поставља** хероја на дно центра екрана
- **Додељује** слику хероја објекту хероја
- **Додаје** хероја у низ објеката игре ради рендеровања
и на крају, додајте функцију `drawGameObjects()` да започнете цртање:
**Шта креирање хероја ради:**
- **Поставља** хероја на дно центра екрана
- **Додељује** слику хероја херојском објекту
- **Додаје** хероја у низ game objects ради цртања
и коначно, додај функцију `drawGameObjects()` која почиње цртање:
```javascript
function drawGameObjects(ctx) {
gameObjects.forEach(go => go.draw(ctx));
}
```
**Разумевање функције за цртање:**
- **Итерира** кроз све објекте игре у низу
- **Позива** метод `draw()` за сваки објекат
- **Прослеђује** контекст платна како би објекти могли сами себе да рендерују
Ваши непријатељи би требало да почну да напредују ка вашем свемирском броду хероја!
}
}
**Разумевање функције цртања:**
- **Пролази** кроз све игрове објекте у низу
- **Позива** методу `draw()` на сваком објекту
- **Прослеђује** canvas контекст тако да се објекти могу сами исцртати
### 🔄 **Педагошки преглед**
**Комплетно разумевање система игре**: Потврди своје знање о целокупној архитектури:
- ✅ Како наслеђивање омогућава Хероју и Непријатељу да деле заједничке особине GameObject-а?
- ✅ Зашто пуц/претплата (pub/sub) образац чини твој код одрживијим?
- ✅ Какву улогу игра игра петља у стварању глатке анимације?
- ✅ Како слушаоци догађаја повезују унос корисника са понашањем игровог објекта?
**Интеграција система**: Твоја игра сада приказује:
- **Објектно оријентисани дизајн**: Основне класе са специјализованим наслеђивањем
- **Архитектура заснована на догађајима**: пуц/претплата образац за лабаву повезаност
- **Фрејмворк за анимацију**: Игра петља са доследним ажурирањима кадрова
- **Обрада уноса**: тастатурни догађаји са спречавањем подразумеваног понашања
- **Управљање ресурсима**: учитавање слика и приказ спрајтова
**Професионални обрасци**: Имплементирао си:
- **Одвајање брига**: одвојена логика уноса, логике и рендеровања
- **Полиморфизам**: сви игрови објекти деле заједнички интерфејс цртања
- **Пренос порука**: чиста комуникација између компоненти
- **Управљање ресурсима**: ефикасно руковање спрајтовима и анимацијом
Твоји непријатељи треба да почну напредовање ка твом херојском свемирском броду!
}
}
```
and add a `createHero()` function to do a similar process for the hero.
@ -395,68 +711,190 @@ npm start
gameObjects.push(hero);
}
```
и на крају, додајте функцију `drawGameObjects()` да започнете цртање:
и коначно, додај функцију `drawGameObjects()` која почиње цртање:
```javascript
function drawGameObjects(ctx) {
gameObjects.forEach(go => go.draw(ctx));
}
```
Ваши непријатељи би требало да почну да напредују ка вашем свемирском броду хероја!
Твоји непријатељи треба да почну напредовање ка твом херојском свемирском броду!
---
## Изазов GitHub Copilot Agent 🚀
## GitHub Copilot Agent Изазов 🚀
Ево изазова који ће побољшати изглед ваше игре: додавање граница и глатких контрола. Тренутно ваш херој може да одлети са екрана, а кретање може деловати трзаво.
Ево изазова који ће побољшати завршни утисак твоје игре: додавање граница и глатке контроле. Тренутно, твој јунак може излетети ван екрана, а кретање може да делује сецкано.
**Ваш задатак:** Учините да ваш свемирски брод делује реалистичније имплементирањем граница екрана и флуидног кретања. Ово је слично начину на који НАСА-ини системи контроле лета спречавају свемирске летелице да пређу безбедне оперативне параметре.
**Твој задатак:** Учини да твој свемирски брод делује реалистичније имплементирајући границе екрана и течна кретања. Ово је слично као контролни системи лета НАСА-е који спречавају свемирска возила да пређу границе безбедних радних параметара.
**Шта треба да направите:** Креирајте систем који држи свемирски брод хероја на екрану и учините да контроле буду глатке. Када играчи држе притиснут тастер са стрелицом, брод би требало да клизи континуирано, а не да се креће у дискретним корацима. Размислите о додавању визуелног ефекта када брод достигне границе екрана можда суптилан ефекат који указује на ивицу зоне игре.
**Ево шта треба направити:** Креирај систем који држи хероја унутар екрана и учини контроле глатким. Када играчи држе стрелицу на тастатури, брод треба да клизи континуирано уместо да се креће у корацима. Размисли о визуелним повратним информацијама када брод достигне границе екрана можда суптилан ефекат који указује на ивицу играчког простора.
Сазнајте више о [режиму агента](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
Сазнај више о [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
## 🚀 Изазов
## 🚀 Изазов
Организација кода постаје све важнија како пројекти расту. Можда сте приметили да ваш фајл постаје претрпан функцијама, променљивама и класама које су све измешане. Ово ме подсећа на то како су инжењери који су организовали код за Аполо мисију морали да креирају јасне, одрживе системе на којима су могли да раде различити тимови истовремено.
Организација кода постаје све важнија како пројекти расту. Можда си приметио да ти се датотека препунила функцијама, променљивима и класама које су све измешане. Ово ме подсећа како су инжењери који су организовали код за Аполо мисију морали да направе јасне и одрживе системе на којима би радиле више тимова истовремено.
**Ваш задатак:**
Размишљајте као софтверски архитекта. Како бисте организовали свој код тако да шест месеци од сада, ви (или ваш тимски колега) можете разумети шта се дешава? Чак и ако све остане у једном фајлу за сада, можете креирати бољу организацију:
**Твој задатак:**
Размишљај као софтверски архитекта. Како би организовао свој код да шест месеци од сада, ти (или неки колега) може лако разумети шта се дешава? Чак и ако све остане у једној датотеци за сада, можеш направити бољу организацију:
- **Груписање повезаних функција** заједно са јасним коментарима
- **Одвајање задатака** - одвојите логику игре од рендеровања
- **Коришћење конзистентних назива** за променљиве и функције
- **Креирање модула** или простора имена за организовање различитих аспеката ваше игре
- **Додавање документације** која објашњава сврху сваког главног дела
- **Груписање повезаних функција** уз јасне наслове за секције
- **Одвајање брига** - држи игру логику одвојену од рендеровања
- **Коришћење доследних конвенција именовања** за променљиве и функције
- **Креирање модула** или namespaces да организујеш различите аспекте игре
- **Додавање документације** која објашњава сврху сваке главне секције
**Питања за размишљање:**
- Који делови вашег кода су најтежи за разумевање када се вратите на њих?
- Како бисте могли да организујете свој код да би било лакше за неког другог да допринесе?
- Шта би се десило ако бисте желели да додате нове функције као што су појачања или различите типове непријатеља?
**Питања за размишљање:**
- Који делови твог кода су најтежи за разумевање када им се вратиш?
- Како можеш организовати свој код да би било лакше неком другом да допринесе?
- Шта би се десило ако желиш да додаш нове функције као што су пауер-упс или различити типови непријатеља?
## Квиз након предавања
## Квиз након предавања
[Квиз након предавања](https://ff-quizzes.netlify.app/web/quiz/34)
[Квиз након предавања](https://ff-quizzes.netlify.app/web/quiz/34)
## Преглед и самостално учење
## Ревизија и Самосталан рад
Све градимо од нуле, што је фантастично за учење, али ево једне мале тајне постоје невероватни JavaScript оквири који могу обавити велики део посла уместо вас. Када се осећате удобно са основама које смо покрили, вреди [истражити шта је доступно](https://github.com/collections/javascript-game-engines).
Правили смо све од почетка, што је одлично за учење, али ево мале тајне постоје неки сјајни JavaScript фрејмворци који могу обавити велики део тешког посла за тебе. Када се осећаш комфорно са основама које смо покрили, вреди [истражити шта је доступно](https://github.com/collections/javascript-game-engines).
Размислите о оквирима као о добро опремљеном алату уместо да правите сваки алат ручно. Они могу решити многе изазове организације кода о којима смо говорили, плус понудити функције које би вам одузеле недеље да их сами направите.
Размишљај о фрејмворцима као о добро опремљеној апарату са алатима уместо да ручно правиш сваки алат. Они могу решити многе од изазова организације кода о којима смо говорили, као и понудити функције које би ти требало недељама да направиш сам.
**Ствари које вреди истражити:**
- Како моторе за игре организују код бићете задивљени паметним обрасцима које користе
- Трикови за перформансе који чине да игре на платну раде изузетно глатко
- Модерне JavaScript функције које могу учинити ваш код чистијим и лакшим за одржавање
- Различити приступи управљању објектима игре и њиховим односима
**Ствари вредне истраживања:**
- Како игре мотор организују код бићеш изненађен паметним обрасцима које користе
- Трикове перформанса за глатко извођење игара на canvas
- Модерне JavaScript функције које могу учинити твој код чистијим и лакшим за одржавање
- Различите приступе управљању игровим објектима и њиховим односима
## Задатак
## 🎯 Твој временски оквир за мајсторство анимације игре
[Коментаришите свој код](assignment.md)
```mermaid
timeline
title Напредак у учењу анимације и интеракције у игрицама
section Основе кретања (20 минута)
Принципи анимације: Анимација заснована на кадровима
: Ажурирање позиције
: Координатни системи
: Глатко кретање
section Системи догађаја (25 минута)
Кориснички унос: Обрада тастатурних догађаја
: Спречавање подразумеваног понашања
: Особине објекта догађаја
: Слушање на нивоу прозора
section Архитектура игрице (30 минута)
Дизајн објеката: Обрасци наслеђивања
: Креирање базне класе
: Специјализована понашања
: Полиморфни интерфејси
section Обрасци комуникације (35 минута)
Имплементација Pub/Sub: Изворници догађаја
: Константе порука
: Слаба повезаност
: Интеграција система
section Мастерство главне петље (40 минута)
Системи у реалном времену: Контрола броја кадрова
: Циклус ажурирања/приказа
: Управљање стањем
: Оптимизација перформанси
section Напредне технике (45 минута)
Професионалне функције: Детекција судара
: Симулација физике
: Стате машине
: Системи компоненти
section Концепти играчких мотора (1 недеља)
Разумевање оквира: Ентитет-компонент системи
: Графикони сцена
: Пипелини ресурса
: Профилисање перформанси
section Вештине продукције (1 месец)
Професионални развој: Организација кода
: Тимска сарадња
: Стратегије тестирања
: Оптимизација имплементације
```
### 🛠️ Резиме твог алата за развој игара
Након завршетка ове лекције, сада си савладао:
- **Принципе анимације**: померање засновано на фрејмовима и глатке транзиције
- **Програмирање засновано на догађајима**: руковање уносом са тастатуре са прописним управљањем догађајима
- **Објектно оријентисани дизајн**: наслеђивање и полиморфни интерфејси
- **Обрасце комуникације**: пуц/претплата архитектура за одржив код
- **Архитектуру игре петље**: ажурирања у реалном времену и циклуси рендеровања
- **Системи уноса**: мапирање корисничке контроле са спречавањем подразумеваног понашања
- **Управљање ресурсима**: учитавање спрајтова и ефикасне технике рендеровања
### ⚡ **Шта можеш учинити следећих 5 минута**
- [ ] Отвори конзолу претраживача и пробај `addEventListener('keydown', console.log)` да видиш догађаје тастатуре
- [ ] Креирај прост div елемент и помери га користећи тастере са стрелицама
- [ ] Испробај `setInterval` за креирање континуираног кретања
- [ ] Покушај да спречиш подразумевано понашање коришћењем `event.preventDefault()`
### 🎯 **Шта можеш постићи ове сате**
- [ ] Заврши квиз након лекције и разумиј програмирање засновано на догађајима
- [ ] Направи покретног хероја свемирски брод са потпуном тастатурном контролом
- [ ] Имплементирај глатке паттерне кретања непријатеља
- [ ] Додај границе да спречиш да игрови објекти изађу ван екрана
- [ ] Креирај основну детекцију судара између игрових објеката
### 📅 **Твој недељни пут анимације**
- [ ] Заврши комплетну свемирску игру са уређеним кретањем и интеракцијама
- [ ] Додај напредне моделе кретања као што су криве, убрзања и физика
- [ ] Имплементирај глатке транзиције и easing функције
- [ ] Креирај ефекте честица и системе визуелних повратних информација
- [ ] Оптимизуј перформансе игре за глатку игру од 60fps
- [ ] Додај мобилне додирне контроле и одзивни дизајн
### 🌟 **Твој месечни интерективни развој**
- [ ] Направи сложене интерактивне апликације са напредним системима анимације
- [ ] Научи анимацијске библиотеке као што су GSAP или направи свој анимацијски мотор
- [ ] Доприноси open source пројектима за развој игара и анимације
- [ ] Савладај оптимизацију перформанси за графички захтевне апликације
- [ ] Креирај едукативни садржај о развоју игара и анимацијама
- [ ] Направи портфолио који приказује напредне вештине интерактивног програмирања
**Примена у стварном свету**: Твоје вештине анимације игре директно се примењују на:
- **Интерактивне веб апликације**: динамички дашборди и интерфејси у реалном времену
- **Визуелизацију података**: анимирани графикони и интерактивна графика
- **Едукативни софтвер**: интерактивне симулације и алати за учење
- **Мобилни развој**: игре на додир и руковање гестовима
- **Десктоп апликације**: Electron апликације са глатким анимацијама
- **Веб анимације**: CSS и JavaScript анимацијске библиотеке
**Професионалне вештине стечене**: Сада можеш:
- **Архитектонски** креирати системе засноване на догађајима који се могу скалирати са сложеношћу
- **Имплементирати** глатке анимације користећи математичке принципе
- **Дебаговати** сложене интеракционе системе коришћењем развојних алата претраживача
- **Оптимизовати** перформансе игре за различите уређаје и претраживаче
- **Дизајнирати** одрживе структуре кода користећи проверене обрасце
**Концепти развоја игре које си савладао**:
- **Управљање фрејмрејтом**: разумевање FPS и контроле тајминга
- **Обрада уноса**: универзални системи тастатуре и догађаја
- **Животни циклус објекта**: обрасци креирања, ажурирања и уништења
- **Синхронизација стања**: одржавање стања игре конзистентним преко фрејмова
- **Архитектура догађаја**: одвојена комуникација између игрових система
**Следећи ниво**: Спреман си да додаш детекцију судара, системе бодовања, звучне ефекте или да истражиш модерне фрејмворке као што су Phaser или Three.js!
🌟 **Постигнуће откључано**: Направио си комплетан интерактивни систем игре са професионалним архитектонским обрасцима!
## Задатак
[Коментариши свој код](assignment.md)
---
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Ограничење одговорности**:
Овај документ је преведен уз помоћ АИ сервиса за превођење [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде што прецизнији, молимо имајте у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешна тумачења која могу произаћи из употребе овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -1,36 +1,103 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4b1d441cfd31924084956000c0fee5a5",
"translation_date": "2025-10-24T23:41:34+00:00",
"original_hash": "039b4d8ce65f5edd82cf48d9c3e6728c",
"translation_date": "2026-01-07T07:53:52+00:00",
"source_file": "6-space-game/4-collision-detection/README.md",
"language_code": "sr"
}
-->
# Направите свемирску игру, део 4: Додавање ласера и детекција судара
# Направи свемирску игру део 4: Додавање ласера и откривање судара
```mermaid
journey
title Ваше путовање детекције судара
section Основе физике
Разумети правоугаонике: 3: Студент
Учити математику пресека: 4: Студент
Савладати координатне системе: 4: Студент
section Механика игре
Имплементирати испаљивање ласера: 4: Студент
Додати животни циклус објекта: 5: Студент
Креирати правила судара: 5: Студент
section Интеграција система
Изградити детекцију судара: 5: Студент
Оптимизовати перформансе: 5: Студент
Тестирати системе интеракције: 5: Студент
```
## Квиз пре предавања
[Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/35)
Сетите се тренутка у "Ратовима звезда" када су Лукови протонски торпеда погодили издувни порт Звезде смрти. Та прецизна детекција судара променила је судбину галаксије! У играма, детекција судара функционише на исти начин - одређује када објекти међусобно делују и шта се дешава након тога.
У овој лекцији, додаћете ласерско оружје својој свемирској игри и имплементирати детекцију судара. Баш као што планери мисија НАСА-е израчунавају путање свемирских летелица како би избегли отпад, научићете како да детектујете када се објекти у игри укрштају. Разложићемо ово на управљиве кораке који се надовезују један на други.
На крају, имаћете функционалан борбени систем где ласери уништавају непријатеље, а судари покрећу догађаје у игри. Ови исти принципи детекције судара користе се у свему, од симулација физике до интерактивних веб интерфејса.
✅ Урадите мало истраживање о првој компјутерској игри икада написаној. Која је била њена функционалност?
Размислите о тренутку у Ратови звезда када је Лукова протонска торпеда погодила издувни отвор Звезде смрти. Та прецизна детекција судара променила је судбину галаксије! У играма, откривање судара ради на исти начин - одређује када се објекти додирују и шта се затим дешава.
У овом лекцији ћете додати ласерске оружје у вашу свемирску игру и имплементирати детекцију судара. Баш као што планери мисија НАСА-е израчунавају трајекторије свемирских летелица да би избегли отпад, научићете како да детектујете када се објекти у игри преклапају. Ово ћемо разбити у управљиве кораке који се надограђују један на други.
До краја, имаћете функционишући борбени систем у ком ласери уништавају непријатеље и сударања покрећу догађаје у игри. Исте основе детекције судара користе се у свему, од фізичких симулација до интерактивних веб интерфејса.
```mermaid
mindmap
root((Детекција судара))
Physics Concepts
Rectangle Boundaries
Intersection Testing
Coordinate Systems
Separation Logic
Game Objects
Laser Projectiles
Enemy Ships
Hero Character
Collision Zones
Lifecycle Management
Object Creation
Movement Updates
Destruction Marking
Memory Cleanup
Event Systems
Keyboard Input
Collision Events
Game State Changes
Audio/Visual Effects
Performance
Efficient Algorithms
Frame Rate Optimization
Memory Management
Spatial Partitioning
```
✅ Урадите мало истраживање о првој икада написаној рачунарској игри. Која је била њена функционалност?
## Детекција судара
Детекција судара функционише као сензори близине на лунарном модулу Аполо - стално проверава растојања и покреће упозорења када се објекти превише приближе. У играма, овај систем одређује када објекти међусобно делују и шта би требало да се догоди након тога.
Детекција судара ради као сензори близине на аполоновом лунарном модулу - стално проверава растојања и покреће упозорења када се објекти превише приближе. У играма, овај систем одређује када се објекти додирују и шта треба да се деси даље.
Приступ који ћемо користити третира сваки објекат у игри као правоугаоник, слично као што системи контроле ваздушног саобраћаја користе поједностављене геометријске облике за праћење авиона. Овај метод са правоугаоницима може изгледати основно, али је рачунарски ефикасан и добро функционише за већину сценарија у игри.
Приступ који ћемо користити третира сваки објекат у игри као правоугаоник, слично као што системи за контролу ваздушног саобраћаја користе поједностављене геометријске облике да прате авионе. Овај правоугаони метод може изгледати једноставно, али је рачунски ефикасан и добро функционише за већину сценарија у игри.
### Представљање правоугаоника
### Репрезентација правоугаоника
Сваки објекат у игри треба координатне границе, слично као што је ровер Марс Патхфиндер мапирао своју локацију на површини Марса. Ево како дефинишемо те координате граница:
Сваком објекту у игри су потребне координате граница, слично као што ровера Марс Патхфиндер мапира позицију на површини Марса. Ево како дефинишемо ове координате граница:
```mermaid
flowchart TD
A["🎯 Игра Објекат"] --> B["📍 Позиција (x, y)"]
A --> C["📏 Димензије (ширина, висина)"]
B --> D["Горе: y"]
B --> E["Лево: x"]
C --> F["Доле: y + висина"]
C --> G["Десно: x + ширина"]
D --> H["🔲 Правоугаоник Оквир"]
E --> H
F --> H
G --> H
H --> I["Спремно за Детекцију Судара"]
style A fill:#e3f2fd
style H fill:#e8f5e8
style I fill:#fff3e0
```
```javascript
rectFromGameObject() {
return {
@ -42,16 +109,38 @@ rectFromGameObject() {
}
```
**Хајде да ово разложимо:**
- **Горња ивица**: То је само место где ваш објекат вертикално почиње (његова y позиција)
- **Лева ивица**: Место где хоризонтално почиње (његова x позиција)
- **Доња ивица**: Додајте висину на y позицију - сада знате где се завршава!
- **Десна ивица**: Додајте ширину на x позицију - и добили сте комплетну границу
**Разложимо ово:**
- **Горња ивица**: То је само место где објекат почиње вертикално (његова y позиција)
- **Лева ивица**: Где почиње хоризонтално (његова x позиција)
- **Доња ивица**: Додајте висину на y позицију сад знате где се завршава!
- **Десна ивица**: Додајте ширину на x позицију и добијате пуну границу
### Алгоритам за пресек
### Алгоритам пресека
Детекција пресека правоугаоника користи логику сличну оној коју телескоп Хабл користи да утврди да ли се небески објекти преклапају у његовом видном пољу. Алгоритам проверава раздвајање:
Откривање пресека правоугаоника користи логику сличну оној како Хабл свемирски телескоп одређује да ли се небески објекти преклапају у свом видном пољу. Алгоритам проверава раздвајање:
```mermaid
flowchart LR
A["Правоугаоник 1"] --> B{"Тестови раздвајања"}
C["Правоугаоник 2"] --> B
B --> D["Лево Р2 > десно Р1?"]
B --> E["Десно Р2 < лево Р1?"]
B --> F["Горе Р2 > дно Р1?"]
B --> G["Дно Р2 < горе Р1?"]
D --> H{"Има ли истинито?"}
E --> H
F --> H
G --> H
H -->|Да| I["❌ Без судара"]
H -->|Не| J["✅ Судар откривен"]
style B fill:#e3f2fd
style I fill:#ffebee
style J fill:#e8f5e8
```
```javascript
function intersectRect(r1, r2) {
return !(r2.left > r1.right ||
@ -61,60 +150,105 @@ function intersectRect(r1, r2) {
}
```
**Тест раздвајања функционише као радарски системи:**
- Да ли је правоугаоник 2 потпуно десно од правоугаоника 1?
- Да ли је правоугаоник 2 потпуно лево од правоугаоника 1?
- Да ли је правоугаоник 2 потпуно испод правоугаоника 1?
- Да ли је правоугаоник 2 потпуно изнад правоугаоника 1?
**Тест раздвајања ради као радарски системи:**
- Да ли се правоугаоник 2 у потпуности налази десно од правоугаоника 1?
- Да ли се правоугаоник 2 у потпуности налази лево од правоугаоника 1?
- Да ли се правоугаоник 2 у потпуности налази испод правоугаоника 1?
- Да ли се правоугаоник 2 у потпуности налази изнад правоугаоника 1?
Ако ниједан од ових услова није тачан, правоугаоници морају бити преклопљени. Овај приступ одражава начин на који оператери радара одређују да ли су два авиона на безбедним растојањима.
Ако ниједан од ових услова није тачан, правоугаоници морају бити преклопљени. Овај приступ одсликава како радари одређују да ли су два авиона на безбедној удаљености.
## Управљање животним циклусима објеката
## Управљање животним циклусом објекта
Када ласер погоди непријатеља, оба објекта морају бити уклоњена из игре. Међутим, брисање објеката током петље може изазвати падове - лекција научена на тежи начин у раним компјутерским системима као што је Аполо рачунар за навигацију. Уместо тога, користимо приступ "означи за брисање" који безбедно уклања објекте између кадрова.
Када ласер погоди непријатеља, оба објекта треба да буду уклоњена из игре. Међутим, брисање објеката током петље може изазвати падове лекција научена на тежи начин у раним рачунарским системима као што је Apollo Guidance Computer. Уместо тога, користимо приступ „обележи за брисање“ који безбедно уклања објекте између кадрова.
Ево како означавамо нешто за уклањање:
```mermaid
stateDiagram-v2
[*] --> Active: Објекат Креиран
Active --> Collided: Судар Детектиран
Collided --> MarkedDead: Постави мртав = тачно
MarkedDead --> Filtered: Следећи Фрејм
Filtered --> [*]: Објекат Уклоњен
Active --> OutOfBounds: Напушта Екран
OutOfBounds --> MarkedDead
note right of MarkedDead
Безбедно за наставак
тренутни фрејм
end note
note right of Filtered
Објекти уклоњени
између фрејмова
end note
```
Ево како обележавамо нешто за уклањање:
```javascript
// Mark object for removal
// Обележи објекат за уклањање
enemy.dead = true;
```
**Зашто овај приступ функционише:**
- Означавамо објекат као "мртав", али га не бришемо одмах
- Ово омогућава тренутном кадру игре да се безбедно заврши
- Нема падова због покушаја коришћења нечега што је већ уклоњено!
- Обележавамо објекат као „мртав“, али га одмах не брисамо
- Ово дозвољава да тренутни фрејм у игри безбедно заврши
- Нема падања због коришћења нечега што више не постоји!
Затим филтрирамо означене објекте пре следећег циклуса рендеровања:
Затим филтрирамо обележене објекте пре наредног циклуса приказа:
```javascript
gameObjects = gameObjects.filter(go => !go.dead);
```
**Шта ради ово филтрирање:**
- Креира нову листу само са "живим" објектима
- Избацује све што је означено као мртво
- Одржава вашу игру да ради глатко
- Спречава нагомилавање меморије од уништених објеката
**Ова филтрација:**
- Креира свежу листу са само „живим“ објектима
- Одустаје од свега што је обележено као мртво
- Одржава вашу игру без проблема
- Спечава накупљање разорених објеката и превелике потрошње меморије
## Имплементација механике ласера
## Имплементирање ласерске механике
Ласерски пројектили у играма функционишу на истом принципу као фотонски торпеда у "Звезданим стазама" - то су дискретни објекти који путују праволинијски док не ударе у нешто. Сваки притисак на размакницу ствара нови ласерски објекат који се креће преко екрана.
Ласерски пројектили у играма раде по истом принципу као фотонска торпеда у Стар Треку то су дискретни објекти који путују правцем линије док не погоде нешто. Свако притискање тастера размак (spacebar) креира нови ласерски објекат који се креће преко екрана.
Да би ово функционисало, потребно је координисати неколико различитих делова:
Да би ово функционисало, морамо усагласити неколико делова:
**Кључне компоненте за имплементацију:**
- **Креирање** ласерских објеката који се појављују из позиције хероја
- **Обрада** уноса са тастатуре за покретање креирања ласера
- **Управљање** кретањем ласера и животним циклусом
- **Имплементација** визуелног приказа ласерских пројектила
**Кључни делови за имплементацију:**
- **Креирај** ласерске објекте који се стварају са позициију хероја
- **Обрадити** унос са тастатуре за покретање креирања ласера
- **Управљање** кретањем и животним циклусом ласера
- **Имплементирати** визуелни приказ ласерских пројектила
## Имплементација контроле брзине пуцања
## Имплементирање контроле учесталости пуцања
Неограничене брзине пуцања би преоптеретиле мотор игре и учиниле игру превише лаком. Прави оружани системи се суочавају са сличним ограничењима - чак су и фазери USS Enterprise-а морали да се напуне између пуцања.
Неограничена учесталост пуцања би преплавила игру и учинила игру превише лаким. Прави оружани системи имају слична ограничења чак су и фазери USS Enterprises требали време за пуњење између пуцњева.
Имплементираћемо систем хлађења који спречава прекомерно пуцање, а истовремено одржава одзивне контроле:
Имплементираћемо систем хлађења који спречава спамовање док одржава контроле одзивним:
```mermaid
sequenceDiagram
participant Player
participant Weapon
participant Cooldown
participant Game
Player->>Weapon: Притисни razmak
Weapon->>Cooldown: Провери да ли је cool
alt Weapon је спремно
Cooldown->>Weapon: cool = true
Weapon->>Game: Креирај ласер
Weapon->>Cooldown: Покрени нови cooldown
Cooldown->>Cooldown: cool = false
Note over Cooldown: Чекај 500мс
Cooldown->>Cooldown: cool = true
else Weapon се хлади
Cooldown->>Weapon: cool = false
Weapon->>Player: Нема акције
end
```
```javascript
class Cooldown {
constructor(time) {
@ -132,42 +266,58 @@ class Weapon {
fire() {
if (!this.cooldown || this.cooldown.cool) {
// Create laser projectile
// Креирај ласерски пројектил
this.cooldown = new Cooldown(500);
} else {
// Weapon is still cooling down
// Даље хлађење оружја није завршено
}
}
}
```
**Како систем хлађења функционише:**
- Када се креира, оружје постаје "вруће" (још не може да пуца)
- Након периода чекања, постаје "хладно" (спремно за пуцање)
- Пре пуцања, проверавамо: "Да ли је оружје хладно?"
- Ово спречава прекомерно кликање, а истовремено одржава одзивност контрола
**Како ради хлађење:**
- Када се створи, оружје је „вруће“ (не може још пуцати)
- Након истека времена хлађења постаје „хладно“ (спремно за пуцање)
- Пре пуцања проверавамо: „Да ли је оружје хладно?“
- Ово спречава кликање убрзано, а контроле остају одзивне
✅ Погледајте лекцију 1 у серији свемирских игара да се подсетите на системе хлађења.
✅ Подсетите се лекције 1 из серијала свемирских игара за појам о хлађењима.
## Изградња система за детекцију судара
## Прављење система детекције судара
Проширићете постојећи код своје свемирске игре како бисте креирали систем за детекцију судара. Као аутоматизовани систем за избегавање судара Међународне свемирске станице, ваша игра ће континуирано пратити позиције објеката и реаговати на њихове пресеке.
Проширићете свој постојећи код свемирске игре да бисте направили систем за детекцију судара. Као аутоматизовани систем за избегавање судара на Међународној Свемирској Станици, ваша игра ће стално пратити позиције објеката и реаговати на пресеке.
Полазећи од кода из претходне лекције, додаћете детекцију судара са специфичним правилима која регулишу интеракције објеката.
Почевши од кода из претходне лекције, додаш детекцију судара са одређеним правилима која регулишу интеракције објеката.
> 💡 **Савет**: Спрайт ласера је већ укључен у вашу фасциклу са ресурсима и референциран у вашем коду, спреман за имплементацију.
> 💡 **Про савет**: Ласерски спрајт је већ укључен у ваш фолдер с ресурсима и реферисан у коду, спреман за имплементацију.
### Правила судара која треба имплементирати
**Механике игре које треба додати:**
1. **Ласер погађа непријатеља**: Објекат непријатеља се уништава када га погоди ласерски пројектил
2. **Ласер погађа границу екрана**: Ласер се уклања када стигне до горње ивице екрана
3. **Судар непријатеља и хероја**: Оба објекта се уништавају када се укрсте
4. **Непријатељ стиже до дна**: Услов за крај игре када непријатељи стигну до дна екрана
**Механика игре која се додаје:**
1. **Ласер погађа непријатеља**: Непријатељски објекат се уништава када га погоди ласерски пројектил
2. **Ласер погађа ивицу екрана**: Ласер се уклања када достигне горњу ивицу екрана
3. **Судар непријатеља и хероја**: Објекти се уништавају када се преклопе
4. **Непријатељ досегне дно**: Услов за крај игре када непријатељи стигну до дна екрана
### 🔄 **Педагошки преглед**
**Основе детекције судара**: Пре имплементације, уверите се да разумете:
- ✅ Како границе правоугаоника дефинишу зоне судара
- ✅ Зашто је тест раздвајања ефикаснији од израчунавања пресека
- ✅ Значај управљања животним циклусом објекта у свим петљама игре
- ✅ Како догађајно оријентисани системи координишу реакције на сударе
**Брзи самотест**: Шта би се десило ако бисте одмах брисали објекте уместо да их обележите?
*Одговор: Брисање током петље може изазвати падове или прескакање објеката у итерацији*
**Физичко разумевање**: Сада разумете:
- **Координатне системе**: Како положај и димензије праве границе
- **Логику пресека**: Математичке принципе иза детекције судара
- **Оптимизацију перформанси**: Зашто су ефикасни алгоритми важни у реалном времену
- **Управљање меморијом**: Безбедне шеме животног циклуса објеката
## Постављање развојног окружења
Добре вести - већ смо припремили већину основа за вас! Сви ваши ресурси за игру и основна структура чекају у подфасцикли `your-work`, спремни да додате кул функције за детекцију судара.
Добре вести већ смо поставили већину основа за вас! Сви ваши ресурси игре и основна структура чекају у подфолдеру `your-work`, спремни да додате кул функције детекције судара.
### Структура пројекта
@ -181,35 +331,60 @@ class Weapon {
-| package.json
```
**Разумевање структуре фолдера:**
- **Садржи** све слике спрайтова потребне за објекте у игри
- **Укључује** главни HTML документ и JavaScript датотеку апликације
- **Обезбеђује** конфигурацију пакета за локални сервер за развој
**Разумевање структуре фајлова:**
- **Садржи** све слике спрајтова потребне за објекте у игри
- **Укључује** главни HTML документ и JavaScript апликациони фајл
- **Обезбеђује** конфигурацију пакета за локални развојни сервер
### Покретање локалног сервера за развој
### Покретање развојног сервера
Идите у фасциклу свог пројекта и покрените локални сервер:
Идите у свој фолдер пројекта и покрените локални сервер:
```bash
cd your-work
npm start
```
**Ова секвенца команди:**
- **Прелази** у фасциклу вашег радног пројекта
**Овај низ команди:**
- **Премешта** у радни директоријум вашег пројекта
- **Покреће** локални HTTP сервер на `http://localhost:5000`
- **Сервира** ваше датотеке игре за тестирање и развој
- **Омогућава** развој уживо са аутоматским освежавањем
- **Сервира** ваше фајлове за игру ради тестирања и развоја
- **Омогућава** живи развој са аутоматским освежавањем
Отворите свој претраживач и идите на `http://localhost:5000` да бисте видели тренутно стање своје игре са херојем и непријатељима приказаним на екрану.
Отворите прегледач и идите на `http://localhost:5000` да бисте видели тренутно стање ваше игре са приказаним херојем и непријатељима.
### Корак по корак имплементација
### Имплементација корак по корак
Као систематски приступ који је НАСА користила за програмирање свемирског брода Војаџер, имплементираћемо детекцију судара методично, градећи сваки компонент корак по корак.
Као систематски приступ који је НАСА користила за програмирање свемирске летелице Voyager, имплементираћемо детекцију судара метдолошки, градећи сваки део корак по корак.
#### 1. Додајте границе судара правоугаоника
```mermaid
flowchart TD
A["1. Ограничавајући Правоугаоник"] --> B["2. Детекција Пресецања"]
B --> C["3. Ласерски Систем"]
C --> D["4. Руковање Догађајима"]
D --> E["5. Правила Судара"]
E --> F["6. Систем Хлађења"]
G["Границе Објекта"] --> A
H["Физички Алгоритам"] --> B
I["Креирање Пројектила"] --> C
J["Унос Са Тастатуре"] --> D
K["Логика Игре"] --> E
L["Ограничење Брзине"] --> F
F --> M["🎮 Комплетна Игра"]
style A fill:#e3f2fd
style B fill:#e8f5e8
style C fill:#fff3e0
style D fill:#f3e5f5
style E fill:#e0f2f1
style F fill:#fce4ec
style M fill:#e1f5fe
```
#### 1. Додавање граница правоугаоника за сударе
Прво, научимо наше објекте у игри како да опишу своје границе. Додајте овај метод у своју класу `GameObject`:
Прво, научимо наше објекте у игри како да описују своје границе. Додајте ову методу у класу `GameObject`:
```javascript
rectFromGameObject() {
@ -222,15 +397,15 @@ rectFromGameObject() {
}
```
**Овај метод постиже:**
**Ова метода остварује:**
- **Креира** објекат правоугаоника са прецизним координатама граница
- **Израчунава** доње и десне ивице користећи позицију плус димензије
- **Израчунава** доњу и десну ивицу коришћењем позиције плус димензије
- **Враћа** објекат спреман за алгоритме детекције судара
- **Обезбеђује** стандардизован интерфејс за све објекте у игри
#### 2. Имплементирајте детекцију пресека
#### 2. Имплементирање детекције пресека
Сада креирајмо нашег детектива за сударе - функцију која може утврдити када се два правоугаоника преклапају:
Сада направимо наш детектив судара функцију која каже када се два правоугаоника преклапају:
```javascript
function intersectRect(r1, r2) {
@ -243,19 +418,19 @@ function intersectRect(r1, r2) {
}
```
**Овај алгоритам функционише тако што:**
**Овај алгоритам ради тако што:**
- **Тестира** четири услова раздвајања између правоугаоника
- **Враћа** `false` ако је било који услов раздвајања тачан
- **Указује** на судар када не постоји раздвајање
- **Користи** логику негације за ефикасно тестирање пресека
- **Враћа** `false` ако било који услов раздвајања важи
- **Индицира** судар када нема раздвајања
- **Користи** негацију за ефикасније тестирање пресека
#### 3. Имплементација система за пуцање ласера
#### 3. Имплементација ласерског система пуцања
Ево где ствари постају узбудљиве! Поставимо систем за пуцање ласера.
Овде почиње узбуђење! Подесимо систем пуцања ласера.
##### Константе порука
##### Константе за поруке
Прво, дефинишимо неке типове порука како би различити делови наше игре могли да комуницирају:
Прво, дефинишемо неке типове порука да би различити делови наше игре могли комуницирати:
```javascript
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
@ -264,13 +439,13 @@ COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
```
**Ове константе обезбеђују:**
- **Стандартизацију** назива догађаја широм апликације
- **Омогућавају** конзистентну комуникацију између система игре
- **Спречавају** грешке у регистрацији обрађивача догађаја
- **Стандардизују** имена догађаја у целој апликацији
- **Омогућују** доследну комуникацију између система игре
- **Спречавају** грешке у укуцавању при регистрацији руку на догађаје
##### Обрада уноса са тастатуре
Додајте детекцију притиска на размакницу у свој слушалац догађаја за тастатуру:
Додајте детекцију притиска тастера размак (space) у слушаоца тастера:
```javascript
} else if(evt.keyCode === 32) {
@ -278,10 +453,10 @@ COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
}
```
**Овај обрађивач уноса:**
- **Детектује** притиске на размакницу користећи keyCode 32
- **Емитује** стандардизовану поруку догађаја
- **Омогућава** раздвојену логику пуцања
**Овај хендлер уноса:**
- **Детектује** притиске на space key (код 32)
- **Емитује** стандардизовани догађај
- **Омогућује** одвојену логику пуцања
##### Постављање слушаоца догађаја
@ -296,11 +471,11 @@ eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
```
**Овај слушалац догађаја:**
- **Реагује** на догађаје притиска на размакницу
- **Проверава** статус хлађења за пуцање
- **Реагује** на догађаје притиска space тастера
- **Проверва** статус хлађења оружја
- **Покреће** креирање ласера када је дозвољено
Додајте обраду судара за интеракције ласера и непријатеља:
Додајте обраду судара између ласера и непријатеља:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -311,12 +486,12 @@ eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
**Овај обрађивач судара:**
- **Прима** податке о догађају судара са оба објекта
- **Означава** оба објекта за уклањање
- **Обележава** оба објекта за уклањање
- **Обезбеђује** правилно чишћење након судара
#### 4. Креирајте класу Laser
#### 4. Креирање Ласер класе
Имплементирајте ласерски пројектил који се креће нагоре и управља својим животним циклусом:
Имплементирајте ласерски пројектил који се креће узбрдо и управља својим животним циклусом:
```javascript
class Laser extends GameObject {
@ -339,23 +514,23 @@ class Laser extends GameObject {
}
```
**Ова имплементација класе:**
- **Проширује** GameObject да наследи основну функционалност
- **Поставља** одговарајуће димензије за спрайт ласера
- **Креира** аутоматско кретање нагоре користећи `setInterval()`
- **Обрађује** самоуништење када стигне до врха екрана
- **Управља** сопственим временом анимације и чишћењем
**Ова класа:**
- **Проширује** GameObject да би наследила основне функције
- **Поставља** одговарајуће димензије за ласерски спрајт
- **Креира** аутоматско кретање горе користећи `setInterval()`
- **Саморазграђује се** када досегне врх екрана
- **Управља** својим анимацијским тајмингом и чишћењем
#### 5. Имплементација система за детекцију судара
#### 5. Имплементирање система за детекцију судара
Креирајте свеобухватну функцију за детекцију судара:
Направите комплетну функцију за детекцију судара:
```javascript
function updateGameObjects() {
const enemies = gameObjects.filter(go => go.type === 'Enemy');
const lasers = gameObjects.filter(go => go.type === "Laser");
// Test laser-enemy collisions
// Тестирање судара ласера са непријатељем
lasers.forEach((laser) => {
enemies.forEach((enemy) => {
if (intersectRect(laser.rectFromGameObject(), enemy.rectFromGameObject())) {
@ -367,22 +542,22 @@ function updateGameObjects() {
});
});
// Remove destroyed objects
// Уклањање уништених објеката
gameObjects = gameObjects.filter(go => !go.dead);
}
```
**Овај систем за детекцију судара:**
- **Филтрира** објекте игре по типу ради ефикасног тестирања
- **Тестира** сваки ласер против сваког непријатеља за пресеке
**Овај систем судара:**
- **Филтрира** објекте по типу ради ефикаснијег тестирања
- **Тестира** сваки ласер за сваким непријатељем у претрази пресека
- **Емитује** догађаје судара када се пресек детектује
- **Чисти** уништене објекте након обраде судара
- **Чисти** уништене објекте након процесирања судара
> ⚠️ **Важно**: Додајте `updateGameObjects()` у главну петљу игре у `window.onload` да бисте омогућили детекцију судара.
> ⚠️ **Важно**: Додајте `updateGameObjects()` у главну петљу игре у `window.onload` да омогућите детекцију судара.
#### 6. Додајте систем хлађења у класу Hero
#### 6. Додавање система хлађења у класу Hero
Унапредите класу Hero са механиком пуцања и ограничењем брзине:
Побољшајте класу Hero механиком пуцања и ограничењем учесталости:
```javascript
class Hero extends GameObject {
@ -414,16 +589,188 @@ class Hero extends GameObject {
}
```
**Разумевање унапређене класе Hero:**
- **Иницијализује** тајмер хлађења на нулу (спреман за пуцање)
- **Креира** ласерске објекте позициониране изнад брода хероја
- **Поставља** период хлађења да спречи прекомерно пуцање
- **Смањује** тајмер хлађења користећи ажурирања заснована на интервалу
- **Обезбеђује** проверу статуса пуцања кроз метод `canFire()`
**Разумевање проширене класе Hero:**
- **Иницијализује** тајмер хлађења на нулу (спремно за пуцање)
- **Креира** ласерске објекте позициониране изнад свемирског брода хероја
- **Поставља** период хлађења да спречи брзо пуцање
- **Смањује** тајмер хлађења интервалним ажурирањима
- **Обезбеђује** проверу статуса пуцања кроз методу `canFire()`
### 🔄 **Педагошки преглед**
**Потпуно разумевање система**: Потврдите своје знање о систему судара:
- ✅ Како границе правоугаоника омогућавају ефикасну детекцију судара?
- ✅ Зашто је управљање животним циклусом објеката критично за стабилност игре?
- ✅ Како систем хлађења спречава проблеме са перформансама?
- ✅ Коју улогу игра догађајно оријентисана архитектура у управљању сударима?
**Интеграција система**: Ваша детекција судара показује:
- **Математску прецизност**: Алгоритми за пресецање правоугаоника
- **Оптимизацију перформанси**: Ефикасне шеме тестирања судара
- **Управљање меморијом**: Безбедно креирање и уништавање објеката
- **Координацију догађаја**: Децоуплинг комуникације система
- **Обраду у реалном времену**: Циклусе ажурирања за сваки кадрова
**Професионални обрасци**: Имплементирали сте:
- **Раздвајање одговорности**: Физика, приказ и уноси раздвојени
- **Објектно оријентисани дизајн**: Наслеђивање и полиморфизам
- **Управљање стањем**: Праћење животног циклуса објеката и стања игре
- **Оптимизацију перформанси**: Ефикасни алгоритми за реално време
### Тестирање ваше имплементације
Ваша свемирска игра сада садржи потпуни систем детекције судара и борбену механику. 🚀 Тестирајте нове могућности:
- **Кретање** стрелицама за верификацију контроле кретања
- **Пуцање ласерима** тастером размак приметите како хлађење спречава спамовање
- **Пратите судара** када ласери погађају непријатеље, што покреће уклањање
- **Проверите чишћење** уз нестајање уништених објеката из игре
Успешно сте имплементирали систем детекције судара користећи исте математичке принципе који воде навигацију и роботiku свемирских летелица.
### ⚡ **Шта можете урадити у наредних 5 минута**
- [ ] Отворите ДевТулс претраживача и поставите прекидаче кода у функцији за детекцију судара
- [ ] Покушајте да измените брзину ласера или кретање непријатеља да видите ефекте судара
- [ ] Експериментишите са различитим вредностима хлађења за тестирање брзине пуцања
- [ ] Додај `console.log` изјаве за праћење догађаја судара у реалном времену
### 🎯 **Шта можете постићи у овом сату**
- [ ] Завршити квиз после лекције и разумети алгоритме детекције судара
- [ ] Додати визуелне ефекте као што су експлозије када дође до судара
- [ ] Имплементирати различите типове пројектила са варијабилним својствима
- [ ] Креирати пауер-апове који привремено побољшавају способности играча
- [ ] Додати звучне ефекте како би судари били задовољнији
### 📅 **Ваш недељни програм физике**
- [ ] Завршити комплетну свемирску игру са уређеним системима судара
- [ ] Имплементирати напредне облика судара осим правоугаоника (круге, полигони)
- [ ] Додати системе честица за реалистичне ефекте експлозије
- [ ] Креирати сложено непријатељско понашање са избегавањем судара
- [ ] Оптимизовати детекцију судара за боље перформансе са множеством објеката
- [ ] Додати физичку симулацију као што су импулс и реалистично кретање
### 🌟 **Ваш месечни мајсторски ниво игре и физике**
- [ ] Правити игре са напредним физичким моторима и реалистичним симулацијама
- [ ] Учити 3Д детекцију судара и алгоритме просторне партиције
- [ ] Доприносити отвореним изворним библиотекама за физику и опен соурс играчким моторима
- [ ] Савладати оптимизацију перформанси за графички захтевне апликације
- [ ] Креирати образовни садржај о игри и детекцији судара
- [ ] Правити портфолио који приказује вештине напредног програмирања физике
## 🎯 Ваш временски план за мајсторство детекције судара
```mermaid
timeline
title Прогрес у учењу детекције судара и физике игре
section Основа (10 минута)
Рактуга математика: Координатни системи
: Израчунавање граница
: Праћење позиције
: Управљање димензијама
section Дизајн алгоритма (20 минута)
Логика пресека: Тестирање раздвајања
: Детекција преклапања
: Оптимизација перформанси
: Рукохватање ивичних случајева
section Имплементација игре (30 минута)
Објектни системи: Управљање животним циклусом
: Координација догађаја
: Праћење статуса
: Чишћење меморије
section Интерактивне функције (40 минута)
Механика борбе: Системи пројектила
: Хлађење оружја
: Израчунавање штете
: Визуелна повратна информација
section Напредна физика (50 минута)
Системи у реалном времену: Оптимизација фрејм рејта
: Просторно партиционисање
: Одговор на судар
: Симулација физике
section Професионалне технике (1 недеља)
Концепти игре мотора: Системи компоненти
: Физички процеси
: Профилисање перформанси
: Оптимизација за више платформи
section Индустријске примене (1 месец)
Вештине производње: Оптимизација великог обима
: Тимска сарадња
: Развој мотора
: Распоређивање на платформама
```
### 🛠️ Резиме вашег алата за физику у игри
Након завршетка ове лекције, сада сте савладали:
- **Математика судара**: Алгоритми за пресек правоугаоника и координатне системе
- **Оптимизацију перформанси**: Ефикасна детекција судара за апликације у реалном времену
- **Управљање животним циклусом објеката**: Безбедна креирања, ажурирања и рушења објеката
- **Архитектуру засновану на догађајима**: Раздвојени системи за одговор на судар
- **Интеграцију у игру**: Физичка ажурирања кадрова и координација рендеровања
- **Системи уноса**: Реактивне контроле са ограничењем учесталости и повратном информацијом
- **Управљање меморијом**: Ефикасне стратегије паулинга и чишћења објеката
**Апликације у стварном свету**: Ваше вештине детекције судара директно се примењују у:
- **Интерактивним симулацијама**: Научно моделирање и образовни алати
- **Дизајну корисничког интерфејса**: Превлачење и испуштање и детекција додира
- **Визуелизацији података**: Интерактивни графикони и кликабилни елементи
- **Мобилном развоју**: Препознавање додирних геста и обрада судара
- **Програмирању робота**: Планирање пута и избегавање препрека
- **Рачунарској графици**: Праћење зрака и просторни алгоритми
**Стечене професионалне вештине**: Сада можете:
- **Дизајнирати** ефикасне алгоритме за детекцију судара у реалном времену
- **Имплементирати** физичке системе који скалирају са сложеношћу објеката
- **Пронаћи грешке** у сложеним системима интеракције коришћењем математичких принципа
- **Оптимизовати** перформансе за различити хардвер и прегледаче
- **Архитектонски** градити одрживе системе игара користећи проверене дизајн шаблоне
**Развијени концепти у развоју игара**:
- **Физичка симулација**: Детекција судара и одговор у реалном времену
- **Инжењеринг перформанси**: Оптимизовани алгоритми за интерактивне апликације
- **Системи догађаја**: Раздвојена комуникација између компоненти игре
- **Управљање објектима**: Ефикасни шаблони животног циклуса за динамички садржај
- **Обрада уноса**: Реактивне контроле са одговарајућим повратним информацијама
**Следећи ниво**: Спремни сте за истраживање напредних физичких мотора као Matter.js, имплементацију 3Д детекције судара или прављење сложених система честица!
🌟 **Остварен циљ**: Направили сте комплетан систем интеракције заснован на физици са професионалном детекцијом судара!
## GitHub Copilot Agent изазов 🚀
Користите Agent режим да завршите следећи изазов:
**Опис:** Унапредите систем детекције судара тако што ћете имплементирати пауер-апове који се појављују насумично и пружају привремене способности када их херојска летелица покупи.
**Задатак:** Креирајте класу PowerUp која наслеђује GameObject и имплементирајте детекцију судара између хероја и пауер-апова. Додајте најмање два типа пауер-апова: један који повећава брзину паљбе (скраћује период између пуњења) и други који креира привремени штит. Укључите логику за појављивање пауер-апова на насумичним интервалима и позицијама.
---
## 🚀 Изазов
Додај експлозију! Погледај игре ресурсе у [the Space Art repo](../../../../6-space-game/solution/spaceArt/readme.txt) и покушај да додаш експлозију када ласер погоди ванземаљца
## Квиз после предавања
[Квиз после предавања](https://ff-quizzes.netlify.app/web/quiz/36)
## Преглед и самостално учење
Експериментиши са интервалима у својој игри до сада. Шта се дешава када их промениš? Прочитај више о [JavaScript временским догађајима](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/).
## Задатак
[Истражи сударе](assignment.md)
---
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на изворном језику треба сматрати меродавним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Ограничење одговорности**:
Овај документ је преведен помоћу АИ преводилачке услуге [Co-op Translator](https://github.com/Azure/co-op-translator). Иако тежимо прецизности, имајте у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на свом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешна тумачења настала коришћењем овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -1,25 +1,89 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "d642759cf1542f554871f74956a59af9",
"translation_date": "2025-10-24T23:42:52+00:00",
"original_hash": "2ed9145a16cf576faa2a973dff84d099",
"translation_date": "2026-01-07T07:58:49+00:00",
"source_file": "6-space-game/5-keeping-score/README.md",
"language_code": "sr"
}
-->
# Направите свемирску игру, део 5: Поени и животи
## Квиз пре предавања
[Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/37)
Спремни да ваша свемирска игра постане права игра? Додајмо систем бодовања и управљање животима - основне механике које су трансформисале ране аркадне игре попут Space Invaders-а из једноставних демонстрација у заразну забаву. Ово је тренутак када ваша игра постаје заиста игра.
## Цртање текста на екрану - Глас ваше игре
Да бисмо приказали ваш резултат, морамо научити како да рендерујемо текст на платну. Метода `fillText()` је ваш главни алат за ово - то је иста техника која се користила у класичним аркадним играма за приказивање резултата и информација о статусу.
Имате потпуну контролу над изгледом текста:
# Изградња Свемирске Игре Deo 5: Бодовање и Животи
```mermaid
journey
title Ваш пут креирања игре
section Повратне информације играча
Разумевање психологије бодовања: 3: Student
Учење визуелне комуникације: 4: Student
Дизајн система награда: 4: Student
section Техничка имплементација
Приказивање текста на канвасу: 4: Student
Управљање стањем: 5: Student
Ажурирања покренута догађајима: 5: Student
section Унапређење игре
Дизајн корисничког искуства: 5: Student
Баланс изазова и награде: 5: Student
Креирање привлачне игре: 5: Student
```
## Предпредавачки квиз
[Предпредавачки квиз](https://ff-quizzes.netlify.app/web/quiz/37)
Спремни да ваша свемирска игра заиста буде као права игра? Додајмо бодовање и управљање животима - основне механике које су ране аркадне игре као што је Space Invaders претвориле из једноставних демонстрација у зависничку забаву. Овде ваша игра постаје заиста играна.
```mermaid
mindmap
root((Системи повратне информације у играма))
Visual Communication
Text Rendering
Icon Display
Color Psychology
Layout Design
Scoring Mechanics
Point Values
Reward Timing
Progress Tracking
Achievement Systems
Life Management
Risk vs Reward
Player Agency
Difficulty Balance
Recovery Mechanics
User Experience
Immediate Feedback
Clear Information
Emotional Response
Engagement Loops
Implementation
Canvas API
State Management
Event Systems
Performance
```
## Цртање текста на екрану - глас ваше игре
Да бисмо приказали ваш резултат, морамо да научимо како да исцртамо текст на платну. Метода `fillText()` је ваш примарни алат за ово - истa техника која се користила у класичним аркадним играма за приказ резултата и статуса.
```mermaid
flowchart LR
A["📝 Текстуални садржај"] --> B["🎨 Стилски приказ"]
B --> C["📍 Позиционирање"]
C --> D["🖼️ Рендеровање платна"]
E["Фонт породице"] --> B
F["Величина фонта"] --> B
G["Боја"] --> B
H["Поравнање"] --> B
I["X Кoордината"] --> C
J["Y Кoордината"] --> C
style A fill:#e3f2fd
style B fill:#e8f5e8
style C fill:#fff3e0
style D fill:#f3e5f5
```
Имате пуну контролу над изгледом текста:
```javascript
ctx.font = "30px Arial";
@ -28,24 +92,74 @@ ctx.textAlign = "right";
ctx.fillText("show this on the screen", 0, 0);
```
✅ Истражите више о [додавању текста на платно](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) - можда ћете бити изненађени колико креативни можете бити са фонтовима и стиловима!
## Животи - Више од броја
У дизајну игара, "живот" представља простор за грешке играча. Овај концепт потиче још из времена флипер машина, где сте добијали више лопти за игру. У раним видео играма попут Asteroids-а, животи су омогућавали играчима да ризикују и уче из грешака.
Визуелна репрезентација је веома важна - приказивање икона бродова уместо само "Животи: 3" ствара тренутно визуелно препознавање, слично као што су рани аркадни кабинети користили иконографију за комуникацију преко језичких баријера.
## Изградња система награђивања у вашој игри
Сада ћемо имплементирати основне системе повратних информација који држе играче ангажованим:
- **Систем бодовања**: Сваки уништени непријатељски брод доноси 100 поена (округли бројеви су лакши за ментално рачунање). Резултат се приказује у доњем левом углу.
- **Бројач живота**: Ваш херој почиње са три живота - стандард који су успоставиле ране аркадне игре ради балансирања изазова и играња. Сваки судар са непријатељем кошта један живот. Преостали животи ће бити приказани у доњем десном углу помоћу икона бродова ![слика живота](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.sr.png).
✅ Зароните дубље у [додавање текста на платно](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) - можда ћете бити изненађени колико можете бити креативни са фонтовима и стилизовањем!
## Животи - више од самог броја
У дизајну игара, „живот“ представља маргину грешке играча. Овај појам датира из пинбол машина, где сте добијали више лопти за игру. У раним видео играма као што је Asteroids, живот је давао играчима дозволу да преузимају ризике и уче из грешака.
```mermaid
flowchart TD
A["🎮 Акција играча"] --> B{"Процена ризика"}
B --> C["Висок ризик, велика награда"]
B --> D["Сигурна стратегија"]
C --> E{"Исход"}
D --> F["Сталан напредак"]
E -->|Успех| G["🏆 Велики поени"]
E -->|Неуспех| H["💔 Губитак живота"]
H --> I{"Колико живота је остало?"}
I -->|Да| J["🔄 Покушај опет"]
I -->|Не| K["💀 Крај игре"]
J --> B
G --> B
F --> B
style C fill:#ffebee
style D fill:#e8f5e8
style G fill:#e3f2fd
style H fill:#fff3e0
```
Визуелни приказ има велики значај - приказивање иконица бродова уместо само „Животи: 3“ ствара тренутно визуелно препознавање, слично као што су рани аркадни ормарици користили иконографију да комуницирају преко језичких баријера.
## Изградња система награда ваше игре
Сада ћемо имплементирати основне системе повратних информација који одржавају играче ангажованим:
```mermaid
sequenceDiagram
participant Player
participant GameEngine
participant ScoreSystem
participant LifeSystem
participant Display
Player->>GameEngine: Пуца у непријатеља
GameEngine->>ScoreSystem: Додај поене
ScoreSystem->>ScoreSystem: +100 поена
ScoreSystem->>Display: Ажурирај поене
Player->>GameEngine: Судар са непријатељем
GameEngine->>LifeSystem: Изгуби живот
LifeSystem->>LifeSystem: -1 живот
LifeSystem->>Display: Ажурирај животе
alt Животи > 0
LifeSystem->>Player: Настави са играњем
else Животи = 0
LifeSystem->>GameEngine: Крај игре
end
```
- **Систем бодовања**: Сваки уништени непријатељски брод доноси 100 поена (кругли бројеви су лакши за умно рачунање). Резултат се приказује у доњем левом углу.
- **Бројач живота**: Ваш херој почиње са три живота - стандард који су поставиле ране аркадне игре ради баланса између изазова и игрувости. Свако судар са непријатељем кошта један живот. Преостале животе приказујемо у доњем десном углу користећи иконе бродова ![life image](../../../../translated_images/life.6fb9f50d53ee0413.sr.png).
## Хајде да почнемо!
## Хајде да почнемо са изградњом!
Прво, припремите своје радно окружење. Идите до фолдера `your-work`. Требало би да видите следеће фајлове:
Прво, поставите свој радни простор. Идите до фајлова у вашем `your-work` подфолдеру. Требало би да видите ове фајлове:
```bash
-| assets
@ -57,24 +171,49 @@ ctx.fillText("show this on the screen", 0, 0);
-| package.json
```
Да бисте тестирали своју игру, покрените развојни сервер из фолдера `your_work`:
Да бисте тестирали игру, покрените развојни сервер из `your_work` фолдера:
```bash
cd your-work
npm start
```
Ово покреће локални сервер на адреси `http://localhost:5000`. Отворите ову адресу у вашем претраживачу да бисте видели своју игру. Тестирајте контроле помоћу стрелица и покушајте да пуцате на непријатеље како бисте проверили да ли све функционише.
Ово покреће локални сервер на `http://localhost:5000`. Отворите ову адресу у вашем прегледачу да видите игру. Тестирајте контроле стрелицама и испробајте пуцање у непријатеље да проверите да ли све ради.
```mermaid
flowchart TD
A["1. Учитавање ресурса"] --> B["2. Променљиве игре"]
B --> C["3. Детекција судара"]
C --> D["4. Побољшање хероја"]
D --> E["5. Функције приказа"]
E --> F["6. Обрада догађаја"]
G["Икона живота"] --> A
H["Пратиоци резултата и живота"] --> B
I["Пресечне тачке херој-непријатељ"] --> C
J["Начини за поене и живот"] --> D
K["Рендеровање текста и икона"] --> E
L["Логика награда и казни"] --> F
F --> M["🎮 Комплетна игра"]
style A fill:#e3f2fd
style B fill:#e8f5e8
style C fill:#fff3e0
style D fill:#f3e5f5
style E fill:#e0f2f1
style F fill:#fce4ec
style M fill:#e1f5fe
```
### Време за кодирање!
1. **Пребаците визуелне ресурсе који су вам потребни**. Копирајте `life.png` ресурс из фолдера `solution/assets/` у ваш `your-work` фолдер. Затим додајте lifeImg у вашу window.onload функцију:
1. **Пребаците визуелне ресурсе које ћете користити**. Копирајте појам `life.png` из папке `solution/assets/` у ваш `your-work` фолдер. Затим додајте lifeImg у вашу window.onload функцију:
```javascript
lifeImg = await loadTexture("assets/life.png");
```
1. Не заборавите да додате `lifeImg` у вашу листу ресурса:
1. Немојте заборавити да додате `lifeImg` у вашу листу ресурса:
```javascript
let heroImg,
@ -84,9 +223,9 @@ npm start
eventEmitter = new EventEmitter();
```
2. **Поставите променљиве за игру**. Додајте код за праћење укупног резултата (почиње од 0) и преосталих живота (почиње од 3). Приказаћемо их на екрану како би играчи увек знали где се налазе.
2. **Подесите променљиве ваше игре**. Додајте код за праћење укупног броја поена (поčinje од 0) и преосталих живота (поčinje од 3). Приказиваћемо их на екрану тако да играчи увек знају где се налазе.
3. **Имплементирајте детекцију судара**. Проширите вашу `updateGameObjects()` функцију да детектује када се непријатељи сударају са вашим херојем:
3. **Имплементирајте детекцију судара**. Продужите вашу функцију `updateGameObjects()` да детектује када се непријатељи сударају са вашим херојем:
```javascript
enemies.forEach(enemy => {
@ -97,19 +236,19 @@ npm start
})
```
4. **Додајте праћење живота и поена вашем хероју**.
1. **Иницијализујте бројаче**. Испод `this.cooldown = 0` у вашој класи `Hero`, поставите бројач живота и поена:
4. **Додајте праћење живота и поена вашем Хероју**.
1. **Иницијализујте бројаче**. Испод `this.cooldown = 0` у вашој класи `Hero`, подесите животе и поене:
```javascript
this.life = 3;
this.points = 0;
```
1. **Прикажите ове вредности играчу**. Направите функције за приказивање ових вредности на екрану:
1. **Прикажите ове вредности играчу**. Направите функције које исцртавају ове вредности на екрану:
```javascript
function drawLife() {
// TODO, 35, 27
// УРАДИТИ, 35, 27
const START_POS = canvas.width - 180;
for(let i=0; i < hero.life; i++ ) {
ctx.drawImage(
@ -132,16 +271,32 @@ npm start
```
1. **Повежите све са вашим петљом игре**. Додајте ове функције у вашу window.onload функцију одмах након `updateGameObjects()`:
1. **Повежите све у ваш game loop**. Додајте ове функције у вашу window.onload функцију одмах након `updateGameObjects()`:
```javascript
drawPoints();
drawLife();
```
1. **Имплементирајте последице и награде у игри**. Сада ћемо додати системе повратних информација који чине акције играча значајним:
### 🔄 **Педагошки преглед**
**Разумевање дизајна игре**: Пре него што имплементирате последице, уверите се да разумете:
- ✅ Какав визуелни повратак комуницира стање игре играчима
- ✅ Зашто доследан положај UI елемената побољшава употребљивост
- ✅ Психологију иза вредности поена и управљање животима
- ✅ Како се приказ текста на canvas разликује од HTML текста
**Брзи самотест**: Зашто аркадне игре обично користе кругле бројеве за вредности поена?
*Одговор: Кругли бројеви су лакши играчима за ментално израчунавање и стварају задовољавајуће психолошке награде*
1. **Судари коштају животе**. Сваки пут када ваш херој удари у непријатеља, губите један живот.
**Принципи корисничког искуства**: Сада примењујете:
- **Визуелну хијерархију**: Важне информације постављене истакнуто
- **Одмах повратну информацију**: Ажурирања у реалном времену на акције играча
- **Когнитивно оптерећење**: Једноставна, јасна презентација информација
- **Емоционални дизајн**: Иконе и боје које стварају повезаност са играчем
1. **Имплементирајте последице и награде у игру**. Сада ћемо додати системе повратних информација који дају смисао акцијама играча:
1. **Судари коштају животе**. Сваки пут када се ваш херој судари са непријатељем, изгубићете један живот.
Додајте ову методу у вашу класу `Hero`:
@ -154,17 +309,17 @@ npm start
}
```
2. **Пуцање на непријатеље доноси поене**. Сваки успешан погодак доноси 100 поена, пружајући тренутну позитивну повратну информацију за прецизно пуцање.
Проширите вашу класу Hero овом методом за повећање:
2. **Гађање непријатеља доноси бодове**. Свако успешно гађање доноси 100 поена, пружајући одмах позитиван повратак за прецизно пуцање.
Продужите вашу класу Hero овом методом за увећање поена:
```javascript
incrementPoints() {
this.points += 100;
}
```
Сада повежите ове функције са вашим догађајима судара:
Сада повежите ове функције са вашем догађајима судара:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -179,39 +334,177 @@ npm start
});
```
✅ Занимају вас друге игре направљене уз помоћ JavaScript-а и Canvas-а? Истражите мало - можда ћете бити изненађени шта је све могуће!
✅ Занима вас још игара направљених у JavaScript-у и Canvas-у? Истражујте - можда ће вас изненадити шта је све могуће!
Након имплементације ових функција, тестирате игру да видите комплетан систем повратних информација у пракси. Требало би да видите иконе живота у доњем десном углу, бодове у доњем левом, и како се судари смањују животе док успешни хици повећавају резултат.
Ваша игра сада има суштинске механике које су ране аркадне игре учиниле тако привлачним - јасне циљеве, одмах повратне информације и смислене последице за акције играча.
### 🔄 **Педагошки преглед**
**Комплетан систем дизајна игре**: Проверите ваше познавање система повратних информација играча:
- ✅ Како механизми бодовања стварају мотивацију и ангажман играча?
- ✅ Зашто је визуелна конзистенција важна за дизајн корисничког интерфејса?
- ✅ Како систем живота балансира изазов и задржавање играча?
- ✅ Какву улогу има одмах повратна информација у стварању задовољавајућег играчког искуства?
**Интеграција система**: Ваш систем повратних информација показује:
- **Дизајн корисничког искуства**: Јасна визуелна комуникација и хијерархија информација
- **Архитектура заснована на догађајима**: Реактивна ажурирања на акције играча
- **Управљање стањем**: Праћење и приказ динамичких података игре
- ** Владење Canvas-ом**: Приказ текста и позиционирање спрајтова
- **Психологија игара**: Разумевање мотивације и ангажовања играча
**Професионални обрасци**: Имплементирали сте:
- **MVC Архитектуру**: Раздвајање логике игре, података и презентације
- **Observer Pattern**: Ажурирања стања игре заснована на догађајима
- **Дизајн компоненти**: Поново употребљиве функције за приказ и логику
- **Оптимизацију перформанси**: Ефикасан приказ у game loop-у
### ⚡ **Шта можете урадити у наредних 5 минута**
- [ ] Експериментишите са различитим величинама и бојама фонта за приказ резултата
- [ ] Пробајте да промените вредности поена и видите како то утиче на осећај игре
- [ ] Додајте console.log изјаве за праћење када поени и животи мењају вредности
- [ ] Тестирајте ивичне случајеве као што је исцрпљивање живота или достигање високих резултата
### 🎯 **Шта можете постићи у току овог сата**
- [ ] Завршите пост-лекцијски квиз и разумите психологију дизајна игре
- [ ] Додајте звукове за бодовање и губитак живота
- [ ] Имплементирајте систем високог резултата користећи localStorage
- [ ] Направите различите вредности поена за различите типове непријатеља
- [ ] Додајте визуелне ефекте као што је тресање екрана при губитку живота
### 📅 **Ваш недељни пут у дизајну игара**
- [ ] Завршите целу свемирску игру са уређеним системима повратних информација
- [ ] Имплементирајте напредне механике бодовања као што су комбо множитељи
- [ ] Додајте достигнућа и откључиви садржај
- [ ] Направите системе прогресије тежине и балансирања
- [ ] Дизајнирајте корисничке интерфејсе за меније и екране завршетка игре
- [ ] Проучите друге игре да разумете механизме ангажовања
### 🌟 **Ваш месечни пут у мајсторству развоја игара**
- [ ] Правите целе игре са софистицираним системима прогресије
- [ ] Учите анализу игара и мерење понашања играча
- [ ] Доприноси у пројектима отвореног кода за развој игара
- [ ] Мајсторство напредних образаца дизајна и монетизације игара
- [ ] Креирајте едукативни садржај о дизајну игара и корисничком искуству
- [ ] Изградите портфолио који приказује вештине у дизајну и развоју игара
## 🎯 Времеплов вашег мајсторства дизајна игара
```mermaid
timeline
title Прогрес учења у дизајну игре и повратним информацијама играча
section Основа (10 минута)
Визуелна комуникација: Приказивање текста
: Дизајн икона
: Принципи распореда
: Психологија боја
section Психологија играча (20 минута)
Мотивациони системи: Вредности поена
: Ризик и награда
: Повратне информације о напретку
: Дизајн достигнућа
section Техничка имплементација (30 минута)
Мастерство платна: Позиционирање текста
: Приказ слика
: Управљање стањем
: Оптимизација перформанси
section Баланс игре (40 минута)
Дизајн тежине: Управљање животима
: Криве бодовања
: Задржавање играча
: Пристupaчност
section Корисничко искуство (50 минута)
Дизајн интерфејса: Хијерархија информација
: Одговорне повратне информације
: Емоционални дизајн
: Тестирање употребљивости
section Напредни системи (1 недеља)
Механика игре: Системи напретка
: Интеграција аналитике
: Дизајн монетизације
: Функције заједнице
section Вештине у индустрији (1 месец)
Професионални развој: Сарадња у тиму
: Документација дизајна
: Истраживање играча
: Оптимизација платформе
```
### 🛠️ Сажетак вашег сета алата за дизајн игара
Након завршетка овог часа, овладали сте:
- **Психологија играча**: Разумевање мотивације, ризика/наге и петљи ангажовања
- **Визуелна комуникација**: Ефикасан UI дизајн коришћењем текста, икона и распореда
- **Системи повратних информација**: Одговор у реалном времену на акције и догађаје
- **Управљање стањем**: Праћење и приказ динамичких података игре ефикасно
- **Приказ текста на Canvas-у**: Професионални приказ текста са стилом и позиционирањем
- **Интеграција догађаја**: Повезивање корисничких акција са значајним последицама у игри
- **Баланс игре**: Дизајн кривих тежине и система напредовања играча
**Примена у стварном свету**: Вештине дизајна игара директно се примењују у:
- **Дизајну корисничког интерфејса**: Креирање привлачних и интуитивних интерфејса
- **Развоју производа**: Разумевање мотивације корисника и повратних петљи
- **Едукативним технологијама**: Гамификација и системи учења
- **Визуелизацији података**: Чинећи сложене информације доступним и занимљивим
- **Развоју мобилних апликација**: Механика задржавања и дизајн корисничког искуства
- **Маркетиншким технологијама**: Разумевање понашања корисника и оптимизација конверзије
**Професионалне вештине које сте стекли**: Сада можете:
- **Дизајнирати** корисничка искуства која мотивишу и ангажују кориснике
- **Имплементирати** системе повратних информација који ефикасно воде понашање корисника
- **Уравнотежити** изазов и приступачност у интерактивним системима
- **Креирати** визуелну комуникацију која функционише кроз различите корисничке групе
- **Анализирати** понашање корисника и унапређивати дизајн
**Концепти развоја игара које сте савладали**:
- **Мотивација играча**: Разумевање шта покреће ангажовање и задржавање
- **Визуелни дизајн**: Креирање јасних, атрактивних и функционалних интерфејса
- **Интеграција система**: Повезивање више игара за кохерентно искуство
- **Оптимизација перформанси**: Ефикасан приказ и управљање стањем
- **Приступачност**: Дизајн прилагођен различитим нивоима вештине и потребама играча
**Следећи ниво**: Спремни сте за истраживање напредних образаца дизајна игара, имплементацију аналитичких система или проучавање монетизације игара и стратегија задржавања играча!
🌟 **Постигнуће одблокирано**: Направили сте комплетан систем повратних информација играча са професионалним принципима дизајна игара!
Након имплементације ових функција, тестирајте своју игру да бисте видели комплетан систем повратних информација у акцији. Требало би да видите иконе живота у доњем десном углу, ваш резултат у доњем левом углу, и гледајте како судари смањују животе, док успешни поготци повећавају ваш резултат.
---
Ваша игра сада има основне механике које су учиниле ране аркадне игре тако привлачним - јасне циљеве, тренутне повратне информације и значајне последице за акције играча.
## Изазов GitHub Copilot агента 🚀
---
Користите Agent режим да завршите следећи изазов:
## GitHub Copilot Agent изазов 🚀
**Опис:** Побољшајте систем бодовања свемирске игре тако што ћете имплементирати функцију високог резултата са перзистентним складиштем и бонус бодовима.
Користите Agent мод да завршите следећи изазов:
**Упутство:** Направите систем високог резултата који чува најбољи резултат играча у localStorage. Додајте бонус поене за узастопне убиства непријатеља (комбо систем) и имплементирајте различите вредности поена за различите типове непријатеља. Укључите визуелни индикатор када играч оствари нови најбољи резултат и прикажите тренутни висок резултат на екрану игре.
**Опис:** Побољшајте систем бодовања свемирске игре имплементацијом функције за најбољи резултат са перзистентним складиштењем и механиком бонус бодова.
**Задатак:** Направите систем за најбољи резултат који чува најбољи резултат играча у localStorage. Додајте бонус бодове за узастопна уништавања непријатеља (комбо систем) и имплементирајте различите вредности бодова за различите типове непријатеља. Укључите визуелни индикатор када играч постигне нови најбољи резултат и прикажите тренутни најбољи резултат на екрану игре.
## 🚀 Изазов
Сада имате функционалну игру са бодовањем и животима. Размислите које додатне функције би могле побољшати искуство играча.
Сада имате функционалну игру са бодовањем и животима. Размислите које додатне функције могу побољшати играчко искуство.
## Квиз после предавања
## Квиз након предавања
[Квиз после предавања](https://ff-quizzes.netlify.app/web/quiz/38)
[Квиз након предавања](https://ff-quizzes.netlify.app/web/quiz/38)
## Преглед и самостално учење
## Преглед и самосталан рад
Желите да истражите више? Истражите различите приступе системима бодовања и живота у играма. Постоје фасцинантни механизми за игре као што је [PlayFab](https://playfab.com) који се баве бодовањем, ранг листама и напредовањем играча. Како би интеграција нечег таквог могла да подигне вашу игру на виши ниво?
Желите ли да истражите више? Истражите различите приступе бодовању и системима живота у играма. Постоје фасцинантни игре мотори као што је [PlayFab](https://playfab.com) који управљају бодовањем, листама лидера и напретком играча. Како би интеграција нечег сличног могла подићи вашу игру на виши ниво?
## Задатак
[Направите игру са бодовањем](assignment.md)
[Изградите игру са бодовима](assignment.md)
---
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.
Овај документ је преведен коришћењем AI преводилачке услуге [Co-op Translator](https://github.com/Azure/co-op-translator). Иако тежимо тачности, молимо имајте у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људског преводиоца. Нисмо одговорни за било каква неспоразума или погрешне тумачења која могу произићи из употребе овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -1,59 +1,163 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "46bcdd9a0174031655a49bb062aa279c",
"translation_date": "2025-10-24T23:40:13+00:00",
"original_hash": "a4b78043f4d64bf3ee24e0689b8b391d",
"translation_date": "2026-01-07T07:57:19+00:00",
"source_file": "6-space-game/6-end-condition/README.md",
"language_code": "sr"
}
-->
# Изградња свемирске игре, део 6: Крај и поновни почетак
Свака добра игра треба јасне услове за завршетак и глатки механизам за поновни почетак. Направили сте импресивну свемирску игру са кретањем, борбом и бодовањем - сада је време да додате последње делове који ће је учинити комплетном.
Ваша игра тренутно траје бесконачно, као сонде Voyager које је NASA лансирала 1977. године - и даље путују кроз свемир деценијама касније. Иако је то у реду за свемирска истраживања, играма су потребне дефинисане тачке завршетка како би пружиле задовољавајуће искуство.
Данас ћемо имплементирати одговарајуће услове за победу/пораз и систем за поновни почетак. На крају овог часа, имаћете полиранију игру коју играчи могу завршити и поново играти, баш као класичне аркадне игре које су дефинисале медијум.
## Квиз пре предавања
[Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/39)
## Разумевање услова за завршетак игре
Када ваша игра треба да се заврши? Ово фундаментално питање обликовало је дизајн игара још од ране аркадне ере. Pac-Man се завршава када вас ухвате духови или очистите све тачке, док се Space Invaders завршава када ванземаљци стигну до дна или их све уништите.
Као креатор игре, ви дефинишете услове за победу и пораз. За нашу свемирску игру, ево проверених приступа који стварају занимљиве игре:
- **Уништили сте `N` непријатељских бродова**: Ово је прилично уобичајено ако поделите игру на различите нивое, где је потребно уништити `N` непријатељских бродова да бисте завршили ниво.
- **Ваш брод је уништен**: Постоје игре у којима губите ако је ваш брод уништен. Други уобичајени приступ је концепт живота. Сваки пут када је ваш брод уништен, одузима се један живот. Када изгубите све животе, губите игру.
- **Сакупили сте `N` поена**: Други уобичајени услов за завршетак је сакупљање поена. Како добијате поене зависи од вас, али је прилично уобичајено доделити поене за различите активности као што су уништавање непријатељског брода или сакупљање предмета који падају када се униште.
- **Завршили сте ниво**: Ово може укључивати неколико услова као што су уништавање `X` непријатељских бродова, сакупљање `Y` поена или можда сакупљање одређеног предмета.
## Имплементација функције за поновни почетак игре
Добре игре подстичу поновно играње кроз глатке механизме за поновни почетак. Када играчи заврше игру (или доживе пораз), често желе одмах да покушају поново - било да би побољшали свој резултат или своје перформансе.
Тетрис је савршен пример за то: када ваши блокови стигну до врха, можете одмах започети нову игру без проласка кроз сложене меније. Направићемо сличан систем за поновни почетак који чисто ресетује стање игре и брзо враћа играче у акцију.
# Изградите свемирску игру, део 6: Крај и поновни почетак
```mermaid
journey
title Ваш пут ка завршетку игре
section Услови завршетка
Дефиниши стања победе/пораза: 3: Student
Имплементирај проверу услова: 4: Student
Обради прелазак стања: 4: Student
section Искусто играча
Дизајнирај системе повратних информација: 4: Student
Креирај механизам рестарта: 5: Student
Ушмишљај кориснички интерфејс: 5: Student
section Интеграција система
Управљај животним циклусом игре: 5: Student
Обради чишћење меморије: 5: Student
Креирај потпуно искуство: 5: Student
```
Свака велика игра треба јасне услове за крај и глатак механизам поновног покретања. Изградили сте импресивну свемирску игру са кретањем, борбом и бодовањем - сада је време да додате последње делове који је чине потпуном.
Ваша игра тренутно траје бесконачно, као што су били свемирски сонде Voyager које је NASA лансирала 1977. године - још увек путују кроз свемир деценијама касније. Док је то у реду за свемирска истраживања, игре требају дефинисане крајеве да би пружиле задовољавајућа искуства.
Данас ћемо имплементирати правилне услове за победу/пораз и систем поновног покретања. До краја ове лекције имаћете уређену игру коју играчи могу завршити и поново играти, баш као класичне аркадне игре које су дефинисале овај медиј.
```mermaid
mindmap
root((Завршетак игре))
End Conditions
Victory States
Defeat Conditions
Progress Tracking
State Validation
Player Feedback
Visual Messages
Color Psychology
Clear Communication
Emotional Response
State Management
Game Loop Control
Memory Cleanup
Object Lifecycle
Event Handling
Restart Systems
Input Handling
State Reset
Fresh Initialization
User Experience
Polish Elements
Message Display
Smooth Transitions
Error Prevention
Accessibility
```
## Претходни квиз
[Претходни квиз](https://ff-quizzes.netlify.app/web/quiz/39)
## Разумевање услова за крај игре
Када ваша игра треба да се заврши? Ово основно питање је обликовало дизајн игара још од ране аркадне ере. Pac-Man се завршава када вас ухвате духови или очистите све тачке, док Space Invaders завршава када ванземаљци стигну до дна или их све уништите.
Као креатор игре, дефинишете услове за победу и пораз. За нашу свемирску игру, ево проверених приступа који стварају занимљиву игру:
```mermaid
flowchart TD
A["🎮 Почетак игре"] --> B{"Провери услове"}
B --> C["Број непријатеља"]
B --> D["Животи хероја"]
B --> E["Праг поена"]
B --> F["Напредак нивоа"]
C --> C1{"Непријатеља = 0?"}
D --> D1{"Животи = 0?"}
E --> E1{"Поенa ≥ циљ?"}
F --> F1{"Задаци завршени?"}
C1 -->|Да| G["🏆 Победа"]
D1 -->|Да| H["💀 Пораз"]
E1 -->|Да| G
F1 -->|Да| G
C1 -->|Не| B
D1 -->|Не| B
E1 -->|Не| B
F1 -->|Не| B
G --> I["🔄 Опција поновног покретања"]
H --> I
style G fill:#e8f5e8
style H fill:#ffebee
style I fill:#e3f2fd
```
- **Јединице непријатеља `N` су уништене**: Веома је уобичајено да ако поделите игру у различите нивое, морате да уништите `N` непријатељских бродова да бисте завршили ниво
- **Ваш брод је уништен**: Постоје игре у којима губите игру ако вам брод буде уништен. Друга честа пракса је да имате концепт живота. Сваки пут када ваш брод буде уништен, један живот се одузима. Када изгубите све животе, губите игру.
- **Сакупили сте `N` поена**: Још један уобичајен услов краја је да сакупите поене. Како их добијате зависи од вас, али је често пракса да се поени додељују за разне активности као што је уништавање непријатељског брода или сакупљање предмета које предмети *испуштају* када се униште.
- **Завршите ниво**: Ово може укључивати неколико услова као што су уништење `X` непријатељских бродова, сакупљање `Y` поена или сакупљање одређеног предмета.
## Имплементација функције поновног покретања игре
Добре игре охрабрују поновну играње кроз глатке механизме поновног покретања. Када играчи заврше игру (или изгубе), често желе да одмах покушају поново - било да би побољшали резултат или унапредили учинак.
```mermaid
stateDiagram-v2
[*] --> Playing: Почетак игре
Playing --> Victory: Сви непријатељи уништени
Playing --> Defeat: Животи = 0
Victory --> MessageDisplay: Прикажи поруку победе
Defeat --> MessageDisplay: Прикажи поруку пораза
MessageDisplay --> WaitingRestart: Порука за притисак Ентер
WaitingRestart --> Resetting: Притиснут тастер Ентер
Resetting --> CleanupMemory: Очисти интервале
CleanupMemory --> ClearEvents: Уклони слушаоце
ClearEvents --> InitializeGame: Нови почетак
InitializeGame --> Playing: Поčinje nova игра
note right of MessageDisplay
Повратне информације обојене бојом:
Зелена = Победа
Црвена = Пораз
end note
note right of Resetting
Потпуни ресет стања
спречава цурење меморије
end note
```
Tetris је савршен пример: када ваши блокови досегну врх, можете одмах започети нову игру без навигације кроз комплексан мени. Направићемо сличан систем поновног покретања који чисто ресетује стање игре и брзо враћа играче у акцију.
**Размишљање**: Размислите о играма које сте играли. Под којим условима се завршавају и како вас подстичу да их поново започнете? Шта чини искуство поновног почетка глатким, а шта фрустрирајућим?
**Рефлексија**: Размислите о играма које сте играли. Под којим условима се завршавају и како вам се нуди поновно покретање? Шта чини искуство поновног покретања глатким, а шта фрустрирајућим?
## Шта ћете направити
## Шта ћете изградити
Имплементираћете завршне функције које ће трансформисати ваш пројекат у комплетно искуство игре. Ови елементи разликују полиране игре од основних прототипова.
Имплементираћете последње функционалности које ће вашу игру трансформисати у потпун играчки доживљај. Ови елементи разликују професионалне игре од основних прототипова.
**Ево шта данас додајемо:**
**Ево шта данас додajемо:**
1. **Услов за победу**: Уништи све непријатеље и добиј заслужену прославу!
2. **Услов за пораз**: Изгуби све животе и суочи се са поразом на екрану
3. **Механизам за поновни почетак**: Притисни Enter да се одмах вратиш у игру - јер једна игра никад није довољна
4. **Управљање стањем**: Чиста табла сваки пут - без преосталих непријатеља или чудних грешака из претходне игре
1. **Услов за победу**: Уништи све непријатеље и добиј одговарајућу прославу (заслужили сте!)
2. **Услов за пораз**: Потрошите све животе и суочите се са екраном пораза
3. **Механизам поновног покретања**: Притисните Enter да се одмах вратите у игру - јер једна игра никад није довољна
4. **Управљање стањем**: Чист почетак сваки пут - без остатака непријатеља или чудних грешака из претходне игре
## Почетак
## Почетак рада
Припремимо ваш развојни окружење. Требало би да имате све датотеке свемирске игре из претходних лекција спремне.
Хајде да припремимо ваше развојно окружење. Требало би да имате све датотеке ваше свемирске игре из претходних лекција.
**Ваш пројекат би требало да изгледа отприлике овако:**
**Ваш пројекат треба да изгледа отприлике овако:**
```bash
-| assets
@ -66,7 +170,7 @@ CO_OP_TRANSLATOR_METADATA:
-| package.json
```
**Покрените ваш развојни сервер:**
**Покрените свој сервер за развој:**
```bash
cd your-work
@ -75,18 +179,43 @@ npm start
**Ова команда:**
- Покреће локални сервер на `http://localhost:5000`
- Правилно сервира ваше датотеке
- Правилно сервира ваше фајлове
- Аутоматски освежава када направите промене
Отворите `http://localhost:5000` у вашем претраживачу и проверите да ли ваша игра ради. Требало би да можете да се крећете, пуцате и интерагујете са непријатељима. Када потврдите, можемо наставити са имплементацијом.
> 💡 **Савет**: Да бисте избегли упозорења у Visual Studio Code, декларишите `gameLoopId` на врху вашег фајла као `let gameLoopId;` уместо да га декларишете унутар функције `window.onload`. Ово прати најбоље праксе модерног JavaScript-а за декларисање променљивих.
Отворите `http://localhost:5000` у вашем прегледачу и проверите да ли ваша игра ради. Требало би да можете да се крећете, пуцате и интерагујете са непријатељима. Када се уверите, можемо наставити са имплементацијом.
> 💡 **Корисни савет**: Да бисте избегли упозорења у Visual Studio Code, деклараишите `gameLoopId` на врху фајла као `let gameLoopId;` уместо да га деклараишете унутар функције `window.onload`. Ово прати модерне добре праксе декларације променљивих у JavaScript-у.
```mermaid
flowchart TD
A["1. Праћење услова"] --> B["2. Обрађивачи догађаја"]
B --> C["3. Константе порука"]
C --> D["4. Контроле рестарта"]
D --> E["5. Приказ порука"]
E --> F["6. Ресетовање система"]
G["isHeroDead()\nisEnemiesDead()"] --> A
H["Догађаји судара\nДогађаји краја игре"] --> B
I["GAME_END_WIN\nGAME_END_LOSS"] --> C
J["Ентер тастер\nПокретач рестарта"] --> D
K["Победа/Пораз\nБоја обојен текст"] --> E
L["Чишћење стања\nСвежа иницијализација"] --> F
F --> M["🎮 Комплетна игра"]
style A fill:#e3f2fd
style B fill:#e8f5e8
style C fill:#fff3e0
style D fill:#f3e5f5
style E fill:#e0f2f1
style F fill:#fce4ec
style M fill:#e1f5fe
```
## Кораци имплементације
### Корак 1: Креирање функција за праћење услова завршетка
### Корак 1: Креирање функција за праћење услова краја
Потребне су нам функције које ће пратити када игра треба да се заврши. Као сензори на Међународној свемирској станици који стално прате критичне системе, ове функције ће континуирано проверавати стање игре.
Потребне су нам функције које ће надгледати када игра треба да се заврши. Као сензори на Међународној свемирској станици који непрекидно прате критичне системе, ове функције ће стално проверавати стање игре.
```javascript
function isHeroDead() {
@ -100,16 +229,49 @@ function isEnemiesDead() {
```
**Ево шта се дешава у позадини:**
- **Проверава** да ли је наш херој остао без живота (ау!)
- **Броји** колико непријатеља је још увек живо
- **Провера** да ли је наш јунак остао без живота (ау!)
- **Броји** колико непријатеља још увек живи и напада
- **Враћа** `true` када је бојно поље чисто од непријатеља
- **Користи** једноставну логику true/false ради једноставности
- **Филтрира** све објекте игре да би пронашао преживеле
### Корак 2: Ажурирање обрађивача догађаја за услове завршетка
Сада ћемо повезати ове провере услова са системом догађаја игре. Сваки пут када дође до судара, игра ће проценити да ли то покреће услов за завршетак. Ово ствара тренутну повратну информацију за критичне догађаје у игри.
- **Користи** једноставну логику тачно/нетачно да све буде јасно
- **Филтрира** све објекте игре да нађе преживеле
### Корак 2: Ажурирање обрађивача догађаја за услове краја
Сада ћемо повезати ове проверe услова са системом догађаја игре. Сваки пут када се догоди колизија, игра ће проценити да ли је достигнут услов за крај. Ово прави тренутни повратни сигнал за критичне догађаје у игри.
```mermaid
sequenceDiagram
participant Collision
participant GameLogic
participant Conditions
participant EventSystem
participant Display
Collision->>GameLogic: Ласер погађа непријатеља
GameLogic->>GameLogic: Уништи предмете
GameLogic->>Conditions: Провери isEnemiesDead()
alt Сви непријатељи поражени
Conditions->>EventSystem: Емитуј GAME_END_WIN
EventSystem->>Display: Прикажи поруку о победи
else Непријатељи остају
Conditions->>GameLogic: Настави игру
end
Collision->>GameLogic: Непријатељ погађа хероја
GameLogic->>GameLogic: Смањи животе
GameLogic->>Conditions: Провери isHeroDead()
alt Животи = 0
Conditions->>EventSystem: Емитуј GAME_END_LOSS
EventSystem->>Display: Прикажи поруку о поразу
else Животи остају
GameLogic->>Conditions: Провери isEnemiesDead()
alt Сви непријатељи поражени
Conditions->>EventSystem: Емитуј GAME_END_WIN
end
end
```
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
first.dead = true;
@ -126,7 +288,7 @@ eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => {
hero.decrementLife();
if (isHeroDead()) {
eventEmitter.emit(Messages.GAME_END_LOSS);
return; // loss before victory
return; // губитак пре победе
}
if (isEnemiesDead()) {
eventEmitter.emit(Messages.GAME_END_WIN);
@ -142,31 +304,31 @@ eventEmitter.on(Messages.GAME_END_LOSS, () => {
});
```
**Шта се овде дешава:**
- **Ласер погоди непријатеља**: Оба нестају, добијате поене и проверавамо да ли сте победили
- **Непријатељ вас погоди**: Губите живот и проверавамо да ли сте још увек у игри
- **Паметно редослед**: Прво проверавамо пораз (никоме није драго да победи и изгуби у исто време!)
- **Тренутне реакције**: Чим се нешто важно догоди, игра то зна
**Овде се догађа:**
- **Ласер погађа непријатеља**: Обојица нестају, добијате поене и проверавамо да ли сте победили
- **Непријатељ погађа вас**: Губите живот и проверавамо да ли сте још живи
- **Паметно редослед**: Прво проверавамо пораз (никако не желите да победите и изгубите истовремено!)
- **Тренутне реакције**: Чим се деси нешто важно, игра то одмах зна
### Корак 3: Додавање нових константи за поруке
### Корак 3: Додавање нових константи порука
Мораћете да додате нове типове порука у ваш објекат `Messages`. Ове константе помажу у одржавању конзистентности и спречавају грешке у вашем систему догађаја.
Треба да додате нове типове порука у свој `Messages` константни објекат. Ове константе помажу у одржавању конзистентности и спречавању типографских грешака у систему догађаја.
```javascript
GAME_END_LOSS: "GAME_END_LOSS",
GAME_END_WIN: "GAME_END_WIN",
```
**У горњем коду, урадили смо:**
- **Додали** константе за догађаје завршетка игре ради одржавања конзистентности
- **Користили** описне називе који јасно указују на сврху догађаја
- **Пратили** постојећу конвенцију именовања за типове порука
**У горе наведеном:**
- **Додали смо** константе за догађаје краја игре ради конзистентности
- **Користили смо** описна имена која јасно показују сврху догађаја
- **Пратили смо** постојећу конвенцију имена типова порука
### Корак 4: Имплементација контрола за поновни почетак
### Корак 4: Имплементација контроле за поновни почетак
Сада ћете додати контроле на тастатури које омогућавају играчима да поново покрену игру. Тастер Enter је природан избор јер се обично повезује са потврђивањем радњи и покретањем нових игара.
Сада ћете додати контроле тастатуре које играчима омогућавају да поново покрену игру. Тастер Enter је природан избор јер је уобичајено повезан са потврђивањем радњи и почетком нових игара.
**Додајте детекцију тастера Enter у ваш постојећи слушалац догађаја keydown:**
**Додајте детекцију Enter тастера у свој постојећи слушач догађаја keydown:**
```javascript
else if(evt.key === "Enter") {
@ -181,16 +343,16 @@ KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
```
**Шта треба да знате:**
- **Проширује** ваш постојећи систем за обраду догађаја на тастатури
- **Користи** тастер Enter као окидач за поновни почетак ради интуитивног корисничког искуства
- **Емитује** прилагођени догађај који други делови ваше игре могу слушати
- **Одржава** исти образац као и ваше друге контроле на тастатури
- **Проширење** постојећег система обраде тастатуре
- **Користи** Enter као тригер за поновни почетак ради интуитивног доживљаја корисника
- **Емитује** прилагођени догађај на који други делови игре могу да реагују
- **Одржава** исти образац као и за остале контроле на тастатури
### Корак 5: Креирање система за приказ порука
### Корак 5: Креирање система приказа порука
Ваша игра треба јасно да комуницира резултате играчима. Креираћемо систем порука који приказује стања победе и пораза користећи текст у боји, слично интерфејсима терминала раних компјутерских система где је зелена означавала успех, а црвена сигнализирала грешке.
Ваша игра треба да комуницира резултате јасно према играчима. Направићемо систем порука који приказује стања победе и пораза користећи текст у бојама, слично терминалима раних рачунарских система где је зелена значила успех, а црвена грешку.
**Креирајте функцију `displayMessage()`:**
**Направите функцију `displayMessage()`:**
```javascript
function displayMessage(message, color = "red") {
@ -201,20 +363,20 @@ function displayMessage(message, color = "red") {
}
```
**Корак по корак, ево шта се дешава:**
- **Поставља** величину и стил фонта за јасан, читљив текст
- **Примењује** параметар боје са "црвеном" као подразумеваном за упозорења
**Корак по корак, ово се дешава:**
- **Поставља** величину и фамилију фонта за јасан, читљив текст
- **Примењује** параметар боје са „црвена“ као подразумеваном за упозорења
- **Центрира** текст хоризонтално и вертикално на платну
- **Користи** модерне JavaScript подразумеване параметре за флексибилне опције боја
- **Користи** 2D контекст платна за директно рендеровање текста
- **Користи** модерне подразумеване параметре JavaScript за флексибилност боја
- **Употребљава** canvas 2D контекст за директно цртање текста
**Креирајте функцију `endGame()`:**
**Направите функцију `endGame()`:**
```javascript
function endGame(win) {
clearInterval(gameLoopId);
// Set a delay to ensure any pending renders complete
// Поставите закашњење да бисте осигурали да се сви неисписани прикази заврше
setTimeout(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
@ -234,18 +396,34 @@ function endGame(win) {
```
**Шта ова функција ради:**
- **Замрзава** све на месту - нема више кретања бродова или ласера
- **Прави** кратку паузу (200ms) да заврши цртање последњег кадра
- **Брише** екран и боји га у црно ради драматичног ефекта
- **Стапа** све на месту - више нема кретања бродова или ласера
- **Прави** кратку паузу (200ms) да последњи фрејм буде у потпуности исцртан
- **Брише** екран и фарба га у црно ради драматичног ефекта
- **Приказује** различите поруке за победнике и губитнике
- **Кодира боје** вести - зелена за добро, црвена за... па, не баш добро
- **Каже** играчима тачно како да се поново укључе
- **Боји** информације зелена за добро, црвена за... па, не баш добро
- **Казује** играчима како да се врате у игру
### 🔄 **Педагошки преглед**
**Управљање стањем игре**: Пре имплементације функције ресетовања, уверите се да разумете:
- ✅ Како услови краја стварају јасне циљеве у игри
- ✅ Зашто је визуелни повратни сигнал важан за разумевање играча
- ✅ Колико је значајно правилно чишћење да би се спречиле цурења меморије
- ✅ Како архитектура заснована на догађајима омогућава чисте трансакције стања
**Кратки само-тест**: Шта би се десило ако не обришете слушаче догађаја током ресетовања?
*Одговор: Цурења меморије и дуплих обрада догађаја што доводи до непредвидивог понашања*
**Принципи дизајна игара**: Сада имплементирате:
- **Јасне циљеве**: Играч зна тачно шта значи победа и пораз
- **Одмах повратни сигнал**: Промене у стању игре се моментално приказују
- **Контрола корисника**: Играч може поново покренути кад год жели
- **Поузданост система**: Правилно чишћење спречава грешке и падове перформанси
### Корак 6: Имплементација функције за ресетовање игре
### Корак 6: Имплементација функције ресетовања игре
Систем за ресетовање треба потпуно да очисти тренутно стање игре и иницијализује нову сесију игре. Ово осигурава да играчи добију чист почетак без преосталих података из претходне игре.
Систем ресетовања мора у потпуности очистити тренутно стање игре и иницијајлизовати свежу сесију игре. Ово осигурава да играчи имају чист почетак без остатака података из претходне игре.
**Креирајте функцију `resetGame()`:**
**Направите функцију `resetGame()`:**
```javascript
function resetGame() {
@ -266,15 +444,15 @@ function resetGame() {
}
```
**Разумимо сваки део:**
- **Проверава** да ли тренутно ради петља игре пре ресетовања
- **Чисти** постојећу петљу игре да заустави све тренутне активности игре
- **Уклања** све слушаоце догађаја да би спречио цурење меморије
- **Реинцијализује** стање игре са новим објектима и променљивим
- **Покреће** нову петљу игре са свим основним функцијама игре
- **Одржава** исти интервал од 100ms ради конзистентног перформанса игре
**Разумевање сваког дела:**
- **Проверава** да ли је тренутно покренут game loop пре ресетовања
- **Брише** постојећи game loop да заустави сву текућу активност
- **Уклања** све слушаче догађаја да спречи цурења меморије
- **Поново иницијајлизује** стање игре новим објектима и променљивима
- **Покреће** нови game loop са свим кључним играчким функцијама
- **Задржава** исти интервал од 100ms за доследне перформансе игре
**Додајте обрађивач догађаја за тастер Enter у вашу функцију `initGame()`:**
**Додајте слушача за Enter тастер у вашу функцију `initGame()`:**
```javascript
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
@ -282,7 +460,7 @@ eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
});
```
**Додајте метод `clear()` у вашу класу EventEmitter:**
**Додајте методу `clear()` у своју класу EventEmitter:**
```javascript
clear() {
@ -290,64 +468,217 @@ clear() {
}
```
**Кључне тачке за памћење:**
- **Повезује** притисак тастера Enter са функционалношћу ресетовања игре
- **Региструје** овог слушаоца догађаја током иницијализације игре
- **Обезбеђује** чист начин за уклањање свих слушалаца догађаја приликом ресетовања
- **Спречава** цурење меморије чишћењем обрађивача догађаја између игара
- **Ресетује** објекат слушалаца на празно стање ради нове иницијализације
**Кључне појединости за памћење:**
- **Повезује** притисак на Enter са функцијом ресетовања игре
- **Региструје** слушача током иницијализације игре
- **Обезбеђује** чист начин за уклањање свих слушача приликом ресетовања
- **Спречава** цурења меморије чишћењем хендлера између игара
- **Ресетује** објекат слушача у празно стање за свежу инициализацију
## Честитамо! 🎉
👽 💥 🚀 Успешно сте изградили комплетну игру од самог почетка. Као програмери који су креирали прве видео игре 1970-их, трансформисали сте линије кода у интерактивно искуство са одговарајућим механикама игре и повратним информацијама корисника. 🚀 💥 👽
👽 💥 🚀 Успешно сте направили комплетну игру од почетка до краја. Као и програмери првих видео игара из 1970-их, претворили сте редове кода у интерактивно искуство са исправним играчким механикама и повратним информацијама за корисника. 🚀 💥 👽
**Постигли сте:**
- **Имплементирали** комплетне услове за победу и пораз са повратним информацијама корисника
- **Креирали** беспрекорни систем за поновни почетак ради континуиране игре
- **Дизајнирали** јасну визуелну комуникацију за стања игре
- **Управљали** сложеним прелазима стања игре и чишћењем
- **Саставили** све компоненте у кохезивну, играљиву игру
- **Имплементирали** потпуне услове победе и пораза са корисничким повратним информацијама
- **Креирали** глатак систем поновног покретања за континуирано играње
- **Дизајнирали** јасну визуелну комуникацију стања игре
- **Управљали** сложеним променама стања игре и чишћењем
- **Саставили** све компоненте у кохерентну, играчку целину
### 🔄 **Педагошки преглед**
**Систем за комплетни развој игре**: Прославите своје овладавање целокупним циклусом развоја игре:
- ✅ Како услови краја стварају задовољавајућа искуства играча?
- ✅ Зашто је правилно управљање стањем кључно за стабилност игре?
- ✅ Како визуелни повратни сигнал унапређује разумевање играча?
- ✅ Коју улогу игра систем поновног покретања у задржавању играча?
**Мастеринг система**: Ваша комплетна игра показује:
- **Фулл-стакк развој игара**: Од графике до уноса и управљања стањем
- **Професионална архитектура**: Системи засновани на догађајима са исправним чишћењем
- **Дизајн корисничког искуства**: Јасан повратни сигнал и интуитивне контроле
- **Оптимизација перформанси**: Ефикасно рендеровање и управљање меморијом
- **Финиш и комплетност**: Сви детаљи који игру чине завршеном
**Вештине спремне за индустрију**: Имплементирали сте:
- **Архитектуру game loop-а**: Системе у реалном времену са конзистентним перформансама
- **Програмирање засновано на догађајима**: Децомпоновни системи који се ефикасно скалирају
- **Управљање стањем**: Сложено руковање подацима и животним циклусом
- **Дизајн корисничког интерфејса**: Јасна комуникација и одзивне контроле
- **Тестирање и отклањање грешака**: Итеративни развој и решавање проблема
### ⚡ **Шта можете урадити у наредних 5 минута**
- [ ] Играјте своју комплетну игру и тестирате све услове победе и пораза
- [ ] Експериментишете са различитим параметрима услова краја
- [ ] Покушајте да додате console.log изјаве за праћење промене стања игре
- [ ] Поделите игру са пријатељима и прикупите повратне информације
### 🎯 **Шта можете постићи у овом сату**
- [ ] Завршите квиз након лекције и размислите о свом путу развоја игре
- [ ] Додајте аудио ефекте за стања победе и пораза
- [ ] Имплементирајте додатне услове краја као што су временски лимити или бонус циљеви
- [ ] Креирајте различите нивое тежине са различитим бројем непријатеља
- [ ] Улепшајте визуелни изглед бољим фонтовима и бојама
### 📅 **Ваш недељни мајсторски курс развоја игара**
- [ ] Завршите унапређену свемирску игру са више нивоа и напредовањем
- [ ] Додајте напредне функције као што су појачања, различите врсте непријатеља и специјално оружје
- [ ] Креирајте систем високих резултата са перзистентном меморијом
- [ ] Дизајнирајте корисничке интерфејсе за меније, подешавања и опције игре
- [ ] Оптимизујте перформансе за различите уређаје и прегледаче
- [ ] Објавите игру онлајн и поделите је са заједницом
### 🌟 **Ваша месечна каријера у развоју игара**
- [ ] Направите више потпуних игара истражујући различите жанрове и механике
- [ ] Учење напредних оквира за развој игара као што су Phaser или Three.js
- [ ] Доприносите пројектима отвореног кода у развоју игара
- [ ] Проучавајте принципе дизајна игара и психологију играча
- [ ] Креирајте портфолио који приказује ваше вештине у развоју игара
- [ ] Повежите се са заједницом за развој игара и наставите са учењем
## 🎯 Ваш комплетан временски оквир за савладавање развоја игара
```mermaid
timeline
title Потпуни напредак у учењу развоја игара
section Основа (Лекције 1-2)
Архитектура игре: Структура пројекта
: Управљање ресурсима
: Основе платна
: Системи догађаја
section Системи интеракције (Лекције 3-4)
Контрола играча: Обрада уноса
: Механике кретања
: Детекција судара
: Физичка симулација
section Механике игре (Лекција 5)
Системи повратних информација: Механизми бодовања
: Управљање животом
: Визуелна комуникација
: Мотивација играча
section Завршетак игре (Лекција 6)
Полицај и ток: Услови завршетка
: Управљање стањем
: Системи поновног покретања
: Корисничко искуство
section Напредне функције (1 недеља)
Вештине унапређења: Интеграција звука
: Визуелни ефекти
: Прогресија нивоа
: Оптимизација перформанси
section Професионални развој (1 месец)
Спремност за индустрију: Свладавање оквира
: Сарадња у тиму
: Развој портфолија
: Укљученост у заједницу
section Напредовање у каријери (3 месеца)
Специјализација: Напредни гејм енџини
: Распоређивање на платформама
: Стратегије монетизације
: Мрежа у индустрији
```
### 🛠️ Резиме Вашег комплетног алата за развој игара
Након завршетка целе ове серије свемирских игара, сада сте савладали:
- **Архитектуру игара**: Системи вођени догађајима, петље игара и управљање стањем
- **Програмирање графике**: Canvas API, приказивање спрајтова и визуелни ефекти
- **Системе уноса**: Руководење тастатуром, детекција судара и респонзивне контроле
- **Дизајн игара**: Повратне информације играчу, системи прогресије и механике ангажовања
- **Оптимизацију перформанси**: Ефикасан приказ, управљање меморијом и контрола фрејм рейта
- **Корисничко искуство**: Јасна комуникација, интуитивне контроле и дотеривање детаља
- **Професионалне шеме**: Чист код, технике отклањања грешака и организација пројеката
**Примена у реалном свету**: Ваше вештине развоја игара се директно односе на:
- **Интерактивне веб апликације**: Динамички интерфејси и системи у реалном времену
- **Визуелизацију података**: Анимиране графиконе и интерактивну графику
- **Образовне технологије**: Гамификација и ангажујућа искуства учења
- **Мобилни развој**: Интерakcije осетљиве на додир и оптимизација перформанси
- **Симулациони софтвер**: Физичке механизме и моделовање у реалном времену
- **Креативна индустрија**: Интерактивна уметност, забава и дигитална искуства
**Професионалне вештине које сте стекли**: Сада можете:
- **Архитектонски дизајнирати** сложене интерактивне системе од нуле
- **Отklonити грешке** у апликацијама у реалном времену користећи систематске приступе
- **Оптимизовати** перформансе за глатко корисничко искуство
- **Дизајнирати** ангажујуће корисничке интерфејсе и шеме интеракције
- **Сарадивати** ефикасно на техничким пројектима уз правилну организацију кода
**Савладане концепте развоја игара**:
- **Системи у реалном времену**: Петље игара, управљање фрејм рейтом и перформансе
- **Архитектура вођена догађајима**: Одвезани системи и пренос порука
- **Управљање стањем**: Сложено управљање подацима и животни циклус
- **Програмирање корисничког интерфејса**: Графика на Canvas-у и респонзивни дизајн
- **Теорија дизајна игара**: Психологија играча и механике ангажовања
## Изазов GitHub Copilot Agent 🚀
**Следећи ниво**: Спремни сте да истражите напредне оквире за игре, 3D графику, мултиплејер системе или да се пребаците у професионалне улоге у развоју игара!
Користите Agent мод да завршите следећи изазов:
🌟 **Постигнуће откључано**: Завршили сте цео пут развоја игре и изграђени сте професионално квалитетно интерактивно искуство од нуле!
**Опис:** Унапредите свемирску игру имплементацијом система за напредовање кроз нивое са повећаном тежином и бонус функцијама.
**Добродошли у заједницу за развој игара!** 🎮✨
**Задатак:** Креирајте систем за више нивоа свемирске игре где сваки ниво има више непријатељских бродова са повећаном брзином и здрављем. Додајте множилац бодова који се повећава са сваким нивоом и имплементирајте појачања (као што су брза ватра или штит) која се насумично појављују када се непријатељи униште. Укључите бонус за завршетак нивоа и приказујте тренутни ниво на екрану уз постојеће бодове и животе.
## GitHub Copilot Agent изазов 🚀
Користите Agent режим за завршетак следећег изазова:
**Опис:** Побољшајте свемирску игру имплементирајући систем прогресије нивоа са повећавањем тежине и бонус функцијама.
**Захтев:** Направите мулти-ниво свемирски систем у којем сваки ниво има више непријатељских бродова са повећаном брзином и здрављем. Додајте множитеља резултата који се повећава са сваким нивоом и имплементирајте пајер-апове (као што су брзо пуцање или штит) који се случајно појављују када се непријатељи униште. Укључите бонус за завршетак нивоа и прикажите тренутни ниво на екрану уз постојећи резултат и животе.
Сазнајте више о [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
## 🚀 Опциони изазов за унапређење
**Додајте звук вашој игри**: Унапредите искуство играња имплементацијом звучних ефеката! Размислите о додавању звука за:
**Додајте звук вашој игри**: Побољшајте своје играчко искуство имплементирањем звучних ефеката! Размислите да додате аудио за:
- **Ласерске пуцње** када играч пуца
- **Уништавање непријатеља** када су бродови погођени
- **Оштећење хероја** када играч прими ударце
- **Музику победе** када је игра добијена
- **Звук пораза** када је игра изгубљена
- **Ласерске исецаје** када играч пуца
- **Уништење непријатеља** када бродови буду погођени
- **Штету јунака** када играч прими ударце
- **Музику победе** када игра буде освоја
- **Звук пораза** када игра буде изгубљена
**Пример имплементације звука:**
```javascript
// Create audio objects
// Креирајте аудио објекте
const laserSound = new Audio('assets/laser.wav');
const explosionSound = new Audio('assets/explosion.wav');
// Play sounds during game events
// Репродукујте звуке током догађаја у игри
function playLaserSound() {
laserSound.currentTime = 0; // Reset to beginning
laserSound.currentTime = 0; // Ресетујте на почетак
laserSound.play();
}
```
**Шта треба да знате:**
- **Креира** Audio објекте за различите звучне ефекте
- **Ресетује** `currentTime` ради омогућавања брзих звучних ефеката
- **Рукује** политикама
- **Ресетује** `currentTime` да би омогућио брзе звучне ефекте
- **Решава** политике аутоматске репродукције прегледача покретањем звукова из корисничких интеракција
- **Управља** јачином звука и тајмингом за боље играчко искуство
> 💡 **Ресурс за учење**: Истражите овај [аудио sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) да бисте сазнали више о имплементацији звука у JavaScript играма.
## Квиз након предавања
[Квиз након предавања](https://ff-quizzes.netlify.app/web/quiz/40)
## Ревизија и самоучење
Ваш задатак је да направите свежу пример игру, па истражите неке од занимљивих игара да бисте видели какву игру бисте можда могли направити.
## Задатак
[Направите пример игру](assignment.md)
---
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу произаћи из коришћења овог превода.
Овај документ је преведен помоћу AI сервиса за превођење [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде прецизан, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом матерњем језику треба сматрати званичним извором. За кључне информације препоруучује се професионални превод од стране стручног лојалног преводиоца. Нисмо одговорни за било каква неразумевања или погрешне тумачења која проистекну из употребе овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -1,51 +1,96 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "5d259f6962464ad91e671083aa0398f4",
"translation_date": "2025-10-24T23:32:17+00:00",
"original_hash": "351678bece18f07d9daa987a881fb062",
"translation_date": "2026-01-07T08:11:17+00:00",
"source_file": "7-bank-project/1-template-route/README.md",
"language_code": "sr"
}
-->
# Изградња апликације за банкарство, део 1: HTML шаблони и руте у веб апликацији
# Израда банковне апликације део 1: HTML шаблони и руте у веб апликацији
Када је рачунар за навигацију Аполо 11 мисије водио лет на Месец 1969. године, морао је да прелази између различитих програма без поновног покретања целог система. Савремене веб апликације функционишу на сличан начин мењају оно што видите без поновног учитавања целокупног садржаја. Ово ствара глатко и одзивно корисничко искуство које се данас очекује.
```mermaid
journey
title Ваш пут развоја банкарске апликације
section Основе SPA
Разумети апликације једне странице: 3: Student
Учити концепте шаблона: 4: Student
Савладати манипулацију DOM-ом: 4: Student
section Системи рутирања
Имплементирати рутирање на страни клијента: 4: Student
Управљати историјом прегледача: 5: Student
Креирати системе навигације: 5: Student
section Професионални обрасци
Градити модуларну архитектуру: 5: Student
Примeњивати добре праксе: 5: Student
Креирати корисничка искуства: 5: Student
```
Када је оријентациони рачунар Аполо 11 навигационо усмеравао на Месец 1969. године, морао је да пребацује између различитих програма без поновног покретања целог система. Савремене веб апликације функционишу слично промене оно што видите без поновног учитавања свега из почетка. Ово ствара глатко, одзивно искуство које корисници данас очекују.
За разлику од традиционалних веб сајтова који поново учитавају целе странице за сваку интеракцију, савремене веб апликације ажурирају само делове који треба да се промене. Овај приступ, сличан начину на који контролни центар прелази између различитих приказа док одржава сталну комуникацију, ствара флуидно искуство које смо навикли да очекујемо.
За разлику од традиционалних сајтова који поново учитавају целе странице за сваку интеракцију, модерне веб апликације ажурирају само делове који захтевају промену. Овај приступ, баш као што контрола мисије пребацује између различитих приказа уз одржавање константне комуникације, ствара оно течемо искуство које смо навикли да очекујемо.
Ево шта чини разлику тако драматичном:
Ево шта прави драматичну разлику:
| Традиционалне апликације са више страница | Савремене апликације са једном страницом |
|------------------------------------------|------------------------------------------|
| Традиционалне мултипејџ апликације | Модерне једнопејџ апликације |
|----------------------------|-------------------------|
| **Навигација** | Поновно учитавање целе странице за сваки екран | Инстантно пребацивање садржаја |
| **Перформансе** | Спорије због комплетног преузимања HTML-а | Брже са делимичним ажурирањима |
| **Корисничко искуство** | Нагли прелази између страница | Глатке, апликацијске транзиције |
| **Перформансе** | Спорије због потпуног преузимања HTML-а | Брже са делимичним ажурирањима |
| **Корисничко искуство** | Непријатни поздравни флеџеви на страници | Глатки, апликацијски прелази |
| **Дељење података** | Тешко између страница | Лако управљање стањем |
| **Развој** | Одржавање више HTML датотека | Један HTML са динамичким шаблонима |
| **Развој** | Више HTML фајлова за одржавање | Један HTML са динамичким шаблонима |
**Разумевање еволуције:**
- **Традиционалне апликације** захтевају серверске захтеве за сваку навигациону акцију
- **Савремене SPA** се учитавају једном и динамички ажурирају садржај користећи JavaScript
- **Очекивања корисника** сада фаворизују инстантне, беспрекорне интеракције
- **Предности перформанси** укључују смањену потрошњу пропусног опсега и брже одговоре
- **Традиционалне апликације** захтевају упите серверу за сваки корак навигације
- **Модерне Једнопејџ апликације (СПА)** учитавају једном и динамички мењају садржај користећи JavaScript
- **Корисничка очекивања** сада фаворизују тренутне и беспрекорне интеракције
- **Предности перформанси** укључују смањени саобраћај и брже одговоре
У овом лекцији, направићемо апликацију за банкарство са више екрана који се беспрекорно међусобно повезују. Као што научници користе модуларне инструменте који се могу конфигурисати за различите експерименте, ми ћемо користити HTML шаблоне као поново употребљиве компоненте које се могу приказати по потреби.
У овој лекцији, направићемо банковну апликацију са више екрана који се беспрекорно надовезују. Баш као што научници користе модуларне инструменте који се могу реконфигурисати за различите експерименте, користићемо HTML шаблоне као поновно употребљиве компоненте које могу бити приказане по потреби.
Радићете са HTML шаблонима (поново употребљивим нацртима за различите екране), JavaScript рутама (системом који омогућава пребацивање између екрана) и API-јем историје прегледача (који омогућава да дугме за повратак ради како треба). Ово су исте основне технике које користе оквири као што су React, Vue и Angular.
Радићете са HTML шаблонима (поновно употребљивим плановима за различите екране), JavaScript рутингом (систем који пребацује између екрана), и API-јем историје прегледача (који омогућава да дугме назад функционише како треба). Ово су исте фундаменталне технике које користе оквири као што су React, Vue, и Angular.
На крају, имаћете функционалну апликацију за банкарство која демонстрира професионалне принципе апликација са једном страницом.
До краја, имаћете радну банковну апликацију која демонстрира професионалне принципе једнопејџ апликације.
## Квиз пре предавања
```mermaid
mindmap
root((Јединствене апликације са једном страницом))
Architecture
Template System
Client-side Routing
State Management
Event Handling
Templates
Reusable Components
Dynamic Content
DOM Manipulation
Content Switching
Routing
Управљање УРЛ-ом
History API
Логика навигације
Интеграција претраживача
User Experience
Брза навигација
Глатке транзиције
Конзистентно стање
Модерне интеракције
Performance
Смањени захтеви ка серверу
Брже прелазе странице
Ефикасна употреба ресурса
Боља одзивност
```
## Пре теста предавања
[Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/41)
[Тест предавања](https://ff-quizzes.netlify.app/web/quiz/41)
### Шта ће вам бити потребно
### Шта ћете морати имати
Биће нам потребан локални веб сервер за тестирање наше апликације за банкарство не брините, то је лакше него што звучи! Ако га већ немате подешеног, само инсталирајте [Node.js](https://nodejs.org) и покрените `npx lite-server` из вашег пројектног фолдера. Ова корисна команда покреће локални сервер и аутоматски отвара вашу апликацију у прегледачу.
Потребан нам је локални веб сервер да бисмо тестирали нашу банковну апликацију не брините, лакше је него што звучи! Ако већ немате један постављен, само инсталирајте [Node.js](https://nodejs.org) и покрените `npx lite-server` из вашег пројект фолдера. Ова корисна команда покреће локални сервер и аутоматски отвара вашу апликацију у прегледачу.
### Припрема
На вашем рачунару, направите фолдер под називом `bank` са датотеком `index.html` унутар њега. Почећемо од овог HTML [основног шаблона](https://en.wikipedia.org/wiki/Boilerplate_code):
На вашем рачунару направите фасциклу под називом `bank` у коју убаците фајл по имену `index.html`. Почећемо са овим HTML [бојлерплејтом](https://en.wikipedia.org/wiki/Boilerplate_code):
```html
<!DOCTYPE html>
@ -61,16 +106,16 @@ CO_OP_TRANSLATOR_METADATA:
</html>
```
**Ево шта овај основни шаблон пружа:**
- **Успоставља** структуру HTML5 документа са правилном декларацијом DOCTYPE-а
- **Конфигурише** кодирање карактера као UTF-8 за подршку међународног текста
- **Омогућава** одзивни дизајн са мета тагом за приказ за мобилну компатибилност
- **Поставља** описни наслов који се појављује на картици прегледача
- **Креира** чисту секцију тела где ћемо изградити нашу апликацију
**Ово што овај бојлерплејт обезбеђује:**
- **Успоставља** HTML5 структуру документа са правилном DOCTYPE декларацијом
- **Конфигурише** енкодирање карактера као UTF-8 за међународну подршку текста
- **Омогућава** респонзивни дизајн преко viewport meta тега за мобилне уређаје
- **Поставља** описни наслов који се појављује на табу прегледача
- **Креира** чисто тело странице где ћемо градити нашу апликацију
> 📁 **Преглед структуре пројекта**
>
> **На крају ове лекције, ваш пројекат ће садржати:**
> **До краја ове лекције, ваш пројекат ће садржати:**
> ```
> bank/
> ├── index.html <!-- Main HTML with templates -->
@ -78,43 +123,60 @@ CO_OP_TRANSLATOR_METADATA:
> └── style.css <!-- (Optional for future lessons) -->
> ```
>
> **Одговорности датотека:**
> **Одговорности фајлова:**
> - **index.html**: Садржи све шаблоне и пружа структуру апликације
> - **app.js**: Управља рутама, навигацијом и управљањем шаблонима
> - **Шаблони**: Дефинишу кориснички интерфејс за пријаву, контролни панел и друге екране
> - **app.js**: Управља рутирањем, навигацијом и управљањем шаблонима
> - **Шаблони**: Дефинишу кориснички интерфејс за пријаву, контролни панел и остале екране
---
## HTML шаблони
## HTML Шаблони
Шаблони решавају основни проблем у веб развоју. Када је Гутенберг изумео покретну штампарску машину 1440-их, схватио је да уместо да урезује целе странице, може да направи поново употребљиве блокове слова и да их распоређује по потреби. HTML шаблони функционишу на истом принципу уместо да креирате засебне HTML датотеке за сваки екран, дефинишете поново употребљиве структуре које се могу приказати по потреби.
Шаблони решавају фундаментални проблем у веб развоју. Када је Гутенберг измислио покретни сликовни тип штампе 1440-их, схватио је да уместо вађења целих страна, може да направи поновно употребљиве словне блокове и распоређује их по потреби. HTML шаблони раде по истом принципу уместо да стварате посебне HTML фајлове за сваки екран, дефинишете поновно употребљиве структуре које се могу приказати по потреби.
Размислите о шаблонима као о нацртима за различите делове ваше апликације. Као што архитекта креира један нацрт и користи га више пута уместо да поново црта идентичне просторије, ми креирамо шаблоне једном и користимо их по потреби. Прегледач држи ове шаблоне скривеним док их JavaScript не активира.
```mermaid
flowchart TD
A["📋 Дефиниција шаблона"] --> B["💬 Сакривено у DOM-у"]
B --> C["🔍 JavaScript пронађе шаблон"]
C --> D["📋 Клонирај садржај шаблона"]
D --> E["🔗 Привежи за видљиви DOM"]
E --> F["👁️ Корисник види садржај"]
G["Шаблон за пријаву"] --> A
H["Шаблон контролне табле"] --> A
I["Будући шаблони"] --> A
style A fill:#e3f2fd
style D fill:#e8f5e8
style F fill:#fff3e0
style B fill:#f3e5f5
```
Размислите о шаблонима као о плановима за различите делове ваше апликације. Баш као што архитекта направи један план и користи га више пута уместо да поново црта идентичне просторије, ми једном креирамо шаблоне и инстанцирамо их по потреби. Прегледач држи ове шаблоне скривеним док их JavaScript не активира.
Ако желите да креирате више екрана за веб страницу, једно решење би било да направите једну HTML датотеку за сваки екран који желите да прикажете. Међутим, ово решење долази са одређеним непогодностима:
Ако желите да направите више екрана за једну веб страницу, једно од решења било би да направите један HTML фајл за сваки екран који желите да прикажете. Међутим, то решење има неколико непријатности:
- Морате поново учитати целу HTML датотеку приликом преласка на други екран, што може бити споро.
- Морате поново учитавати цео HTML када прелазите са екрана на екран, што може бити споро.
- Тешко је делити податке између различитих екрана.
Друга опција је да имате само једну HTML датотеку и дефинишете више [HTML шаблона](https://developer.mozilla.org/docs/Web/HTML/Element/template) користећи елемент `<template>`. Шаблон је поново употребљив HTML блок који прегледач не приказује, а потребно га је инстанцирати у време извршења помоћу JavaScript-а.
Други приступ је да имате само један HTML фајл и дефинишете више [HTML шаблона](https://developer.mozilla.org/docs/Web/HTML/Element/template) користећи елемент `<template>`. Шаблон је поновно употребљив HTML блок који прегледач не приказује, и који мора бити инстанциран у време извршавања коришћењем JavaScript-а.
### Хајде да направимо
### Хајде да га направимо
Направићемо апликацију за банкарство са два главна екрана: страницу за пријаву и контролни панел. Прво, додајмо елемент за резервисано место у тело HTML-а овде ће се појављивати сви наши различити екрани:
Правићемо банковну апликацију са два главна екрана: страницу за пријаву и контролни панел. Прво, додајмо елемент простора за приказ (placeholder) у тело нашег HTML-а овде ће се појављивати сви наши различити екрани:
```html
<div id="app">Loading...</div>
```
**Разумевање овог резервисаног места:**
**Разумевање овог преваземања (placeholder):**
- **Креира** контејнер са ID-јем "app" где ће се приказивати сви екрани
- **Приказује** поруку о учитавању док JavaScript не иницијализује први екран
- **Приказује** поруку за учитавање док Javascript не иницијализује први екран
- **Обезбеђује** једну тачку за монтирање нашег динамичког садржаја
- **Омогућава** лако циљање из JavaScript-а користећи `document.getElementById()`
- **Омогућава** лако дохватање из JavaScript-а користећи `document.getElementById()`
> 💡 **Савет**: Пошто ће садржај овог елемента бити замењен, можемо ставити поруку о учитавању или индикатор који ће се приказивати док се апликација учитава.
> 💡 **Совет експерта**: Пошто ће садржај овог елемента бити замењен, можемо ставити поруку или индикатор учитавања која ће се показивати док апликација учитава.
Затим, додајмо HTML шаблон за страницу за пријаву. За сада ћемо само додати наслов и секцију која садржи линк који ћемо користити за навигацију.
Даље, додамо испод HTML шаблон за страницу за пријаву. За сада ћемо ставити само наслов и одељак који садржи везу којом ћемо извршавати навигацију.
```html
<template id="login">
@ -125,17 +187,17 @@ CO_OP_TRANSLATOR_METADATA:
</template>
```
**Разлагање овог шаблона за пријаву:**
- **Дефинише** шаблон са јединственим идентификатором "login" за циљање из JavaScript-а
**Разломак овог шаблона за пријаву:**
- **Дефинише** шаблон са јединственим идентификатором "login" за добијање из JavaScript-а
- **Укључује** главни наслов који успоставља бренд апликације
- **Садржи** семантички елемент `<section>` за груписање повезаног садржаја
- **Обезбеђује** навигациони линк који ће усмерити кориснике на контролни панел
- **Садржи** семантички `<section>` елемент за груписање сродног садржаја
- **Обезбеђује** навигациони линк који ће усмеравати кориснике ка контролном панелу
Затим ћемо додати још један HTML шаблон за страницу контролног панела. Ова страница ће садржати различите секције:
- Заглавље са насловом и линком за одјаву
- Тренутни баланс банковног рачуна
- Листа трансакција, приказана у табели
- Тренутни стање рачуна у банци
- Листу трансакција приказану у табели
```html
<template id="dashboard">
@ -163,72 +225,87 @@ CO_OP_TRANSLATOR_METADATA:
```
**Разумевање сваког дела овог контролног панела:**
- **Структурира** страницу са семантичким елементом `<header>` који садржи навигацију
- **Приказује** наслов апликације конзистентно на свим екранима ради брендирања
- **Обезбеђује** линк за одјаву који води назад на страницу за пријаву
- **Приказује** тренутни баланс рачуна у посебној секцији
- **Организује** податке о трансакцијама користећи правилно структурисану HTML табелу
- **Структурира** страницу семантичким `<header>` елементом који садржи навигацију
- **Приказује** наслов апликације конзистентно преко свих екрана ради брендирања
- **Обезбеђује** линк за одјаву који води назад на екран за пријаву
- **Приказује** тренутан салдо рачуна у посебном одељку
- **Организује** податке о трансакцијама користећи правилно структурирану HTML табелу
- **Дефинише** заглавља табеле за колоне Датум, Објекат и Износ
- **Оставља** тело табеле празно за касније динамичко убацивање садржаја
- **Оставља** тело табеле празно за динамичко уметање садржаја касније
> 💡 **Совет експерта**: Када правите HTML шаблоне, ако желите да видите како ће изгледати, можете коментарисати `<template>` и `</template>` линије користећи `<!-- -->`.
> 💡 **Савет**: Када креирате HTML шаблоне, ако желите да видите како ће изгледати, можете коментарисати линије `<template>` и `</template>` тако што ћете их обухватити са `<!-- -->`.
### 🔄 **Педагошки преглед**
**Разумевање система шаблона**: Пре него што имплементирате JavaScript проверите да ли разумете:
- ✅ Како се шаблони разликују од уобичајених HTML елемената
- ✅ Зашто шаблони остају скривени док их JavaScript не активира
- ✅ Значај семантичке HTML структуре у шаблонима
- ✅ Како шаблони омогућавају поновну употребу UI компоненти
✅ Зашто мислите да користимо `id` атрибуте на шаблонима? Да ли бисмо могли да користимо нешто друго, као што су класе?
**Брзи самотест**: Шта се дешава ако уклоните `<template>` тагове око вашег HTML-а?
*Одговор: Садржај постаје одмах видљив и губи функцију шаблона*
## Оживљавање шаблона помоћу JavaScript-а
**Предности архитектуре**: Шаблони пружају:
- **Поновну употребљивост**: Једна дефиниција, више инстанци
- **Перформансе**: Није потребно поновно парсирање HTML-а
- **Одрживост**: Централизована UI структура
- **Флексибилност**: Динамично пребацивање садржаја
Сада треба да учинимо наше шаблоне функционалним. Као што 3D штампач узима дигитални нацрт и ствара физички објекат, JavaScript узима наше скривене шаблоне и ствара видљиве, интерактивне елементе које корисници могу да виде и користе.
✅ Зашто мислите да користимо атрибуте `id` на шаблонима? Да ли бисмо могли да употребимо нешто друго као класе?
Процес следи три конзистентна корака који чине основу савременог веб развоја. Када разумете овај образац, препознаћете га у многим оквирима и библиотекама.
## Оживљавање шаблона уз JavaScript
Ако пробате вашу тренутну HTML датотеку у прегледачу, видећете да се заглавила приказујући `Loading...`. То је зато што треба да додамо неки JavaScript код да бисмо инстанцирали и приказали HTML шаблоне.
Сада треба да учинимо наше шаблоне функционалним. Баш као што 3Д штампач узима дигитални план и ствара физички објекат, JavaScript узима наше скривене шаблоне и креира видљиве, интерактивне елементе које корисници могу видети и користити.
Процес прати три конзистентна корака која чине темеље модерног веб развоја. Када разумете овај образац, препознаћете га у многим оквирима и библиотекама.
Ако пробате свој тренутни HTML фајл у прегледачу, видећете да заглави приказујући `Loading...`. То је зато што морамо додати неки JavaScript код да инстанцирамо и прикажемо HTML шаблоне.
Инстанцирање шаблона обично се ради у 3 корака:
1. Проналажење елемента шаблона у DOM-у, на пример користећи [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById).
2. Клонирање елемента шаблона, користећи [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode).
3. Прикључивање на DOM испод видљивог елемента, на пример користећи [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild).
1. Проналазак елемента шаблона у DOM-у, на пример коришћењем [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById).
2. Клонирање елемента шаблона, коришћењем [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode).
3. Прикључивање на DOM испод видљивог елемента, на пример коришћењем [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild).
```mermaid
flowchart TD
A[🔍 Step 1: Find Template] --> B[📋 Step 2: Clone Template]
B --> C[🔗 Step 3: Attach to DOM]
A[🔍 Корак 1: Пронађи шаблон] --> B[📋 Корак 2: Клонирај шаблон]
B --> C[🔗 Корак 3: Прикачи на DOM]
A1["document.getElementById('login')"] --> A
B1["template.content.cloneNode(true)"] --> B
C1["app.appendChild(view)"] --> C
C --> D[👁️ Template Visible to User]
C --> D[👁️ Шаблон видљив кориснику]
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#e8f5e8
style D fill:#fff3e0
```
**Визуелни приказ процеса:**
- **Корак 1** проналази скривени шаблон у структури DOM-а
- **Корак 2** креира радну копију која се може безбедно модификовати
- **Корак 3** убацује копију у видљиву област странице
- **Резултат** је функционалан екран са којим корисници могу да интерагују
- **Корак 1** лоцира скривени шаблон у DOM структури
- **Корак 2** креира радну копију која се безбедно може мењати
- **Корак 3** убацује копију у видљиви део странице
- **Резултат** је функционалан екран са којим корисници могу интераговати
✅ Зашто је потребно клонирати шаблон пре него што га прикључимо на DOM? Шта мислите да би се десило ако бисмо прескочили овај корак?
✅ Зашто је потребно клонирати шаблон пре него што га прикључимо у DOM? Шта мислите шта би се десило ако прескочимо овај корак?
### Задатак
Направите нову датотеку под називом `app.js` у вашем пројектном фолдеру и увезите ту датотеку у `<head>` секцију вашег HTML-а:
Направите нови фајл по имену `app.js` у вашем пројект фолдеру и укључите тај фајл у `<head>` секцију вашег HTML-а:
```html
<script src="app.js" defer></script>
```
**Разумевање овог увоза скрипте:**
- **Повезује** JavaScript датотеку са нашим HTML документом
- **Користи** атрибут `defer` како би се осигурало да се скрипта покрене након што се HTML парсира
**Разумевање увоза овог скрипта:**
- **Повезује** JavaScript фајл са нашим HTML документом
- **Користи** атрибут `defer` да обезбеди да се скрипта изврши након што се HTML парсира
- **Омогућава** приступ свим DOM елементима пошто су потпуно учитани пре извршења скрипте
- **Прати** савремене најбоље праксе за учитавање скрипти и перформансе
- **Праћење** савремених најбољих пракси учитавања скрипти и перформанси
Сада у `app.js`, направићемо нову функцију `updateRoute`:
Сада у `app.js` направићемо нову функцију `updateRoute`:
```js
function updateRoute(templateId) {
@ -241,11 +318,11 @@ function updateRoute(templateId) {
```
**Корак по корак, ево шта се дешава:**
- **Проналази** елемент шаблона користећи његов јединствени ID
- **Лоцира** елемент шаблона користећи његов јединствени ID
- **Креира** дубоку копију садржаја шаблона користећи `cloneNode(true)`
- **Проналази** контејнер апликације где ће се садржај приказати
- **Чисти** било који постојећи садржај из контејнера апликације
- **Убацује** клонирани садржај шаблона у видљиви DOM
- **Пронађе** контејнер апликације где ће садржај бити приказан
- **Обрише** сваки постојећи садржај из контејнера апликације
- **Убаци** клонирани садржај шаблона у видљиви DOM
Сада позовите ову функцију са једним од шаблона и погледајте резултат.
@ -253,79 +330,200 @@ function updateRoute(templateId) {
updateRoute('login');
```
**Шта овај позив функције постиже:**
- **Активира** шаблон за пријаву прослеђујући његов ID као параметар
- **Демонстрира** како програмски пребацивати између различитих екрана апликације
**Оно што овај позив функције постиже:**
- **Активира** шаблон за пријаву преносом његовог ID као параметра
- **Демонстрира** како се програмски пребацује између различитих екрана апликације
- **Приказује** екран за пријаву уместо поруке "Loading..."
Која је сврха овог кода `app.innerHTML = '';`? Шта се дешава без њега?
Која је сврха ове линије кода `app.innerHTML = '';`? Шта се дешава без ње?
## Креирање рута
Рутирање се у суштини односи на повезивање URL-ова са одговарајућим садржајем. Замислите како су рани телефонски оператери користили прекидачке табле за повезивање позива узимали би долазни захтев и усмеравали га на исправну дестинацију. Веб рутирање функционише на сличан начин, узимајући URL захтев и одређујући који садржај да се прикаже.
Традиционално, веб сервери су то радили служећи различите HTML датотеке за различите URL-ове. Пошто градимо апликацију са једном страницом, морамо сами да управљамо овим рутирањем помоћу JavaScript-а. Овај приступ нам даје већу контролу над корисничким искуством и перформансама.
Рутација је у суштини повезивање URL-ова са правим садржајима. Размислите како су рани телефонски оператери користили спрежне табле да повезују позиве узимали би долазни захтев и усмеравали га на исправну дестинацију. Веб рутирање функционише слично, узима URL захтев и одређује који садржај приказати.
```mermaid
flowchart LR
A["🌐 URL Path<br/>/dashboard"] --> B["🗺️ Routes Object<br/>Lookup"]
B --> C["🎯 Template ID<br/>'dashboard'"]
C --> D["📄 Find Template<br/>getElementById"]
D --> E["👁️ Display Screen<br/>Clone & Append"]
A["🌐 URL Путања<br/>/dashboard"] --> B["🗺️ Објекат Рута<br/>Преглед"]
B --> C["🎯 ИД Шаблона<br/>'dashboard'"]
C --> D["📌 Пронађи Шаблон<br/>getElementById"]
D --> E["👁️ Прикажи Екран<br/>Клонирај & Додај"]
F["📍 /login"] --> G["🎯 'login'"]
H["📍 /unknown"] --> I["❌ Not Found"]
I --> J["🔄 Redirect to /login"]
H["📍 /unknown"] --> I["❌ Није Пронађено"]
I --> J["🔄 Преусмери на /login"]
style B fill:#e3f2fd
style E fill:#e8f5e8
style I fill:#ffebee
style J fill:#fff3e0
```
Традиционално, веб сервери су то решавали тако што су служили различите HTML фајлове за различите URL-ове. Пошто правимо једнопејџ апликацију, морамо то сами решити са JavaScript-ом. Овај приступ нам даје већу контролу над корисничким искуством и перформансама.
**Разумевање тока рутирања:**
```mermaid
flowchart LR
A["🌐 URL путања<br/>/dashboard"] --> B["🗺️ Објекат рута<br/>Потрага"]
B --> C["🎯 ИД шаблона<br/>'dashboard'"]
C --> D["📄 Пронађи шаблон<br/>getElementById"]
D --> E["👁️ Прикажи екран<br/>Клонирај & Додај"]
F["📍 /login"] --> G["🎯 'login'"]
H["📍 /unknown"] --> I["❌ Није пронађено"]
I --> J["🔄 Преусмери на /login"]
style B fill:#e3f2fd
style E fill:#e8f5e8
style I fill:#ffebee
style J fill:#fff3e0
```
**Разумевање протока рутирања:**
- **Промене URL-а** покрећу претрагу у нашој конфигурацији рута
- **Важеће руте** се мапирају на одређене ID-јеве шаблона за приказ
- **Неважеће руте** покрећу резервно понашање како би се избегла неисправна стања
- **Приказ шаблона** следи тростепени процес који смо раније научили
- **Валидне руте** се мапирају на одређене ID-ове шаблона за приказ
- **Невалидне руте** изазивају резервно понашање да спрече кварове стања
- **Приказ шаблона** следи трех корака процес који смо раније научили
Када говоримо о веб апликацији, *рутирање* називамо намеру да се **URL-ови** повежу са специфичним екранима који треба да се прикажу. На сајту са више HTML фајлова, ово се аутоматски ради пошто су путање фајлова приказане у URL-у. На пример, са овим фајловима у вашем пројект фолдеру:
```
mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html
```
Ако направите веб сервер са `mywebsite` као кореном, мапирање URL ће бити:
```
https://site.com --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
```
Међутим, за нашу веб апликацију користимо један HTML фајл који садржи све екране, па нам ово подразумевано понашање неће помоћи. Морамо ручно направити ову мапу и ажурирати приказани шаблон коришћењем JavaScript-а.
### Задатак
Користићемо једноставан објекат да имплементирамо [мапу](https://en.wikipedia.org/wiki/Associative_array) између URL путања и наших шаблона. Додајте овај објекат на врх вашег фајла `app.js`.
```js
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard' },
};
```
**Разумевање ове конфигурације рута:**
- **Дефинише** мапирање између URL путева и идентификатора шаблона
- **Користи** синтаксу објекта где су кључеви URL путеви, а вредности садрже информације о шаблонима
- **Омогућава** лако проналажење који шаблон приказати за било који дати URL
- **Пружа** скалабилну структуру за додавање нових рута у будућности
Хајде сада мало да изменимо функцију `updateRoute`. Уместо да директно прослеђујемо `templateId` као аргумент, желимо прво да га добијемо тако што ћемо погледати тренутну URL адресу, а затим користити нашу мапу да добијемо одговарајућу вредност ID шаблона. Можемо користити [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) да добијемо само део пута из URL-а.
```js
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
Када говоримо о веб апликацији, називамо *рутирање* намером да се мапирају **URL-ови** на одређене екране који треба да се прикажу. На веб сајту са више HTML датотека, ово се аутоматски ради јер се путање датотека одражавају на URL-у.
✅ Шта се дешава ако унесете непознату путању у URL? Како бисмо могли да решимо овај проблем?
const template = document.getElementById(route.templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
}
```
**Објашњење шта се овде дешава:**
- **Извлачи** тренутни пут из URL-а прегледача користећи `window.location.pathname`
- **Тражи** одговарајућу конфигурацију руте у нашем објекту рута
- **Добија** ID шаблона из конфигурације руте
- **Практикује** исти процес рендеровања шаблона као и раније
- **Прави** динамички систем који реагује на промене URL-а
Овде смо мапирали руте које смо декларисали на одговарајуће шаблоне. Можете пробати да промените URL ручно у прегледачу и проверите да ли ради исправно.
✅ Шта ће се десити ако унесете непознату путању у URL? Како бисмо то могли решити?
## Додавање навигације
Са успостављеним рутирањем, корисницима је потребан начин да се крећу кроз апликацију. Традиционални веб-сајтови поново учитавају целе странице када се кликне на линкове, али ми желимо да ажурирамо и URL и садржај без освежавања странице. Ово ствара глатко искуство слично ономе како десктоп апликације мењају различите приказе.
Када имамо рутинг, корисницима је потребан начин да се крећу кроз апликацију. Традиционални веб-сајтови освежавају целе странице када се кликне на линкове, али ми желимо да ажурирамо и URL и садржај без освежавања странице. Ово ствара глаткије искуство слично томе како десктоп апликације пребацују између различитих приказа.
Потребно је координирати две ствари: ажурирање URL-а у прегледачу како би корисници могли да обележавају странице и деле линкове, и приказивање одговарајућег садржаја. Када се правилно имплементира, ово ствара беспрекорну навигацију коју корисници очекују од модерних апликација.
Треба да координирамо две ствари: ажурирање URL-а у прегледачу да корисници могу да означе странице и деле линкове и приказивање одговарајућег садржаја. Када је имплементирано исправно, ово ствара беспрекорну навигацију коју корисници очекују од модерних апликација.
> 🏗️ **Увид у архитектуру**: Компоненте навигационог система
```mermaid
sequenceDiagram
participant User
participant Browser
participant App
participant Template
User->>Browser: Кликне на "Пријава" линк
Browser->>App: onclick догађај активиран
App->>App: preventDefault() & navigate('/dashboard')
App->>Browser: history.pushState('/dashboard')
Browser->>Browser: URL се ажурира на /dashboard
App->>App: позива се updateRoute()
App->>Template: Пронађи и клонирај шаблон контролне табле
Template->>App: Враћа клонирани садржај
App->>Browser: Замени садржај апликације шаблоном
Browser->>User: Прикажи екран контролне табле
Note over User,Template: Корисник кликне на назад дугме прегледача
User->>Browser: Кликне назад дугме
Browser->>Browser: Историја се враћа на /login
Browser->>App: попстате догађај активиран
App->>App: аутоматски позив updateRoute()
App->>Template: Пронађи и клонирај шаблон пријаве
Template->>App: Враћа клонирани садржај
App->>Browser: Замени садржај апликације шаблоном
Browser->>User: Прикажи екран пријаве
```
### 🔄 **Педагошки преглед**
**Архитектура једностраничне апликације (SPA)**: Потврдите ваше разумевање целог система:
- ✅ Каква је разлика између рутирања са стране клијента и традиционалног рутирања на серверу?
- ✅ Зашто је History API непоходан за исправну SPA навигацију?
- ✅ Како шаблони омогућавају динамички садржај без освежавања странице?
- ✅ Коју улогу има управљање догађајима у пресретању навигације?
**Интеграција система**: Ваша SPA демонстрира:
- **Управљање шаблонима**: Поновно употребљиви UI компоненти са динамичким садржајем
- **Рутирање на страни клијента**: Управљање URL-ом без захтева серверу
- **Архитектуру вођену догађајима**: Респонзивна навигација и интеракције корисника
- **Интеграцију са претраживачем**: Подршка за историју и дугмад назад/напред
- **Оптимизацију перформанси**: Брзе транзиције и смањено оптерећење сервера
**Професионални обрасци**: Имплементирали сте:
- **Раздвајање модела и приказа**: Шаблони одвојени од логике апликације
- **Управљање стањем**: Синхронизација URL-а и приказаног садржаја
- **Прогресивно побољшање**: JavaScript побољшава основну HTML функционалност
- **Корисничко искуство**: Глатка навигација слична апликацијама без освежавања странице
> <20> **Увид у архитектуру**: Компоненте навигационог система
>
> **Шта градите:**
> - **🔄 Управљање URL-ом**: Ажурира адресну траку прегледача без поновног учитавања странице
> - **📋 Систем шаблона**: Динамички мења садржај на основу тренутне руте
> - **📚 Интеграција историје**: Одржава функционалност дугмади за назад/напред у прегледачу
> - **🛡️ Обрада грешака**: Елегантни механизми за случај неважећих или недостајућих рута
> - **🔄 Управљање URL-ом**: Ажурира адресну траку прегледача без освежавања
> - **📋 Систем шаблона**: Динамичка замена садржаја према тренутној рути
> - **📚 Интеграција историје**: Одржава подршку за дугмад назад и напред
> - **🛡️ Управљање грешкама**: Фоллбек механизми за неважеће или нестале руте
>
> **Како компоненте раде заједно:**
> - **Слушају** догађаје навигације (кликове, промене историје)
> - **Слушају** догађаје навигације (кликови, промене историје)
> - **Ажурирају** URL користећи History API
> - **Приказују** одговарајући шаблон за нову руту
> - **Одржавају** беспрекорно корисничко искуство током целе апликације
> - **Рендерују** одговарајући шаблон за нову руту
> - **Одржавају** беспрекорно корисничко искуство
Следећи корак за нашу апликацију је додавање могућности навигације између страница без потребе за ручним мењањем URL-а. Ово подразумева две ствари:
Следећи корак је да додамо могућност навигације између страница без потребе за ручним мењањем URL-а. То подразумева две ствари:
1. Ажурирање тренутног URL-а
2. Ажурирање приказаног шаблона на основу новог URL-а
1. Ажурирање тренутног URL-а
2. Ажурирање приказаног шаблона према новом URL-у
Већ смо се побринули за други део помоћу функције `updateRoute`, тако да морамо да смислимо како да ажурирамо тренутни URL.
Већ смо се позабавили другом тачком помоћу функције `updateRoute`, сада треба да смислимо како да ажурирамо тренутни URL.
Мораћемо да користимо JavaScript, а конкретно [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) који омогућава ажурирање URL-а и креирање новог уноса у историји прегледања, без поновног учитавања HTML-а.
Морамо да користимо JavaScript, а конкретно [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) која омогућава ажурирање URL-а и додавање новог уноса у историју прегледања без ре-учитавања HTML-а.
> ⚠️ **Важно обавештење**: Иако HTML елемент за сидро [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) може самостално да се користи за креирање хиперлинкова ка различитим URL-овима, он ће подразумевано натерати прегледач да поново учита HTML. Неопходно је спречити ово понашање када се рутирање обрађује прилагођеним JavaScript-ом, користећи функцију preventDefault() на догађају клика.
> ⚠️ **Важна напомена**: Иако се HTML елемент анкера [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) може користити самостално за хиперлинкове ка различитим URL-овима, он ће по подразумеваној поставци узроковати ре-учитавање странице. Потребно је спречити то понашање када рукујемо рутирањем помоћу прилагођеног JavaScript-а, користећи preventDefault() функцију на догађају клика.
### Задатак
### Задаци
Хајде да направимо нову функцију коју можемо користити за навигацију у нашој апликацији:
Направимо нову функцију коју можемо користити за навигацију у нашој апликацији:
```js
function navigate(path) {
@ -333,16 +531,16 @@ function navigate(path) {
updateRoute();
}
```
**Разумевање ове функције за навигацију:**
- **Ажурира** URL прегледача на нову путању користећи `history.pushState`
- **Додаје** нови унос у историју прегледача за правилну подршку дугмади назад/напред
- **Покреће** функцију `updateRoute()` за приказ одговарајућег шаблона
- **Одржава** искуство апликације са једном страницом без поновног учитавања странице
Ова метода прво ажурира тренутни URL на основу дате путање, а затим ажурира шаблон. Својство `window.location.origin` враћа корен URL-а, омогућавајући нам да реконструишемо комплетан URL из дате путање.
**Објашњење ове навигационе функције:**
- **Ажурира** URL прегледача на нову путању користећи `history.pushState`
- **Додаје** нови унос у тај стек историје прегледача за исправно коришћење дугмади назад/напред
- **Покреће** функцију `updateRoute()` да прикаже одговарајући шаблон
- **Одржава** искуство једностраничне апликације без освежавања странице
Сада када имамо ову функцију, можемо се позабавити проблемом који имамо ако путања не одговара ниједној дефинисаној рути. Модификоваћемо функцију `updateRoute` додавањем резервне опције за једну од постојећих рута ако не можемо да пронађемо одговарајућу.
Овај метод прво ажурира тренутни URL заснован на датој путањи, а затим ажурира шаблон. Својство `window.location.origin` враћа корен URL-а, што нам омогућава реконструкцију комплетног URL-а из дате путање.
Сада када имамо ову функцију, можемо решити проблем ако путања не одговара ниједној дефинисаној рути. Модификоваћемо функцију `updateRoute` тако што ћемо додати фоллбек на једну од постојећих рута ако не можемо пронаћи поклапање.
```js
function updateRoute() {
@ -360,16 +558,16 @@ function updateRoute() {
app.appendChild(view);
}
```
**Кључне тачке које треба запамтити:**
- **Проверава** да ли постоји рута за тренутну путању
- **Преусмерава** на страницу за пријаву када се приступи неважећој рути
- **Обезбеђује** резервни механизам који спречава прекиде у навигацији
- **Омогућава** да корисници увек виде важећи екран, чак и са погрешним URL-овима
Ако рута не може да се пронађе, сада ћемо преусмерити на страницу `login`.
**Кључне ствари за памћење:**
- **Проверава** да ли рута постоји за тренутну путању
- **Редиректује** на страницу за пријаву ако је рута неважећа
- **Обезбеђује** механизам фоллбека који спречава покварену навигацију
- **Гарантује** да корисници увек виде важећи екран, чак и са погрешним URL-овима
Ако рута не постоји, бићемо преусмерени на страницу `login`.
Сада хајде да направимо функцију која ће добити URL када се кликне на линк и спречити подразумевано понашање прегледача за линкове:
Хајде сада да направимо функцију која добија URL када се кликне на линк, и спречава подразумевано понашање прегледача:
```js
function onLinkClick(event) {
@ -377,36 +575,36 @@ function onLinkClick(event) {
navigate(event.target.href);
}
```
**Разлагање овог обрађивача клика:**
- **Спречава** подразумевано понашање прегледача за линкове користећи `preventDefault()`
- **Извлачи** одредишни URL из кликнутог елемента линка
- **Позива** нашу прилагођену функцију за навигацију уместо поновног учитавања странице
- **Одржава** глатко искуство апликације са једном страницом
**Објашњење овог обработчика клика:**
- **Спречава** подразумевано понашање линка у прегледачу коришћењем `preventDefault()`
- **Извлачи** одредишни URL из кликнутог елемента линка
- **Позива** нашу прилагођену навигациону функцију уместо ре-учитавања странице
- **Одржава** глатко искуство једностраничне апликације
```html
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>
```
**Шта ова веза преко onclick атрибута постиже:**
- **Повезује** сваки линк са нашим прилагођеним навигационим системом
- **Прослеђује** догађај клика нашој функцији `onLinkClick` за обраду
- **Омогућава** глатку навигацију без поновног учитавања странице
- **Одржава** правилну структуру URL-а коју корисници могу обележити или делити
Атрибут [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) повезује догађај клика са JavaScript кодом, овде позивом функције `navigate()`.
**Шта ово повезивање onclick ради:**
- **Повезује** сваки линк са прилагођеним навигационим системом
- **Прослеђује** догађај клика нашој функцији `onLinkClick` на обраду
- **Омогућава** глатку навигацију без освежавања странице
- **Одржава** исправну структуру URL-а коју корисници могу означити или делити
Покушајте да кликнете на ове линкове, сада би требало да можете да се крећете између различитих екрана ваше апликације.
Атрибут [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) повезује догађај `click` са JavaScript кодом, овде позивом функције `navigate()`.
✅ Метода `history.pushState` је део HTML5 стандарда и имплементирана је у [свим модерним прегледачима](https://caniuse.com/?search=pushState). Ако правите веб апликацију за старије прегледаче, постоји трик који можете користити уместо овог API-ја: коришћењем [хеша (`#`)](https://en.wikipedia.org/wiki/URI_fragment) пре путање можете имплементирати рутирање које функционише са регуларном навигацијом преко сидра и не поново учитава страницу, јер је његова сврха била да креира унутрашње линкове унутар странице.
Пробајте да кликнете на ове линкове, требало би да сада можете да навигирате између различитих екрана ваше апликације.
✅ Метода `history.pushState` је део HTML5 стандарда и имплементирана у [свим модерним прегледачима](https://caniuse.com/?search=pushState). Ако развијате веб апликацију за старије прегледаче, постоји трик који можете користити као замену: коришћењем [хеша (`#`)](https://en.wikipedia.org/wiki/URI_fragment) пре путање можете имплементирати рутирање које ради уз редовну навигацију анкера и не ре-учитава страницу, јер је намењено прављењу интерних линкова унутар странице.
## Омогућавање рада дугмади за назад и напред
Дугмад за назад и напред су основа веб прегледања, слично као што контролори мисија НАСА-е могу да прегледају претходна стања система током свемирских мисија. Корисници очекују да ова дугмад функционишу, а када не функционишу, то нарушава очекивано искуство прегледања.
Дугмад назад и напред су основа веб прегледања, као што контролери мисија NASA-е могу прегледати прошла стања система током свемирских мисија. Корисници очекују да ова дугмад раде, и ако не раде, то нарушава очекивано искуство прегледања.
Нашој апликацији са једном страницом је потребна додатна конфигурација да би то подржала. Прегледач одржава историјски стек (који смо додавали помоћу `history.pushState`), али када корисници навигирају кроз ову историју, наша апликација мора да реагује ажурирањем приказаног садржаја.
Наша једностранична апликација треба додатну конфигурацију да то подржи. Прегледач држи стек историје (који смо попуњавали са `history.pushState`), али када корисници пролазе кроз ту историју, наша апликација мора да реагује ажурирањем приказаног садржаја у складу са тим.
```mermaid
sequenceDiagram
@ -415,111 +613,220 @@ sequenceDiagram
participant App
participant Template
User->>Browser: Clicks "Login" link
Browser->>App: onclick event triggered
User->>Browser: Кликне на везу "Пријава"
Browser->>App: onclick догађај активиран
App->>App: preventDefault() & navigate('/dashboard')
App->>Browser: history.pushState('/dashboard')
Browser->>Browser: URL updates to /dashboard
App->>App: updateRoute() called
App->>Template: Find & clone dashboard template
Template->>App: Return cloned content
App->>Browser: Replace app content with template
Browser->>User: Display dashboard screen
Browser->>Browser: URL се ажурира на /dashboard
App->>App: позван updateRoute()
App->>Template: Пронађи и клонирај шаблон контролне табле
Template->>App: Врати клонирани садржај
App->>Browser: Замени садржај апликације шаблоном
Browser->>User: Прикажи екран контролне табле
Note over User,Template: User clicks browser back button
Note over User,Template: Корисник кликне дугме назад у прегледачу
User->>Browser: Clicks back button
Browser->>Browser: History moves back to /login
Browser->>App: popstate event fired
App->>App: updateRoute() called automatically
App->>Template: Find & clone login template
Template->>App: Return cloned content
App->>Browser: Replace app content with template
Browser->>User: Display login screen
User->>Browser: Кликне дугме назад
Browser->>Browser: Историја се враћа на /login
Browser->>App: попстате догађај активиран
App->>App: аутоматски позван updateRoute()
App->>Template: Пронађи и клонирај шаблон пријаве
Template->>App: Врати клонирани садржај
App->>Browser: Замени садржај апликације шаблоном
Browser->>User: Прикажи екран пријаве
```
**Кључне тачке интеракције:**
- **Акције корисника** покрећу навигацију кроз кликове или дугмад прегледача
- **Апликација пресреће** кликове на линкове како би спречила поновно учитавање странице
- **History API** управља променама URL-а и стеком историје прегледача
- **Шаблони** пружају структуру садржаја за сваки екран
- **Слушаоци догађаја** осигуравају да апликација реагује на све типове навигације
**Кључне интеракције:**
- **Корисничке акције** покрећу навигацију кликовима или дугмадима прегледача
- **Апликација пресреће** кликове на линкове да спречи освежавање странице
- **History API** управља променама URL-а и стеком историје прегледача
- **Шаблони** обезбеђују структуру садржаја за сваки екран
- **Слушаоци догађаја** осигуравају да апликација реагује на све типове навигације
Коришћење `history.pushState` креира нове уносе у историји навигације прегледача. Можете то проверити држећи *дугме назад* вашег прегледача, требало би да прикаже нешто овако:
Коришћењем `history.pushState` се креирају нови уноси у историји навигације прегледача. Можете то проверити тако што ћете држати *дугме назад* у вашем прегледачу, треба да видите нешто овако:
![Снимак екрана историје навигације](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.sr.png)
![Снимање екрана историје навигације](../../../../translated_images/history.7fdabbafa521e064.sr.png)
Ако покушате да кликнете на дугме назад неколико пута, видећете да се тренутни URL мења и историја се ажурира, али исти шаблон се и даље приказује.
Ако више пута кликнете на дугме назад, видећете да се тренутни URL мења и историја се ажурира, али исти шаблон се наставља приказивати.
То је зато што апликација не зна да треба да позове `updateRoute()` сваки пут када се историја промени. Ако погледате документацију за [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), можете видети да ако се стање промени - што значи да смо прешли на други URL - догађај [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) се покреће. Искористићемо то да решимо овај проблем.
То је зато што апликација не зна да мора да позове `updateRoute()` сваки пут када се историја промени. Ако погледате документацију [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), видећете да ако се стање промени - односно ако смо прешли на други URL - покреће се догађај [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event). Искористићемо то да решимо овај проблем.
### Задатак
### Задаци
Да бисмо осигурали да се приказани шаблон ажурира када се историја прегледача промени, додаћемо нову функцију која позива `updateRoute()`. То ћемо урадити на крају нашег `app.js` фајла:
Да бисмо били сигурни да је приказани шаблон ажуриран када се промене историјски записи у прегледачу, додавамо нову функцију која позива `updateRoute()`. То ћемо урадити на дну нашег фајла `app.js`:
```js
window.onpopstate = () => updateRoute();
updateRoute();
```
**Разумевање ове интеграције историје:**
- **Слуша** догађаје `popstate` који се дешавају када корисници навигирају помоћу дугмади прегледача
- **Користи** стрелну функцију за концизну синтаксу обрађивача догађаја
- **Позива** `updateRoute()` аутоматски сваки пут када се стање историје промени
- **Иницијализује** апликацију позивањем `updateRoute()` када се страница први пут учита
- **Обезбеђује** да се правилан шаблон приказује без обзира на то како корисници навигирају
> 💡 **Савет**: Користили смо [стрелну функцију](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) овде да декларишемо наш обрађивач догађаја `popstate` ради концизности, али обична функција би функционисала исто.
**Објашњење ове интеграције са историјом:**
- **Слуша** догађаје `popstate` који се јављају када корисници навигирају са дугмадима прегледача
- **Користи** стреличну функцију за концизан синтакс у обради догађаја
- **Аутоматски позива** `updateRoute()` кад год се промени стање историје
- **Иницира** апликацију позивом `updateRoute()` при учитавању странице
- **Гарантује** да се приказује исправан шаблон без обзира како корисници навигирају
Ево видео подсетника о стрелним функцијама:
> 💡 **Професионални савет**: Овде смо користили [стреличну функцију](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) за дефинисање нашег обработчика догађаја `popstate` због концизности, али обична функција би радила на исти начин.
[![Стрелне функције](https://img.youtube.com/vi/OP6eEbOj2sc/0.jpg)](https://youtube.com/watch?v=OP6eEbOj2sc "Стрелне функције")
Ево освежавајућег видеа о стреличним функцијама:
> 🎥 Кликните на слику изнад за видео о стрелним функцијама.
[![Стреличне функције](https://img.youtube.com/vi/OP6eEbOj2sc/0.jpg)](https://youtube.com/watch?v=OP6eEbOj2sc "Arrow Functions")
Сада покушајте да користите дугмад назад и напред вашег прегледача и проверите да ли се приказана рута овог пута правилно ажурира.
> 🎥 Кликните слику горе за видео о стреличним функцијама.
Сада покушајте да користите дугмад назад и напред у вашем прегледачу и проверите да ли се приказана рута овога пута исправно ажурира.
### ⚡ **Шта можете урадити у наредних 5 минута**
- [ ] Тестирајте навигацију у вашој банкарској апликацији користећи дугмад назад/напред прегледача
- [ ] Покушајте ручно да унесете различите URL-ове у адресну траку за тестирање рутирања
- [ ] Отворите DevTools у прегледачу и испитајте како се шаблони клонирају у DOM
- [ ] Експериментишите са додавањем console.log изјава за праћење тока рутирања
### 🎯 **Шта можете постићи у овом сату**
- [ ] Завршите квиз након лекције и разумите SPA архитектонске концепте
- [ ] Додајте CSS стилове да ваше банкарске шаблоне изгледају професионално
- [ ] Имплементирајте страницу за 404 грешке са одговарајућим управљањем грешкама
- [ ] Креирајте страницу са заслугама са додатном функционалношћу рутирања
- [ ] Додајте стања учитавања и транзиције између замена шаблона
### 📅 **Ваш недељни план развоја SPA**
- [ ] Завршите комплетну банкарску апликацију са формама, управљањем подацима и перзистенцијом
- [ ] Додајте напредне функције рутирања као што су параметри руте и угнежђене руте
- [ ] Имплементирајте чувара навигације и рутирање засновано на аутентификацији
- [ ] Креирајте поновно употребљиве шаблонске компоненте и библиотеку компоненти
- [ ] Додајте анимације и транзиције за глатко корисничко искуство
- [ ] Дистрибуирајте ваш SPA на хостинг платформи и правилно конфигуришите рутирање
### 🌟 **Ваш месечни курс савладавања фронтенд архитектуре**
- [ ] Изградите сложене SPA користећи модерне фрејмворке као што су React, Vue или Angular
- [ ] Научите напредне обрасце управљања стањем и библиотеке
- [ ] Савладајте алате за градњу и развојне токове за SPA развој
- [ ] Имплементирајте функције Progressive Web App и офлајн подршку
- [ ] Истражите технике оптимизације перформанси за велики SPA
- [ ] Призначите доприносе пројектима отвореног кода SPA и делите своје знање
## 🎯 Једностранична апликација ваша временска линија савладавања
```mermaid
timeline
title Напредак у учењу развоја SPA и модерне веб архитектуре
section Основа (20 минута)
Системи шаблона: HTML елементи шаблона
: Манипулација DOM-ом
: Клонирање садржаја
: Динамичко приказивање
section Основе рутирања (30 минута)
Навигација на клијентској страни: Управљање URL-ом
: History API
: Мапирање руте
: Обрада догађаја
section Корисничко искуство (40 минута)
Профини навигације: Интеграција претраживача
: Подршка за дугме назад
: Обрада грешака
: Глатке транзиције
section Архитектонски обрасци (50 минута)
Професионалне SPA апликације: Системи компоненти
: Управљање стањем
: Оптимизација перформанси
: Границе грешака
section Напредне технике (1 недеља)
Интеграција фрејмворка: React Router
: Vue Router
: Angular Router
: Библиотеке за стање
section Вештине за производњу (1 месец)
Развој за предузећа: Системи за билдовање
: Стратегије тестирања
: Пијаве за производњу
: Надгледање перформанси
```
### 🛠️ Резиме вашег SPA развојног алата
Након завршетка ове лекције, сада сте савладали:
- **Архитектура шаблона**: Поново употребљиви HTML компоненти са динамичким рендеровањем садржаја
- **Рутирање на страни клијента**: Управљање URL-ом и навигација без освежавања странице
- **Интеграција са прегледачем**: Коришћење History API и подршка за дугмад назад/напред
- **Системи вођени догађајима**: Управљање навигацијом и интеракцијама корисника
- **Манипулација DOM-ом**: Клонирање шаблона, промене садржаја и управљање елементима
- **Управљање грешкама**: Глатке алтернативе за неважеће руте и нестали садржај
- **Обрасци перформанси**: Ефикасно учитавање и стратегије рендеровања
**Примене у стварном свету**: Вештине развоја SPA-а примењују се директно на:
- **Модерне веб апликације**: React, Vue, Angular и други фрејмворкови
- **Прогресивне веб апликације**: Апликације које раде офлајн, с искуством као апликације
- **Бизнис контролне табле**: Комплексне пословне апликације са више приказа
- **Е-трговину**: Каталози производа, корпе за куповину и токови плаћања
- **Управљање садржајем**: Креирање и уређивање динамичких садржаја
- **Мобилни развој**: Хибридне апликације коришћењем веб технологија
**Професионалне вештине које сте стекли**: Сада можете:
- **Архитектура** једностранићних апликација са правилним одвајањем одговорности
- **Имплементирање** система за усмеравање на страни клијента који се скалирају са сложеношћу апликације
- **Отклањање грешака** у сложеним навигационим токовима коришћењем алата за развој у прегледачу
- **Оптимизација** перформанси апликације кроз ефикасно управљање шаблонима
- **Дизајн** корисничких искустава која делују нативно и одзивно
**Мастеризовани концепти фронтенд развоја**:
- **Архитектура компоненти**: Поново употребљиви UI обрасци и системи шаблона
- **Синхронизација стања**: Управљање URL стањем и историјом прегледача
- **Програмирање вођено догађајима**: Обрада интеракција корисника и навигација
- **Оптимизација перформанси**: Ефикасна манипулација DOM-ом и учитавање садржаја
- **Дизајн корисничког искуства**: Глатке транзиције и интуитивна навигација
**Следећи ниво**: Спремни сте да истражите модерне фронтенд фрејмворке, напредно управљање стањем или изградите сложене пословне апликације!
🌟 **Постигнуће откључано**: Изградили сте професионалну основу једностранићне апликације са модерним веб архитектонским образцима!
---
## Изазов GitHub Copilot Agent 🚀
## GitHub Copilot Agent Изазов 🚀
Користите Agent мод да завршите следећи изазов:
Користите Agent режим да завршите следећи изазов:
**Опис:** Унапредите апликацију за банкарство имплементацијом обраде грешака и шаблона за 404 страницу за неважеће руте, побољшавајући корисничко искуство приликом навигације на непостојеће странице.
**Опис:** Побољшати банкарску апликацију имплементирањем обраде грешака и шаблона странице 404 за неважеће руте, побољшавајући корисничко искуство приликом навигације на неекстистирајуће странице.
**Задатак:** Направите нови HTML шаблон са id-ом "not-found" који приказује кориснички пријатну 404 страницу са стилизовањем. Затим модификујте JavaScript логику рутирања да приказује овај шаблон када корисници навигирају на неважеће URL-ове, и додајте дугме "Иди на почетну" које води назад на страницу за пријаву.
**Наредба:** Креирајте нови HTML шаблон са id "not-found" који приказује кориснички пријатељску 404 страницу грешке са стилом. Затим измените JavaScript логику усмеравања да прикаже овај шаблон када корисници навигацијом посете неважеће URL-ове, и додајте дугме "Go Home" које враћа на страницу за пријаву.
Сазнајте више о [Agent моду](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
Сазнајте више о [agent режиму](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
## 🚀 Изазов
Додајте нови шаблон и руту за трећу страницу која приказује заслуге за ову апликацију.
Додајте нови шаблон и руту за трећу страницу која приказује заслуге ове апликације.
**Циљеви изазова:**
- **Направите** нови HTML шаблон са одговарајућом структуром садржаја
- **Додајте** нову руту у ваш објекат конфигурације рута
- **Укључите** линкове за навигацију ка и од странице са заслугама
- **Тестирајте** да сва навигација правилно функционише са историјом прегледача
**Циљеви изазова:**
- **Креирајте** нови HTML шаблон са одговарајућом структуром садржаја
- **Додајте** нову руту у вашу конфигурацију рута
- **Укључите** навигационе линкове ка и са странице са заслугама
- **Тестирајте** да ли сва навигација исправно ради са историјом прегледача
## Квиз након предавања
[Квиз након предавања](https://ff-quizzes.netlify.app/web/quiz/42)
## Преглед и самостално учење
## Преглед и Самостални рад
Рутирање је један од изненађујуће сложених делова веб развоја, посебно како се веб креће од понашања поновног учитавања страница ка апликацијама са једном страницом. Прочитајте мало о [начину на који Azure Static Web App сервис](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) обрађује рутирање. Можете ли објаснити зашто су неке одлуке описане у том документу неопходне?
Routing је један од изненадно тешких делова веб развоја, нарочито како веб прелази са понашања освежавања страница на освежење једностранићних апликација. Прочитајте мало о томе [како Azure Static Web App услуга](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) управља усмеравањем. Можете ли објаснити зашто су неке од одлука које су описане у том документу неопходне?
**Додатни ресурси за учење:**
- **Истражите** како популарни оквири као што су React Router и Vue Router имплементирају рутирање на страни клијента
- **Истражите** разлике између рутирања заснованог на хешу и рутирања помоћу History API-ја
- **Научите** о серверском рендеровању (SSR) и како оно утиче на стратегије рутирања
- **Истражите** како прогресивне веб апликације (PWAs) обрађују рутирање и навигацију
**Додатни ресурси за учење:**
- **Истражите** како популарни фрејмворци попут React Router и Vue Router имплементирају усмеравање на страни клијента
- **Истражите** разлике између усмеравања базираног на хешу и усмеравања помоћу history API-ја
- **Научите** о серверској рендерингу (SSR) и како она утиче на стратегије усмеравања
- **Истражите** како Progressive Web Apps (PWA) управљају усмеравањем и навигацијом
## Задатак
[Унапредите рутирање](assignment.md)
[Унапредите усмеравање](assignment.md)
---
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати меродавним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Изјава о одрицању одговорности**:
Овај документ је преведен уз помоћ АИ преводилачке услуге [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да превод буде тачан, молимо вас да имате у виду да аутоматски преводи могу да садрже грешке или нетачности. Оригинални документ на његовом матичном језику треба сматрати ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразумевања или погрешна тумачења која произилазе из коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,38 +1,90 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "32bd800759c3e943c38ad9ae6e1f51e0",
"translation_date": "2025-10-24T23:27:49+00:00",
"original_hash": "b807b09df716dc48a2b750835bf8e933",
"translation_date": "2026-01-07T08:16:18+00:00",
"source_file": "7-bank-project/4-state-management/README.md",
"language_code": "sr"
}
-->
# Изградња апликације за банкарство, део 4: Концепти управљања стањем
# Направите банкарску апликацију, део 4: Концепти управљања стањем
## Квиз пре предавања
## ⚡ Шта можете урадити у наредних 5 минута
[Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/47)
**Пут за брзи почетак за заузете програмере**
```mermaid
flowchart LR
A[⚡ 5 минута] --> B[Дијагностикујте проблеме са стањем]
B --> C[Креирајте централни објекат стања]
C --> D[Додајте функцију updateState]
D --> E[Видите одмах побољшања]
```
- **Минут 1**: Тестирајте тренутни проблем са стањем - пријавите се, освежите страницу, посматрајте одјаву
- **Минут 2**: Замените `let account = null` са `let state = { account: null }`
- **Минут 3**: Креирајте једноставну функцију `updateState()` за контролисана ажурирања
- **Минут 4**: Ажурирајте једну функцију да користи нови образац
- **Минут 5**: Тестирајте побољшану предвидљивост и могућност снимања грешака
**Брзи дијагностички тест**:
```javascript
// Пре: Расут стање
let account = null; // Изгубљено након освежавања!
// После: Централизовано стање
let state = Object.freeze({ account: null }); // Контролисано и пратљиво!
```
**Зашто је ово важно**: За 5 минута ћете доживети трансформацију од хаотичног управљања стањем до предвидивих, лако опструираних образаца. Ово је основа која чини сложене апликације одрживим.
## 🗺️ Ваш пут учења кроз мајсторство управљања стањем
```mermaid
journey
title Од расутостa до професионалне архитектуре
section Дијагностика проблема
Identify state loss issues: 3: You
Understand scattered updates: 4: You
Recognize architecture needs: 6: You
section Централизовање контроле
Create unified state object: 5: You
Implement controlled updates: 7: You
Add immutable patterns: 8: You
section Додавање перзистенције
Implement localStorage: 6: You
Handle serialization: 7: You
Create session continuity: 9: You
section Балансирање свежењe
Address data staleness: 5: You
Build refresh systems: 8: You
Achieve optimal balance: 9: You
```
**Циљ вашег путовања**: До краја ове лекције изградићете професионални систем управљања стањем који рукује перзистенцијом, свежином података и предвидивим ажурирањима - исте образце које користе производне апликације.
## Пре-лекцијски квиз
[Пре-лекцијски квиз](https://ff-quizzes.netlify.app/web/quiz/47)
## Увод
Управљање стањем је као навигациони систем на свемирској летели Voyager када све функционише како треба, једва примећујете да постоји. Али када нешто крене наопако, то постаје разлика између достизања међузвезданог простора и лутања изгубљеног у космичком вакууму. У веб развоју, стање представља све што ваша апликација треба да памти: статус пријаве корисника, податке из формулара, историју навигације и привремена стања интерфејса.
Управљање стањем је као навигациони систем на свемирском броду Voyager када све ради глатко, готово да не приметите да је ту. Али када нешто пође по злу, постаје разлика између доласка до интерстеларног простора и лутања у космичком празнину. У веб развоју, стање представља све што ваша апликација мора да памти: статус пријаве корисника, податке из форми, историју навигације и привремена стања интерфејса.
Како се ваша апликација за банкарство развијала од једноставног формулара за пријаву до сложеније апликације, вероватно сте наишли на неке уобичајене изазове. Освежите страницу и корисници ће бити неочекивано одјављени. Затворите прегледач и сав напредак ће нестати. Решавате проблем и трагате кроз више функција које све модификују исте податке на различите начине.
Док се ваша банкарска апликација развијала из једноставног формулара за пријаву у софистициранију апликацију, вероватно сте наишли на неке уобичајене изазове. Освежите страницу и корисници се неочекивано одјављују. Затворите прегледач и сав напредак нестаје. Снимање грешке значи претраживање преко више функција које на различите начине мењају исте податке.
Ово нису знаци лошег кодирања то су природне потешкоће које се јављају када апликације достигну одређени праг сложености. Сваки програмер се суочава са овим изазовима када њихове апликације прелазе из фазе "доказ концепта" у фазу "спремно за производњу".
Ово нису знакови лошег кода ово су природне растуће боли које се јављају када апликације достигну одређени ниво сложености. Сваки програмер се суочава са овим изазовима док њихове апликације прелазе из „доказа концепта“ у „спремне за производњу“.
У овом предавању ћемо имплементирати централизовани систем за управљање стањем који ће вашу апликацију за банкарство претворити у поуздану, професионалну апликацију. Научићете како да управљате токовима података предвидљиво, да правилно чувате корисничке сесије и да креирате глатко корисничко искуство које модерне веб апликације захтевају.
У овој лекцији ћемо имплементирати централизовани систем управљања стањем који ће вашу банкарску апликацију трансформисати у поуздану, професионалну апликацију. Научићете како контролисано управљати током података, правилно чувати сесије корисника и створити глатко корисничко искуство које модерне веб апликације захтевају.
## Предуслови
Пре него што се упустите у концепте управљања стањем, потребно је да правилно подесите своје развојно окружење и поставите темеље апликације за банкарство. Ово предавање се директно надовезује на концепте и код из претходних делова ове серије.
Пре него што зароните у концепте управљања стањем, морате имати исправно подешено развојно окружење и постављену основу банкарске апликације. Ова лекција се директно надовезује на концепте и код из претходних делова ове серије.
Уверите се да имате следеће компоненте спремне пре него што наставите:
Уверите се да имате следеће компоненте спремне пре наставка:
**Потребно подешавање:**
- Завршите [лекцију о преузимању података](../3-data/README.md) - ваша апликација треба успешно да учитава и приказује податке о рачуну
- Инсталирајте [Node.js](https://nodejs.org) на вашем систему за покретање backend API-ја
- Покрените [server API](../api/README.md) локално за обраду операција са подацима о рачуну
**Потребна подешавања:**
- Завршите [лекцију о дохватању података](../3-data/README.md) - ваша апликација треба успешно да учита и прикаже податке о рачуну
- Инсталирајте [Node.js](https://nodejs.org) на свом систему за покретање серверске API
- Покрените локално [серверски API](../api/README.md) да бисте управљали операцијама са подацима рачуна
**Тестирање вашег окружења:**
@ -40,71 +92,143 @@ CO_OP_TRANSLATOR_METADATA:
```sh
curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result
# -> треба да врати "Bank API v1.0.0" као резултат
```
**Шта ова команда ради:**
- **Шаље** GET захтев вашем локалном API серверу
- **Тестира** везу и проверава да ли сервер одговара
- **Враћа** информације о верзији API-ја ако све ради исправно
- **Слање** GET захтева вашем локалном API серверу
- **Тестирање** везе и провера одговора сервера
- **Враћање** информација о верзији API ако све ради исправно
## 🧠 Преглед архитектуре управљања стањем
```mermaid
mindmap
root((Управљање стањем))
Тренутни проблеми
Губитак сесије
Проблеми са освежавањем странице
Утицај затварања прегледача
Проблеми ресетовања променљивих
Расуте измене
Више тачака измене
Изазови у дебаговању
Непредвидиво понашање
Непотпуна чистка
Проблеми са статусом одјаве
Цурење меморије
Безбедносни ризици
Централизована решења
Унифицирани објекат стања
Један извор истине
Предвидива структура
Скалирана основа
Контролисане измене
Немутабилни обрасци
Коришћење Object.freeze
Промене засноване на функцијама
Праћење стања
Управљање историјом
Видљивост у дебагу
Ревизија измена
Стратегије перзистенције
Интеграција localStorage-а
Континуитет сесије
Серијализација у JSON
Аутоматска синхронизација
Свеже податке
Освежавање са сервера
Руковање застарелим подацима
Оптимизација баланса
Оптимизација складиштења
Минимални подаци
Фокус на перформансе
Безбедносне разматрања
```
**Основно правило**: Професионално управљање стањем балансира предвидивост, перзистенцију и перформансе за стварање поузданих корисничких искустава која се скалирају од једноставних интеракција до сложених радних токова апликација.
---
## Дијагностика проблема са тренутним стањем
## Дијагностика тренутних проблема са стањем
Као Шерлок Холмс који испитује место злочина, морамо разумети шта се тачно дешава у нашој тренутној имплементацији пре него што решимо мистерију нестајућих корисничких сесија.
Као што Шерлок Холмс испитује место злочина, морамо сасвим разумети шта се дешава у нашој тренутној имплементацији пре него што решимо мистерију нестајања корисничких сесија.
Хајде да спроведемо једноставан експеримент који открива основне изазове управљања стањем:
Извршићемо једноставан експеримент који открива изазове управљања стањем:
**🧪 Пробајте овај дијагностички тест:**
1. Пријавите се у вашу апликацију за банкарство и идите на контролну таблу
2. Освежите страницу прегледача
3. Посматрајте шта се дешава са вашим статусом пријаве
**🧪 Испробајте овај дијагностички тест:**
1. Пријавите се у вашу банкарску апликацију и идите на контролну таблу
2. Освежите страницу у прегледачу
3. Посматрајте шта се догађа са статусом пријаве
Ако сте преусмерени назад на екран за пријаву, открили сте класичан проблем са перзистенцијом стања. Ово понашање се дешава јер наша тренутна имплементација чува корисничке податке у JavaScript променљивама које се ресетују при сваком учитавању странице.
Ако вас врати на екран за пријаву, открили сте класичан проблем перзистенције стања. Ово се дешава јер наша тренутна имплементација чува корисничке податке у JavaScript променљивима која се ресетују сваки пут када се страница освежи.
**Проблеми тренутне имплементације:**
**Тренутни проблеми имплементације:**
Једноставна променљива `account` из наше [претходне лекције](../3-data/README.md) ствара три значајна проблема која утичу и на корисничко искуство и на одрживост кода:
Једноставна променљива `account` из наше [претходне лекције](../3-data/README.md) ствара три значајна проблема која утичу и на корисничко искуство и одрживост кода:
| Проблем | Технички узрок | Утицај на корисника |
|---------|----------------|---------------------|
| **Губитак сесије** | Освежавање странице брише JavaScript променљиве | Корисници морају често да се поново пријављују |
| **Распршене измене** | Више функција директно модификује стање | Дебаговање постаје све теже |
| **Непотпуно чишћење** | Одјава не брише све референце стања | Потенцијални проблеми са безбедношћу и приватношћу |
| Проблем | Технички узрок | Утицај на корисника |
|--------------------|--------------------------------------------|------------------------------------|
| **Губитак сесије** | Освежавање странице брише JavaScript променљиве | Корисници морају често да се пријављују |
| **Разбацана ажурирања** | Више функција директно мења стање | Снимање грешака постаје све теже |
| **Непотпуно чишћење** | Одјава не брише све референце стања | Могући безбедносни и приватни ризици |
**Архитектонски изазов:**
Као што је дизајн Титаника са преграђеним одељцима изгледао робусно све док више одељака није истовремено поплављено, решавање ових проблема појединачно неће решити основни архитектонски проблем. Потребно нам је свеобухватно решење за управљање стањем.
Као што је Титаник имао коморе које су деловале робусно све док се није напунило више комора у исто време, поправљање ових проблема појединачно неће решити основни архитектонски проблем. Потребно нам је свеобухватно решење за управљање стањем.
> 💡 **Шта заправо покушавамо да постигнемо овде?**
> 💡 **Шта заправо покушавамо да постигнемо?**
[Управљање стањем](https://en.wikipedia.org/wiki/State_management) је заправо решавање два основна проблема:
1. **Где су моји подаци?**: Праћење информација које имамо и одакле долазе
2. **Да ли су сви на истој страни?**: Осигуравање да оно што корисници виде одговара ономе што се заиста дешава
**Наш план:**
Уместо да се вртимо у круг, направићемо **централизовани систем за управљање стањем**. Замислите то као да имате једну веома организовану особу која је задужена за све важне ствари:
![Шема која приказује токове података између HTML-а, корисничких акција и стања](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.sr.png)
1. **Где су ми подаци?**: Праћење шта имамо и одакле долазе подаци
2. **Да ли су сви усаглашени?**: Осигурати да оно што корисници виде одговара стварном стању
**Наш план игре:**
Уместо да трчимо у круг, креираћемо **централизовани систем управљања стањем**. Замислите да имамо једну заиста организовану особу која контролише све битне ствари:
![Шема која приказује ток података између HTML-а, корисничких акција и стања](../../../../translated_images/data-flow.fa2354e0908fecc8.sr.png)
```mermaid
flowchart TD
A[Корисничка Акција] --> B[Обрада Догађаја]
B --> C[фаункција updateState]
C --> D{Валидација Стата}
D -->|Валидан| E[Креирај Нови Стат]
D -->|Невалидан| F[Обрада Грешке]
E --> G[object.freeze]
G --> H[Ажурирај localStorage]
H --> I[Покрени Aжурирање UI]
I --> J[Корисник Види Промене]
F --> K[Корисник Види Грешку]
subgraph "Слој Управљања Статом"
C
E
G
end
subgraph "Слој Перзистенције"
H
L[localStorage]
H -.-> L
end
```
**Разумевање овог тока података:**
- **Централизује** све стање апликације на једном месту
- **Управља** свим променама стања кроз контролисане функције
- **Централизује** цело стање апликације на једном месту
- **Маршира** све промене стања кроз контролисане функције
- **Осигурава** да кориснички интерфејс остане синхронизован са тренутним стањем
- **Обезбеђује** јасан, предвидљив образац за управљање подацима
- **Пружа** јасан, предвидив образац за управљање подацима
> 💡 **Професионални увид**: Ова лекција се фокусира на основне концепте. За сложене апликације, библиотеке као што је [Redux](https://redux.js.org) пружају напредније функције за управљање стањем. Разумевање ових основних принципа помоћи ће вам да савладате било коју библиотеку за управљање стањем.
> 💡 **Професионални увид**: Ова леција се фокусира на основне концепте. За сложене апликације, библиотеке као што је [Redux](https://redux.js.org) пружају напредније могућности управљања стањем. Разумевање ових основних принципа помоћи ће вам да савладате било коју библиотеку за управљање стањем.
> ⚠️ **Напредна тема**: Нећемо покривати аутоматска ажурирања корисничког интерфејса која се покрећу променама стања, јер то укључује концепте [реактивног програмирања](https://en.wikipedia.org/wiki/Reactive_programming). Сматрајте ово одличним следећим кораком у вашем процесу учења!
> ⚠️ **Напредна тема**: Нећемо покривати аутоматска ажурирања UI покренута променама стања јер то укључује концепте [реактивног програмирања](https://en.wikipedia.org/wiki/Reactive_programming). Размотрите ово као одличан следећи корак у вашем учењу!
### Задатак: Централизовање структуре стања
### Задатак: Централизујте структуру стања
Хајде да почнемо са трансформацијом нашег расутог управљања стањем у централизовани систем. Овај први корак поставља темеље за све наредне унапређења.
Почнимо трансформацију разбацаног управљања стањем у централизовани систем. Овај први корак поставља темеље за све будуће исправке.
**Корак 1: Креирање централизованог објекта стања**
**Корак 1: Креирајте централни објекат стања**
Замените једноставну декларацију `account`:
@ -112,7 +236,7 @@ curl http://localhost:5000/api
let account = null;
```
Са структурираним објектом стања:
са структуираним објектом стања:
```js
let state = {
@ -122,20 +246,20 @@ let state = {
**Зашто је ова промена важна:**
- **Централизује** све податке апликације на једном месту
- **Припрема** структуру за додавање више својстава стања касније
- **Креира** јасну границу између стања и других променљивих
- **Успоставља** образац који се може проширити како ваша апликација расте
- **Припрема** структуру за додавање више својстава стања у будућности
- **Ствара** јасну границу између стања и других променљивих
- **Успоставља** образац који се шири како ваша апликација расте
**Корак 2: Ажурирање образаца приступа стању**
**Корак 2: Ажурирајте обрасце приступа стању**
Ажурирајте ваше функције да користе нову структуру стања:
Прилагодите функције да користе нову структуру стања:
**У функцијама `register()` и `login()`**, замените:
```js
account = ...
```
Са:
са:
```js
state.account = ...
```
@ -145,55 +269,87 @@ state.account = ...
const account = state.account;
```
**Шта ове измене постижу:**
- **Одржавају** постојећу функционалност уз побољшање структуре
**Шта ова ажурирања постижу:**
- **Одржавају** постојећу функционалност уз бољу структуру
- **Припремају** ваш код за сложеније управљање стањем
- **Креирају** конзистентне обрасце за приступ подацима стања
- **Постављају** темеље за централизована ажурирања стања
- **Креирају** доследне обрасце за приступ подацима стања
- **Успостављају** темеље за централизована ажурирања стања
> 💡 **Напомена**: Ово рефакторисање тренутно не решава све наше проблеме, али ствара суштинске основе за моћна побољшања која следе!
### 🎯 Педагошки паузни тест: Принципи централизације
**Пауза и Размишљање**: Управо сте имплементирали темеље централизованог управљања стањем. Ово је кључна архитектонска одлука.
**Брза самооцењивања:**
- Можете ли објаснити зашто је централизовање стања у једном објекту боље од разбацаних променљивих?
- Шта би се десило ако заборавите да ажурирате функцију да користи `state.account`?
- Како овај образац припрема ваш код за напредније могућности?
> 💡 **Напомена**: Ово рефакторисање не решава одмах наше проблеме, али ствара неопходну основу за моћна унапређења која следе!
**Веза са стварним светом**: Образац централизације који сте научили је основа модерних фрејмворка као што су Redux, Vuex и React Context. Ви градите исту архитектонску концепцију коју користе велике апликације.
**Изазовно питање**: Ако треба да додате корисничке преференције (тему, језик) у вашу апликацију, где бисте их додали у структуру стања? Како би се ово скалирало?
## Имплементација контролисаних ажурирања стања
Са централизованим стањем, следећи корак укључује успостављање контролисаних механизама за модификацију података. Овај приступ осигурава предвидљиве промене стања и олакшава дебаговање.
Са централизованим стањем, следећи корак је успостављање контролисаних механизама за измене података. Овај приступ обезбеђује предвидиве промене стања и лакше снимање грешака.
Основни принцип подсећа на контролу ваздушног саобраћаја: уместо да дозволимо више функција да независно модификују стање, усмерићемо све промене кроз једну, контролисану функцију. Овај образац пружа јасну контролу над тим када и како се подаци мењају.
Језгро овог принципа подсећа на контролу ваздушног саобраћаја: уместо да дозволимо више функција да самостално мењају стање, усмерићемо све промене кроз једну контролисану функцију. Овај образац пружа јасан надзор када и како се подаци мењају.
**Управљање неизменљивим стањем:**
**Управљање непромењивим стањем (Immutable):**
Третираћемо наш објекат `state` као [*неизменљив*](https://en.wikipedia.org/wiki/Immutable_object), што значи да га никада нећемо директно модификовати. Уместо тога, свака промена креира нови објекат стања са ажурираним подацима.
Третираћемо наш `state` објекат као [*непромењив*](https://en.wikipedia.org/wiki/Immutable_object), што значи да га никада не мењамо директно. Уместо тога, свака промена креира нови објекат стања са ажурираним подацима.
Иако овај приступ може изгледати неефикасно у поређењу са директним модификацијама, он пружа значајне предности за дебаговање, тестирање и одржавање предвидљивости апликације.
Иако овај приступ можда у почетку изгледа неефикасно у поређењу са директним изменама, он пружа значајне предности за снимање грешака, тестирање и одрживост предвидивости апликације.
**Предности управљања неизменљивим стањем:**
**Предности управљања непромењивим стањем:**
| Предност | Опис | Утицај |
|----------|------|--------|
| **Предвидљивост** | Промене се дешавају само кроз контролисане функције | Лакше за дебаговање и тестирање |
| **Праћење историје** | Свака промена стања креира нови објекат | Омогућава функцију поништавања/поновног извршења |
| **Спречавање нежељених ефеката** | Нема случајних модификација | Спречава мистериозне грешке |
| **Оптимизација перформанси** | Лако је детектовати када се стање заиста променило | Омогућава ефикасна ажурирања корисничког интерфејса |
| Предност | Опис | Утицај |
|-------------------|----------------------------------------------|-----------------------------------|
| **Предвидивост** | Промене се дешавају само кроз контролисане функције | Лакше снимање грешака и тестирање |
| **Праћење историје** | Свако ажурирање стања креира нови објекат | Омогућава функције као Undo/Redo |
| **Превенција споредних ефеката** | Без случајних измена | Спречава мистериозне грешке |
| **Оптимизација перформанси** | Лако детектује када се стање заиста промени | Омогућава ефикасна UI ажурирања |
**Неизменљивост у JavaScript-у са `Object.freeze()`:**
**JavaScript непромењивост са `Object.freeze()`:**
JavaScript пружа [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) за спречавање модификација објеката:
JavaScript пружа [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) за спречавање измена објекта:
```js
const immutableState = Object.freeze({ account: userData });
// Any attempt to modify immutableState will throw an error
// Сваки покушај измене immutableState ће изазвати грешку
```
**Објашњење шта се овде дешава:**
- **Спречава** директна додељивања или брисања својстава
- **Баца** изузетке ако се покушају модификације
- **Осигурава** да промене стања морају проћи кроз контролисане функције
- **Креира** јасан уговор о томе како се стање може ажурирати
> 💡 **Дубински увид**: Сазнајте разлику између *плитких* и *дубоких* неизменљивих објеката у [MDN документацији](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). Разумевање ове разлике је кључно за сложене структуре стања.
- **Спречава** директне доделе или брисање својстава
- **Баца** изузетке ако се покуша измена
- **Осигурава** да промене морају ићи кроз контролисане функције
- **Ствара** јасан уговор о томе како се стање може мењати
> 💡 **Детаљније**: Сазнајте разлику између *плитког* и *дубоког* замрзавања објеката у [MDN документацији](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). Разумевање ове разлике је кључно за сложене структуре стања.
```mermaid
stateDiagram-v2
[*] --> StateV1: Почетно стање
StateV1 --> StateV2: updateState('account', newData)
StateV2 --> StateV3: updateState('account', anotherUpdate)
StateV3 --> StateV4: updateState('preferences', userSettings)
note right of StateV1
Object.freeze()
Неизменљиво
Могуће дебаговање
end note
note right of StateV2
Нови објекат је креиран
Претходно стање сачувано
Предвидиве промене
end note
```
### Задатак
Хајде да креирамо нову функцију `updateState()`:
Креирајмо нову функцију `updateState()`:
```js
function updateState(property, newData) {
@ -204,9 +360,9 @@ function updateState(property, newData) {
}
```
У овој функцији, креирамо нови објекат стања и копирамо податке из претходног стања користећи [*оператор ширења (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Затим замењујемо одређено својство објекта стања новим подацима користећи [нотацију са заградама](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` за додељивање. На крају, закључавамо објекат да спречимо модификације користећи `Object.freeze()`. Тренутно имамо само својство `account` у стању, али са овим приступом можете додати онолико својстава колико вам је потребно.
У овој функцији креирамо нови објекат стања и копирамо податке из претходног стања коришћењем [оператора ширења (`...`)](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Затим преписујемо одређено својство стања са новим подацима коришћењем [нозичне нотације](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]`. На крају закључавамо објекат да не би могао бити мењан коришћењем `Object.freeze()`. Тренутно чувајемо само својство `account` у стању, али овим приступом можете додати колико год својстава је потребно.
Такође ћемо ажурирати иницијализацију `state` да бисмо осигурали да је почетно стање такође закључано:
Такође ћемо ажурирати иницијализацију `state` како бисмо осигурали да је и почетно стање замрзнуто:
```js
let state = Object.freeze({
@ -214,19 +370,19 @@ let state = Object.freeze({
});
```
Након тога, ажурирајте функцију `register` заменом `state.account = result;` са:
Након тога, ажурирајте функцију `register` заменом доделе `state.account = result;` са:
```js
updateState('account', result);
```
Урадите исто са функцијом `login`, заменом `state.account = data;` са:
Учинимо исто у функцији `login`, заменивши `state.account = data;` са:
```js
updateState('account', data);
```
Сада ћемо искористити прилику да решимо проблем са подацима о рачуну који се не бришу када корисник кликне на *Logout*.
Сада ћемо искористити прилику да поправимо проблем што се подаци рачуна не бришу када корисник кликне на *Logout*.
Креирајте нову функцију `logout()`:
@ -237,63 +393,123 @@ function logout() {
}
```
У функцији `updateDashboard()`, замените преусмеравање `return navigate('/login');` са `return logout();`.
У функцији `updateDashboard()`, замените преусмеравање `return navigate('/login');` са `return logout();`
Пробајте да региструјете нови рачун, одјавите се и поново пријавите да проверите да ли све и даље ради исправно.
Пробајте да региструјете нови рачун, одјавите се и поново пријавите да проверите да ли све исправно ради.
> Савет: можете погледати све промене стања додавањем `console.log(state)` на крај функције `updateState()` и отварањем конзоле у алатима за развој вашег прегледача.
> Савет: можете пратити све промене стања додавањем `console.log(state)` на дно функције `updateState()` и отварањем конзоле у алатима за развој у вашем прегледачу.
## Имплементација перзистенције података
Проблем губитка сесије који смо идентификовали раније захтева решење за перзистенцију које одржава корисничко стање током сесија у прегледачу. Ово трансформише нашу апликацију из привременог искуства у поуздан, професионални алат.
Проблем губитка сесије који смо раније идентификовали захтева решење перзистенције које одржава стање корисника кроз прегледачке сесије. Ово трансформише нашу апликацију из привременог искуства у поуздан, професионалан алат.
Замислите како атомски часовници одржавају прецизно време чак и током прекида напајања чувајући критично стање у неиспарљивој меморији. Слично томе, веб апликацијама су потребни механизми за перзистенцију како би сачувале битне корисничке податке током сесија у прегледачу и освежавања странице.
Размислите како атомски сати одржавају прецизно време чак и током прекида напајања чувајући кључне податке у непроводној меморији. Слично томе, веб апликацијама су потребни механизми за перзистентно чување који очувавају битне корисничке податке кроз сесије и освежавања страница.
**Стратешка питања за перзистенцију података:**
Пре имплементације перзистенције, размислите о овим критичним факторима:
Пре имплементације перзистенције, размотрите ове критичне факторе:
| Питање | Контекст банкарске апликације | Утицај одлуке |
|--------------------------|-----------------------------------|--------------------------------|
| **Да ли су подаци осетљиви?** | Стање рачуна, историја трансакција | Одабрати безбедне методе складиштења |
| **Колико дуго треба да се чува?** | Стање пријаве у поређењу са привременим корисничким подешавањима | Изаберите одговарајући рок чувања |
| **Да ли сервер треба да га има?** | Аутентификациони токени у поређењу са UI подешавањима | Одредите захтеве за дељење |
**Опције за складиштење у прегледачу:**
| Питање | Контекст апликације за банкарство | Утицај одлуке |
|--------|----------------------------------|---------------|
| **Да ли су подаци осетљиви?** | Стање рачуна, историја трансакција | Изаберите сигурне методе чувања |
| **Колико дуго треба да
> 💡 **Напредна опција**: За сложене офлајн апликације са великим сетовима података, размислите о коришћењу [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Овај API пружа потпуну базу података на страни клијента, али захтева сложенију имплементацију.
Модерни прегледачи пружају неколико механизама за чување, сваки дизајниран за различите случајеве употребе:
### Задатак: Имплементација локалног складиштења (localStorage) за перзистенцију
**Примарни Storage API-ји:**
Хајде да имплементирамо перзистентно складиштење како би корисници остали пријављени све док се експлицитно не одјаве. Користићемо `localStorage` за чување података о налогу током сесија у претраживачу.
1. **[`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage)**: Перзистентно [Key/Value складиште](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)
- **Чува** податке преко сесија прегледача на неодређено време
- **Опстаје** кроз поновне покрете прегледача и рачунара
- **Ограничено** на специфичан домен веб сајта
- **Идеално** за корисничке преференције и стање пријаве
**Корак 1: Дефинисање конфигурације складиштења**
2. **[`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage)**: Привремено сесијско складиште
- **Функционише** идентично као localStorage током активних сесија
- **Брише** се аутоматски када се затвори картица прегледача
- **Погодно** за привремене податке који не треба да опстану
3. **[HTTP Колачићи](https://developer.mozilla.org/docs/Web/HTTP/Cookies)**: Складиште које дели сервер
- **Аутоматски** се шаљу са сваким захтевом ка серверу
- **Идеално** за [аутентификационе](https://en.wikipedia.org/wiki/Authentication) токене
- **Ограничени** су по величини и могу утицати на перформансе
**Потреба за серијализацијом података:**
И `localStorage` и `sessionStorage` чувају само [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String):
```js
// Претвори објекте у JSON низове за чување
const accountData = { user: 'john', balance: 150 };
localStorage.setItem('account', JSON.stringify(accountData));
// Парсирај JSON низове назад у објекте приликом преузимања
const savedAccount = JSON.parse(localStorage.getItem('account'));
```
**Разумевање серијализације:**
- **Претвара** JavaScript објекте у JSON низове користећи [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
- **Реконструише** објекте из JSON-а користећи [`JSON.parse()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)
- **Обрађује** сложене угнежђене објекте и низове аутоматски
- **Не функционише** са функцијама, undefined вредностима и кружним референцама
> 💡 **Напредна Опција**: За сложене офлајн апликације са великим скуповима података, размислите о [`IndexedDB` API-ју](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Нуди потпуну базу података на клијентској страни али захтева компликованију имплементацију.
```mermaid
quadrantChart
title Опције за чување у прегледачу
x-axis Ниска сложеност --> Висока сложеност
y-axis Кратко трајање --> Дугачко трајање
quadrant-1 Професионални алати
quadrant-2 Једноставна упорност
quadrant-3 Привремено чување
quadrant-4 Напредни системи
localStorage: [0.3, 0.8]
sessionStorage: [0.2, 0.2]
HTTP Cookies: [0.6, 0.7]
IndexedDB: [0.9, 0.9]
Memory Variables: [0.1, 0.1]
```
### Задатак: Имплементирајте перзистенцију у localStorage
Хајде да имплементирамо перзистентно складиште како би корисници остали пријављени док се експлицитно не одјаве. Користићемо `localStorage` за чување података о налогу преко сесија прегледача.
**Први корак: Defинисање конфигурације складишта**
```js
const storageKey = 'savedAccount';
```
**Шта ова константа обезбеђује:**
- **Креира** конзистентан идентификатор за наше складиштене податке
- **Спречава** грешке у референцама кључева складиштења
- **Олакшава** промену кључа складиштења ако је потребно
- **Прати** најбоље праксе за одрживи код
**Шта ова константа пружа:**
- **Креира** доследан идентификатор за наше податке
- **Спречава** типографске грешке у референцама на кључ складишта
- **Олакшава** промену кључа складишта ако је потребно
- **Прати** најбоље праксе за одржив код
**Корак 2: Додавање аутоматске перзистенције**
**Други корак: Додавање аутоматске перзистенције**
Додајте ову линију на крај функције `updateState()`:
Додајте овај ред на крају функције `updateState()`:
```js
localStorage.setItem(storageKey, JSON.stringify(state.account));
```
**Објашњење шта се овде дешава:**
- **Конвертује** објекат налога у JSON стринг за складиштење
- **Чува** податке користећи наш конзистентан кључ складиштења
**Разлагање шта се овде дешава:**
- **Претвара** објекат налога у JSON низ за складиштење
- **Снима** податке користећи наш доследни кључ за складиштење
- **Извршава** се аутоматски кад год дође до промене стања
- **Осигурава** да су складиштени подаци увек синхронизовани са тренутним стањем
- **Обезбеђује** да ће сачувани подаци увек бити синхронизовани са тренутним стањем
> 💡 **Предност архитектуре**: Пошто смо централизовали све ажурирања стања кроз `updateState()`, додавање перзистенције захтевало је само једну линију кода. Ово показује снагу добрих архитектонских одлука!
> 💡 **Архитектонска предност**: Јер смо централизовали све ажурирања стања преко `updateState()`, додавање перзистенције захтевало је само један ред кода. Ово показује снагу добрих архитектонских одлука!
**Корак 3: Враћање стања при учитавању апликације**
**Трећи корак: Враћање стања при учитавању апликације**
Креирајте функцију за иницијализацију која враћа сачуване податке:
Креирајте иницијализациону функцију за враћање сачуваних података:
```js
function init() {
@ -302,7 +518,7 @@ function init() {
updateState('account', JSON.parse(savedAccount));
}
// Our previous initialization code
// Наш претходни код за иницијализацију
window.onpopstate = () => updateRoute();
updateRoute();
}
@ -311,48 +527,62 @@ init();
```
**Разумевање процеса иницијализације:**
- **Преузима** све претходно сачуване податке о налогу из localStorage
- **Парсира** JSON стринг назад у JavaScript објекат
- **Ажурира** стање користећи нашу контролисану функцију ажурирања
- **Враћа** корисничку сесију аутоматски при учитавању странице
- **Извршава** се пре ажурирања рута како би се осигурало да је стање доступно
- **Преузима** било какве сачуване податке налога из localStorage
- **Парсира** JSON низ назад у JavaScript објекат
- **Ажурира** стање користећи нашу контролисану update функцију
- **Аутоматски** враћа корисничку сесију при учитавању странице
- **Извршава се** пре ажурирања рутирања како би стање било доступно
**Корак 4: Оптимизација подразумеване руте**
**Четврти корак: Оптимизација подразумеване руте**
Ажурирајте подразумевану руту како бисте искористили предности перзистенције:
Ажурирајте подразумевану руту да искористите предности перзистенције:
У `updateRoute()`, замените:
```js
// Replace: return navigate('/login');
// Замени: return navigate('/login');
return navigate('/dashboard');
```
**Зашто ова промена има смисла:**
- **Ефикасно користи** наш нови систем перзистенције
- **Омогућава** да контролна табла проверава аутентификацију
- **Преусмерава** аутоматски на пријаву ако не постоји сачувана сесија
- **Креира** беспрекорно корисничко искуство
- **Искористи** наш нови систем перзистенције ефикасно
- **Дозвољава** контролу аутентификације преко контролне табле
- **Аутоматски** преусмерава на пријаву ако нема сачуване сесије
- **Креира** незнатније корисничко искуство
**Тестирање ваше имплементације:**
1. Пријавите се у вашу апликацију за банкарство
2. Освежите страницу у претраживачу
3. Проверите да ли сте остали пријављени и на контролној табли
4. Затворите и поново отворите претраживач
5. Поново отворите вашу апликацију и проверите да ли сте још увек пријављени
1. Пријавите се у вашу банкарску апликацију
2. Освежите страницу прегледача
3. Потврдите да сте и даље пријављени и на контролној табли
4. Затворите и поново отворите прегледач
5. Вратите се у апликацију и потврдите да сте још увек пријављени
🎉 **Остварен успех**: Успешно сте имплементирали систем перзистентног управљања стањем! Ваша апликација сада ради као професионална веб апликација.
### 🎯 Педагошки преглед: Архитектура перзистенције
**Разумевање архитектуре**: Имплементирали сте софистицирани слој перзистенције који балансира корисничко искуство са сложеношћу управљања подацима.
**Кључни појмови које сте савладали**:
- **JSON серијализација**: Претварање сложених објеката у низове за чување
- **Аутоматска синхронизација**: Промене стања активирају перзистенцију
- **Оповраћај сесије**: Апликације могу вратити кориснички контекст након прекида
- **Централизација перзистенције**: Једна функција ажурирања управља свим складиштењем
**Веза са индустријом**: Овај образац перзистенције је основ за Progressive Web Apps (PWA), офлајн-прво апликације и модерна мобилна веб искуства. Градите могућности на професионалном нивоу.
🎉 **Остварено достигнуће**: Успешно сте имплементирали управљање перзистентним стањем! Ваша апликација сада функционише као професионална веб апликација.
**Рефлексионо питање**: Како бисте модификовали овај систем да подржи више корисничких налога на истом уређају? Узмите у обзир приватност и безбедност.
## Балансирање перзистенције и свежине података
Наш систем перзистенције успешно одржава корисничке сесије, али уводи нови изазов: застарелост података. Када више корисника или апликација мења исте серверске податке, локално кеширане информације постају застареле.
Наш систем перзистенције успешно одржава корисничке сесије, али уводи нови изазов: застарелост података. Када више корисника или апликација мењају исте серверске податке, локални кеширани подаци постају неажурни.
Ова ситуација подсећа на викиншке навигаторе који су се ослањали и на сачуване карте звезда и на тренутна посматрања небеских тела. Карте су пружале конзистентност, али навигатори су морали да се ослањају на свежа посматрања како би узели у обзир промене. Слично томе, наша апликација треба и перзистентно корисничко стање и ажурне серверске податке.
Ова ситуација подсећа на викиншке навигаторе који су рачунали и на сачуване звездне мапе и на актуелна небеска посматрања. Мапе су обезбеђивале конзистентност, али навигатори су требали свеже посматрања да би узели у обзир променљиве услове. Слично томе, нашој апликацији треба и перзистентно корисничко стање и актуелни подаци са сервера.
**🧪 Откривање проблема са свежином података:**
1. Пријавите се на контролну таблу користећи налог `test`
2. Покрените ову команду у терминалу како бисте симулирали трансакцију из другог извора:
2. Пустите ову команду у терминалу да симулирате трансакцију са другог извора:
```sh
curl --request POST \
@ -361,31 +591,47 @@ curl --request POST \
http://localhost:5000/api/accounts/test/transactions
```
3. Освежите страницу контролне табле у претраживачу
4. Проверите да ли видите нову трансакцију
3. Освежите страницу контролне табле у прегледачу
4. Пратите да ли се појављује нова трансакција
**Шта овај тест показује:**
- **Показује** како localStorage може постати "застарео" (неажуран)
- **Симулација** реалних сценарија где се подаци мењају ван ваше апликације
- **Открива** тензију између перзистенције и свежине података
**Шта овај тест демонстрира:**
- **Показује** како локално складиштење може постати „застарело“ (неажурно)
- **Симуилација** стварних сценарија где се подаци мењају изван ваше апликације
- **Отвара** тензију између перзистенције и свежине података
**Изазов застарелости података:**
**Изазов са застарелошћу података:**
| Проблем | Узрок | Утицај на корисника |
|---------|-------|---------------------|
| **Застарели подаци** | localStorage се никада аутоматски не ажурира | Корисници виде неажурне информације |
| **Промене на серверу** | Друге апликације/корисници мењају исте податке | Неконзистентни прикази на различитим платформама |
| **Кеш vs. стварност** | Локални кеш не одговара стању сервера | Лоше корисничко искуство и конфузија |
| **Застарели подаци** | localStorage никад аутоматски не истиче | Корисници виде неажурне информације |
| **Промене на серверу** | Друге апликације/корисници мењају исте податке | Неподударни прикази на различитим платформама |
| **Кеширање против реалности** | Локални кеш не одговара стању на серверу | Лоше корисничко искуство и збуњеност |
**Стратегија решења:**
Имплементираћемо образац "освежавања при учитавању" који балансира предности перзистенције са потребом за свежим подацима. Овај приступ одржава глатко корисничко искуство уз осигурање тачности података.
### Задатак: Имплементација система за освежавање података
Имплементираћемо образац „освежавања при учитавању“ који балансира предности перзистенције и потребу за свежећим подацима. Овај приступ задржава глатко корисничко искуство док обезбеђује тачност података.
```mermaid
sequenceDiagram
participant U as Корисник
participant A as Апликација
participant L as локалнаПамћење
participant S as Сервер
U->>A: Отвара апликацију
A->>L: Учитај сачувано стање
L-->>A: Врати кеширане податке
A->>U: Одмах прикажи кориснички интерфејс
A->>S: Преузми свеж податак
S-->>A: Врати текуће податке
A->>L: Ажурирај кеш
A->>U: Ажурирај кориснички интерфејс са свежим подацима
```
### Задатак: Имплементирајте систем освежавања података
Креираћемо систем који аутоматски преузима свежије податке са сервера, истовремено одржавајући предности нашег система за управљање перзистентним стањем.
Креираћемо систем који аутоматски преузима свеже податке са сервера уз одржавање предности нашег система перзистенције стања.
**Корак 1: Креирање ажурирача података о налогу**
**Први корак: Креирање ажурирача података налога**
```js
async function updateAccountData() {
@ -403,15 +649,15 @@ async function updateAccountData() {
}
```
**Разумевање логике ове функције:**
- **Проверава** да ли је корисник тренутно пријављен (state.account постоји)
- **Преусмерава** на одјаву ако не постоји валидна сесија
- **Преузима** свежије податке о налогу са сервера користећи постојећу функцију `getAccount()`
- **Решава** грешке сервера на одговарајући начин одјављивањем неважећих сесија
- **Ажурира** стање са свежим подацима користећи наш контролисани систем ажурирања
- **Покреће** аутоматску перзистенцију у localStorage кроз функцију `updateState()`
**Логика ове функције:**
- **Проверава** да ли је корисник пријављен (постоји state.account)
- **Преусмерава** на одјаву ако нема важећу сесију
- **Преузима** свеже податке налога са сервера користећи постојећу функцију `getAccount()`
- **Руководи** грешкама са сервера на начин да одјави неважеће сесије
- **Ажурира** стање свежим подацима преко контролисаног система за ажурирање
- **Покреће** аутоматску перзистенцију у localStorage кроз `updateState()`
**Корак 2: Креирање обрађивача за освежавање контролне табле**
**Други корак: Креирање хендлера за освежавање контролне табле**
```js
async function refresh() {
@ -421,14 +667,14 @@ async function refresh() {
```
**Шта ова функција за освежавање постиже:**
- **Координира** процес освежавања података и ажурирања корисничког интерфејса
- **Чека** да се свежи подаци учитају пре ажурирања приказа
- **Осигурава** да контролна табла приказује најновије информације
- **Одржава** чисту поделу између управљања подацима и ажурирања корисничког интерфејса
- **Координише** процес освежавања података и ажурирање UI-а
- **Чека** пре него што прикаже свеже податке
- **Обезбеђује** да контролна табла приказује најактуелније информације
- **Одржава** јасну поделу између управљања подацима и ажурирања UI-а
**Корак 3: Интеграција са системом рута**
**Трећи корак: Интеграција са системом рутирања**
Ажурирајте конфигурацију рута како би се освежавање аутоматски покренуло:
Ажурирајте конфигурацију руте да аутоматски покреће освежавање:
```js
const routes = {
@ -438,68 +684,125 @@ const routes = {
```
**Како ова интеграција функционише:**
- **Извршава** функцију освежавања сваки пут када се учита рута контролне табле
- **Осигурава** да се свежи подаци увек приказују када корисници навигирају на контролну таблу
- **Одржава** постојећу структуру рута уз додавање свежине података
- **Пружа** конзистентан образац за иницијализацију специфичну за руте
**Тестирање вашег система за освежавање података:**
1. Пријавите се у вашу апликацију за банкарство
2. Покрените curl команду из претходног примера да креирате нову трансакцију
3. Освежите страницу контролне табле или навигирајте на другу руту па се вратите
4. Проверите да ли се нова трансакција одмах приказује
- **Извршава** функцију освежавања сваки пут када се учита рутa контролне табле
- **Обезбеђује** да се увек прикажу свеже информације када корисници посете контролну таблу
- **Одржава** постојећу структуру рутирања уз додатак свежине података
- **Пружа** доследан образац за рутирање-специфичну иницијализацију
**Тестирање вашег система освежавања података:**
1. Пријавите се у вашу банкарску апликацију
2. Покрените curl команду из претходног корака за креирање нове трансакције
3. Освежите страницу контролне табле или идите са ње па се вратите
4. Потврдите да се нова трансакција одмах појављује
🎉 **Постигнута савршена равнотежа**: Ваша апликација сада комбинује глатко искуство перзистентног стања са тачношћу свежећих сервера података!
## 📈 Ваш тајмлајн за овладавање управљања стањем
```mermaid
timeline
title Путовање ка професионалном управљању стањем
section Препознавање проблема
Дијагноза проблема са стањем
: Идентификовати проблеме губитка сесије
: Разумети проблеме са разбацаним ажурирањима
: Препознати архитектонске потребе
section Основаност архитектуре
Централизовани дизајн стања
: Креирати уједињене објекте стања
: Имплементирати контролисане шаблоне ажурирања
: Успоставити непромењиве принципе
Предвидива ажурирања
: Усавршити коришћење Object.freeze()
: Креирати системе прилагођене дебаговању
: Направити скалабилне шаблоне
section Мастерство перзистенције
Интеграција localStorage-а
: Обрадити JSON серијализацију
: Имплементирати аутоматску синхронизацију
: Креирати континуитет сесије
Баланс свежине података
: Решити изазове застарелости
: Креирати механизме освежавања
: Оптимизовати перформансе у односу на прецизност
section Професионални шаблони
Системи спремни за продукцију
: Имплементирати руковање грешкама
: Креирати одржљиве архитектуре
: Пратити најбоље праксе у индустрији
Напредне могућности
: Припремљени за интеграцију оквира
: Спремни за комплексне потребе стања
: Основа за функционалности у реалном времену
```
**🎓 Мердјан примене**: Успешно сте изградили комплетан систем управљања стањем користећи исте принципе који покрећу Redux, Vuex и друге професионалне библиотеке. Ови шаблони се скалирају од једноставних апликација до предузетничких решења.
🎉 **Постигнут савршен баланс**: Ваша апликација сада комбинује глатко искуство перзистентног стања са тачношћу свежих серверских података!
**🔄 Следећи ниво могућности**:
- Спремни сте за савладавање оквира за управљање стањем (Redux, Zustand, Pinia)
- Припремљени да имплементирате реал-тиме функције коришћењем WebSockets
- Опремљени за изградњу офлајн-прво Progressive Web апликација
- Постављена основа за напредне шаблоне као што су стање машине и посматрачи
## Изазов GitHub Copilot Agent 🚀
## Изазов GitHub Copilot агента 🚀
Користите Agent мод за решавање следећег изазова:
Користите Agent режим за завршетак следећег изазова:
**Опис:** Имплементирајте свеобухватан систем за управљање стањем са функцијама за поништавање/поновно извршавање за апликацију за банкарство. Овај изазов ће вам помоћи да увежбате напредне концепте управљања стањем, укључујући праћење историје стања, непроменљива ажурирања и синхронизацију корисничког интерфејса.
**Опис:** Имплементирајте свеобухватан систем управљања стањем са undo/redo функционалношћу за банкарску апликацију. Овај изазов ће вам помоћи да увежбате напредне концепте управљања стањем, укључујући праћење историје стања, иммутабилне измене и синхронизацију корисничког интерфејса.
**Задатак:** Креирајте побољшани систем за управљање стањем који укључује: 1) Низ историје стања који прати сва претходна стања, 2) Функције за поништавање и поновно извршавање које могу вратити претходна стања, 3) Дугмад у корисничком интерфејсу за операције поништавања/поновног извршавања на контролној табли, 4) Максимални лимит историје од 10 стања како би се спречили проблеми са меморијом, и 5) Правилно чишћење историје када се корисник одјави. Осигурајте да функције поништавања/поновног извршавања раде са променама стања рачуна и да се перзистирају током освежавања претраживача.
**Задатак:** Креирајте проширени систем управљања стањем који укључује: 1) низ историје стања који бележи све претходне стања, 2) undo и redo функције које могу вратити претходна стања, 3) UI дугмад за undo/redo операције на контролној табли, 4) максимум од 10 стања у историји ради спречавања проблема са меморијом, и 5) правилно чишћење историје када се корисник одјави. Обезбедите да undo/redo функционише са променама стања налога и да перзистира преко освежавања прегледача.
Сазнајте више о [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
Сазнајте више о [agent режиму](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
## 🚀 Изазов: Оптимизација складиштења
## 🚀 Изазов: Оптимизација складишта
Ваша имплементација сада ефикасно управља корисничким сесијама, освежавањем података и стањем. Међутим, размислите да ли наш тренутни приступ оптимално балансира ефикасност складиштења са функционалношћу.
Ваша имплементација сада ефикасно управља корисничким сесијама, освежавањем података и управљањем стањем. Међутим, размислите да ли наш тренутни приступ оптимално балансира ефикасност складиштења са функционалношћу.
Као шаховски мајстори који разликују битне фигуре од оних које могу бити жртвоване, ефикасно управљање стањем захтева идентификацију података који морају бити перзистентни у односу на оне који увек треба да буду свежи са сервера.
Као мајстори шаха који разликују битне фигуре од резервних пешака, ефикасно управљање стањем захтева идентификовање који подаци морају да опстану, а који увек требају бити свеже преузети са сервера.
**Анализа оптимизације:**
Оцените вашу тренутну имплементацију localStorage и размислите о овим стратешким питањима:
- Које су минималне информације потребне за одржавање аутентификације корисника?
- Који подаци се довољно често мењају да локално кеширање не пружа значајну корист?
- Како оптимизација складиштења може побољшати перформансе без нарушавања корисничког искуства?
Процените вашу тренутну имплементацију localStorage и размотрите ова стратешка питања:
- Које је минимално потребно информације за одржавање аутентификације корисника?
- Који подаци се довољно често мењају да би локално кеширање било мало корисно?
- Како оптимизација складишта може побољшати перформансе без умањења корисничког искуства?
Ова врста архитектонске анализе разликује искусне програмере који разматрају и функционалност и ефикасност у својим решењима.
**Стратегија имплементације:**
- **Идентификујте** битне податке који морају бити перзистентни (вероватно само идентификација корисника)
- **Модификујте** вашу имплементацију localStorage да складишти само критичне податке о сесији
- **Осигурајте** да се свежи подаци увек учитавају са сервера приликом посете контролној табли
- **Идентификујте** суштинске податке који морају да опстану (вероватно само кориснички идентитет)
- **Модификујте** вашу localStorage имплементацију да чува само критичне податке сесије
- **Обезбедите** да се свеже податке увек учитавају са сервера приликом посета контролној табли
- **Тестирајте** да ваш оптимизовани приступ одржава исто корисничко искуство
**Напредно разматрање:**
- **Упоредите** компромисе између складиштења комплетних података о налогу и само аутентификационих токена
- **Документујте** ваше одлуке и разлоге за будуће чланове тима
**Напредна разматрања:**
- **Упоредите** компромисе између чувања потпуних података налога и само аутентификационих токена
- **Документујте** ваше одлуке и образложења за будуће тимске чланове
Овај изазов ће вам помоћи да размишљате као професионални програмер који узима у обзир и корисничко искуство и ефикасност апликације. Узмите времена да експериментишете са различитим приступима!
Овај изазов ће вам помоћи да мислите као професионални програмер који разматра и корисничко искуство и ефикасност апликације. Узмите време да експериментишете са различитим приступима!
## Квиз након предавања
## Квиз после предавања
[Квиз након предавања](https://ff-quizzes.netlify.app/web/quiz/48)
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/48)
## Задатак
[Имплементирајте дијалог "Додај трансакцију"](assignment.md)
[Implement "Add transaction" dialog](assignment.md)
Ево примера резултата након завршетка задатка:
![Снимак екрана који приказује пример дијалога "Додај трансакцију"](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.sr.png)
![Screenshot showing an example "Add transaction" dialog](../../../../translated_images/dialog.93bba104afeb79f1.sr.png)
---
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу произаћи из коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Одрицање одговорности**:
Овај документ је преведен помоћу AI преводилачке услуге [Co-op Translator](https://github.com/Azure/co-op-translator). Иако тежимо прецизности, молимо имајте у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешне тумачења која произилазе из употребе овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -112,7 +112,7 @@ CO_OP_TRANSLATOR_METADATA:
**Очекивани резултат:**
Након завршетка овог задатка, ваша апликација за банкарство треба да има потпуно функционалну функцију "Додај трансакцију" која изгледа и функционише професионално:
![Снимак екрана који приказује пример дијалога "Додај трансакцију"](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.sr.png)
![Снимак екрана који приказује пример дијалога "Додај трансакцију"](../../../../translated_images/dialog.93bba104afeb79f1.sr.png)
## Тестирање имплементације

@ -11,7 +11,7 @@ CO_OP_TRANSLATOR_METADATA:
У овом пројекту ћете научити како да направите измишљену банку. Ове лекције укључују упутства о томе како да распоредите веб апликацију и обезбедите руте, направите форме, управљате стањем и преузимате податке са API-ја од којег можете добити податке банке.
| ![Screen1](../../../translated_images/screen1.baccbba0f1f93364672eb250d2fbd21574bb1caf79a2155022dc098a741cbdfe.sr.png) | ![Screen2](../../../translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.sr.png) |
| ![Screen1](../../../translated_images/screen1.baccbba0f1f93364.sr.png) | ![Screen2](../../../translated_images/screen2.123c82a831a1d14a.sr.png) |
|--------------------------------|--------------------------------|
## Лекције

@ -1,366 +1,639 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "cfd4a15974168ca426d50c67682ab9d4",
"translation_date": "2025-10-24T23:04:50+00:00",
"original_hash": "a9a3bcc037a447e2d8994d99e871cd9f",
"translation_date": "2026-01-07T07:51:52+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/README.md",
"language_code": "sr"
}
-->
# Korisćenje uređivača koda: Savladavanje VSCode.dev-a
# Коришћење уредника кода: Савладавање VSCode.dev
Sećate li se u *Matriksu* kada je Neo morao da se poveže na ogroman kompjuterski terminal kako bi pristupio digitalnom svetu? Današnji alati za veb razvoj su potpuno suprotni neverovatno moćne mogućnosti dostupne sa bilo kog mesta. VSCode.dev je uređivač koda zasnovan na pretraživaču koji donosi profesionalne alate za razvoj na bilo koji uređaj sa internet vezom.
Сећате се у *Матриксу* када је Нео морао да се прикључи на огромну рачунарску конзолу да би приступио дигиталном свету? Данашњи алати за веб развој су сасвим друга прича невероватно снажне могућности доступне са било ког места. VSCode.dev је уредник кода базиран на прегледачу који доноси професионалне алате за развој на уређај са интернет везом.
Baš kao što je štamparska presa učinila knjige dostupnim svima, a ne samo pisarima u manastirima, VSCode.dev demokratizuje kodiranje. Možete raditi na projektima sa računara u biblioteci, školskom laboratorijumu ili bilo gde gde imate pristup pretraživaču. Bez instalacija, bez ograničenja tipa "treba mi moj specifičan setup".
Баш као што је штампарска машина омогућила књиге свима, а не само преписивачима у манастирима, VSCode.dev демократизује програмирање. Можете радити на пројектима са рачунара у библиотеци, школског лабоса или било где где имате приступ прегледачу. Није потребна инсталација, нема ограничења типа „Мене занима само моје специфично окружење“.
Na kraju ove lekcije, razumećete kako da se krećete kroz VSCode.dev, direktno otvarate GitHub repozitorijume u pretraživaču i koristite Git za kontrolu verzija sve veštine na koje se profesionalni programeri oslanjaju svakodnevno.
До краја овог часа, разумећете како да се крећете кроз VSCode.dev, како да отварате GitHub репозиторијуме директно у прегледачу и како да користите Git за контролу верзија све вештине на којима професионални програмери свакодневно раде.
## Šta ćete naučiti
## ⚡ Шта Можете Учити у Следећих 5 Минутa
Nakon što prođemo kroz ovo zajedno, moći ćete:
**Брзи водич за заузете програмере**
- Navigirati kroz VSCode.dev kao da je vaš drugi dom pronalazeći sve što vam treba bez gubljenja
- Otvoriti bilo koji GitHub repozitorijum u pretraživaču i odmah početi sa uređivanjem (ovo je prilično magično!)
- Koristiti Git za praćenje promena i čuvanje napretka kao profesionalac
- Poboljšati svoj uređivač ekstenzijama koje čine kodiranje bržim i zabavnijim
- Kreirati i organizovati projektne fajlove sa samopouzdanjem
```mermaid
flowchart LR
A[⚡ 5 минута] --> B[Посетите vscode.dev]
B --> C[Повежите GitHub налог]
C --> D[Отворите било који репозиторијум]
D --> E[Одмах започните уређивање]
```
- **Минут 1**: Идите на [vscode.dev](https://vscode.dev) - нема потребе за инсталацијом
- **Минут 2**: Пријавите се помоћу GitHub-а да повежете своје репозиторијуме
- **Минут 3**: Искористите трик са URL-ом: промените `github.com` у `vscode.dev/github` у било ком URL-у репозиторијума
- **Минут 4**: Направите нови фајл и гледајте како аутоматски функционише истицање синтаксе
- **Минут 5**: Направите измену и обавите комит кроз панел Source Control
**Брзи тест URL**:
```
# Transform this:
github.com/microsoft/Web-Dev-For-Beginners
# Into this:
vscode.dev/github/microsoft/Web-Dev-For-Beginners
```
**Зашто је ово важно**: За 5 минута искусићете слободу програмирања било где уз професионалне алате. Ово представља будућност развоја приступачну, моћну и одмах доступну.
## 🗺️ Ваш Пут Кроз Развој у Облаку
```mermaid
journey
title Од локалног подешавања до мајсторства у развоју у облаку
section Разумевање платформе
Откријте уређивање преко интернета: 4: You
Повежите се са GitHub екосистемом: 6: You
Савладајте навигацију интерфејсом: 7: You
section Вештине управљања фајловима
Креирајте и организујте фајлове: 5: You
Уређујте са истицањем синтаксе: 7: You
Навигирајте структуром пројеката: 8: You
section Мајсторство верзије контроле
Разумете Git интеграцију: 6: You
Вежбајте радне токове комитовања: 8: You
Савладајте обрасце сарадње: 9: You
section Професионална прилагођавања
Инсталирајте моћне додатке: 7: You
Конфигуришите развојно окружење: 8: You
Изградите личне радне токове: 9: You
```
**Циљ вашег пута**: На крају овог часа, савладаћете професионално окружење за развој у облаку које ради са било ког уређаја, омогућавајући вам да програмирате са истим алатима које користе програмери највећих технолошких компанија.
## Шта ћете научити
## Šta vam je potrebno
Након што заједно прођемо кроз ово, моћи ћете да:
Zahtevi su jednostavni:
- Користите VSCode.dev као свој други дом да пронађете све што вам треба без губитка
- Отварате било који GitHub репозиторијум у прегледачу и одмах почнете са уређивањем (ово је помало магично!)
- Користите Git да пратите измене и снимате свој напредак као прави професионалац
- Учините свој уредник бољим уз екстензије које чине програмирање бржим и забавнијим
- Са самопоуздањем креирате и организујете фајлове једног пројекта
- Besplatan [GitHub nalog](https://github.com) (vodimo vas kroz proces kreiranja ako je potrebno)
- Osnovno poznavanje veb pretraživača
- Lekcija o osnovama GitHub-a pruža korisnu pozadinu, iako nije neophodna
## Шта ће вам требати
> 💡 **Novi ste na GitHub-u?** Kreiranje naloga je besplatno i traje nekoliko minuta. Kao što vam bibliotečka kartica omogućava pristup knjigama širom sveta, GitHub nalog otvara vrata ka repozitorijumima koda na internetu.
Захтеви су једноставни:
## Zašto su uređivači koda zasnovani na vebu važni
- Бесплатан [GitHub налог](https://github.com) (помоћи ћемо вам са креирањем ако је потребно)
- Основно познавање веб прегледача
- Лекција GitHub Basics пружа корисну позадину, иако није неопходна
Pre interneta, naučnici na različitim univerzitetima nisu mogli lako da dele istraživanja. Zatim je došao ARPANET 1960-ih, povezujući računare na daljinu. Uređivači koda zasnovani na vebu slede isti princip čineći moćne alate dostupnim bez obzira na vašu fizičku lokaciju ili uređaj.
> 💡 **Нови сте на GitHub-у?** Креирање налога је бесплатно и траје неколико минута. Као што библиотечка картица омогућава приступ књигама широм света, тако и GitHub налог отвара врата код репозиторијума широм интернета.
Uređivač koda služi kao vaš radni prostor za razvoj, gde pišete, uređujete i organizujete fajlove koda. Za razliku od jednostavnih uređivača teksta, profesionalni uređivači koda pružaju isticanje sintakse, detekciju grešaka i funkcije za upravljanje projektima.
## 🧠 Преглед Екосистема Развоја у Облаку
VSCode.dev donosi ove mogućnosti u vaš pretraživač:
```mermaid
mindmap
root((VSCode.dev Мастерство))
Platform Benefits
Accessibility
Device Independence
No Installation Required
Instant Updates
Universal Access
Integration
GitHub Connection
Repository Sync
Settings Persistence
Collaboration Ready
Development Workflow
File Management
Project Structure
Syntax Highlighting
Multi-tab Editing
Auto-save Features
Version Control
Git Integration
Commit Workflows
Branch Management
Change Tracking
Customization Power
Extensions Ecosystem
Productivity Tools
Language Support
Theme Options
Custom Shortcuts
Environment Setup
Personal Preferences
Workspace Configuration
Tool Integration
Workflow Optimization
Professional Skills
Industry Standards
Version Control
Code Quality
Collaboration
Documentation
Career Readiness
Remote Work
Cloud Development
Team Projects
Open Source
```
**Основни принцип**: Окружења за развој у облаку представљају будућност програмирања пружају професионалне алате који су приступачни, колаборативни и независни од платформе.
## Зашто су Веб Базирани Уредници Кода Важни
Пре интернета, научници на разним универзитетима нису могле лако да деле своја истраживања. Затим је 1960-их настао ARPANET, повезујући рачунаре на даљину. Веб базирани уредници кода следе исти принцип омогућавају моћне алате без обзира на физичку локацију или уређај.
Уредник кода служи као ваше радно место за развој, где пишете, уређујете и организујете кодне фајлове. За разлику од обичних текстуалних уредника, професионални уредници кода пружају истицање синтаксе, откривање грешака и функције управљања пројектом.
VSCode.dev доноси ове могућности у ваш прегледач:
**Prednosti uređivanja na vebu:**
**Предности уређивања у браузеру:**
| Funkcija | Opis | Praktična korist |
|---------|-------------|----------|
| **Nezavisnost platforme** | Radi na bilo kom uređaju sa pretraživačem | Rad sa različitih računara bez problema |
| **Bez potrebne instalacije** | Pristup putem veb URL-a | Zaobilazi ograničenja instalacije softvera |
| **Automatska ažuriranja** | Uvek radi na najnovijoj verziji | Pristup novim funkcijama bez ručnih ažuriranja |
| **Integracija sa repozitorijumima** | Direktna veza sa GitHub-om | Uređivanje koda bez lokalnog upravljanja fajlovima |
| Карактеристика | Опис | Практична корист |
|--------------------------|----------------------------------|-----------------------------|
| **Независност од платформе** | Ради на сваком уређају са прегледачем | Радите са различитих рачунара без прекида |
| **Нема потребе за инсталацијом** | Приступ преко веб URL-а | Избегава ограничења инсталације софтвера |
| **Аутоматска ажурирања** | Увек ради најновија верзија | Имплементација нових функција без ручне интервенције |
| **Интеграција са репозиторијумима** | Директно повезивање са GitHub-ом | Уређујте код без локалног управљања фајловима |
**Praktične implikacije:**
- Kontinuitet rada u različitim okruženjima
- Dosledan interfejs bez obzira na operativni sistem
- Mogućnosti za trenutnu saradnju
- Smanjeni zahtevi za lokalno skladištenje
**Практичне импликације:**
- Континуитет рада у различитим окружењима
- Конзистентно корисничко сучеље без обзира на оперативни систем
- Одмах доступне могућности за сарадњу
- Смањене потребе за локалном меморијом
## Istraživanje VSCode.dev-a
## Истражујући VSCode.dev
Baš kao što je laboratorija Marije Kiri sadržala sofisticiranu opremu u relativno jednostavnom prostoru, VSCode.dev spaja profesionalne alate za razvoj u interfejs pretraživača. Ova veb aplikacija pruža iste osnovne funkcionalnosti kao i desktop uređivači koda.
Баш као што је лабораторија Марије Кири садржала напредну опрему у релативно једноставном простору, тако VSCode.dev пакује професионалне алате за развој у интерфејс прегледача. Ова веб апликација пружа исту основну функционалност као и уредници за радну површину.
Počnite tako što ćete otići na [vscode.dev](https://vscode.dev) u svom pretraživaču. Interfejs se učitava bez preuzimanja ili instalacije sistema direktna primena principa cloud computing-a.
Почните тако што ћете отићи на [vscode.dev](https://vscode.dev) у свом прегледачу. Интерфејс се учитава без преузимања или системских инсталација директна примена принципа облачног рачунарства.
### Povezivanje vašeg GitHub naloga
### Повезивање вашег GitHub налога
Kao što je telefon Aleksandra Grejema Bela povezivao udaljene lokacije, povezivanje vašeg GitHub naloga spaja VSCode.dev sa vašim repozitorijumima koda. Kada se od vas zatraži da se prijavite na GitHub, preporučuje se da prihvatite ovu vezu.
Као што је телефон Александра Грахама Белла повезао удаљена места, повезивање вашег GitHub налога повезује VSCode.dev са вашим кодним репозиторијумима. Када вам буде затражено да се пријавите помоћу GitHub налога, препоручује се да прихватите ту везу.
**Integracija sa GitHub-om pruža:**
- Direktan pristup vašim repozitorijumima unutar uređivača
- Sinhronizovane postavke i ekstenzije na različitim uređajima
- Pojednostavljen proces čuvanja na GitHub-u
- Personalizovano razvojno okruženje
**GitHub интеграција пружа:**
- Директан приступ вашим репозиторијумима у оквиру уредника
- Синхронизована подешавања и екстензије на свим уређајима
- Поједностављен радни ток снимања на GitHub
- Персонализовано радно окружење
### Upoznavanje sa novim radnim prostorom
### Упознавање са вашим новим радним простором
Kada se sve učita, videćete prelepo čist radni prostor koji je dizajniran da vas fokusira na ono što je važno vaš kod!
Када се све учита, видећете прелепо чист радни простор дизајниран да вас држи фокусираним на оно што је важно ваш код!
![Подразумевани интерфејс VSCode.dev](../../../../translated_images/default-vscode-dev.5d06881d65c1b323.sr.png)
**Ево обиласка околине:**
- **Трака активности** (она трака са леве стране): Ваш главни навигациони мени са Explorer 📁, Претрага 🔍, Source Control 🌿, Екстензије 🧩 и Подешавања ⚙️
- **Бочни панел** (панел поред ње): Приказује релевантне информације у зависности од избора
- **Радни простор уредника** (велики простор у средини): Овде се дешава магија ваш главни простор за програмирање
**Одвојите тренутак да истражите:**
- Кликните на иконе на Траци активности и видите шта свака ради
- Запазите како се бочни панел ажурира да покаже различите информације лепо, зар не?
- Преглед Explorer (📁) ће вероватно бити место где ћете провести највише времена, зато се упознајте с њим
```mermaid
flowchart TB
subgraph "Архитектура интерфејса VSCode.dev"
A[Лента активности] --> B[Истраживач 📁]
A --> C[Претрага 🔍]
A --> D[Контрола извора 🌿]
A --> E[Проширења 🧩]
A --> F[Поставке ⚙️]
B --> G[Дрво фајлова]
C --> H[Пронађи и замени]
D --> I[Статус Gит-а]
E --> J[Пијаца проширења]
F --> K[Конфигурација]
L[Бочна трака] --> M[Панел контекста]
N[Подручје уређивача] --> O[Датотеке кода]
P[Терминал/Излаз] --> Q[Командна линија]
end
```
## Отварање GitHub репозиторијума
**Evo ture kroz vaš novi prostor:**
- **Traka aktivnosti** (ona traka sa leve strane): Vaša glavna navigacija sa Explorer 📁, Pretraga 🔍, Kontrola izvora 🌿, Ekstenzije 🧩 i Postavke ⚙️
- **Bočna traka** (panel pored nje): Menja se kako bi vam prikazala relevantne informacije na osnovu onoga što ste izabrali
- **Prostor za uređivanje** (veliki prostor u sredini): Ovde se dešava magija vaš glavni prostor za kodiranje
Пре интернета, истраживачи су морали физички да иду у библиотеке ради приступа документима. GitHub репозиторијуми делују слично то су колекције кода смештене удаљено. VSCode.dev елиминише традиционални корак преузимања репозиторијума на локални рачунар пре уређивања.
**Odvojite trenutak da istražite:**
- Kliknite na ikone na traci aktivnosti i pogledajte šta svaka radi
- Primetite kako se bočna traka ažurira da prikaže različite informacije prilično zgodno, zar ne?
- Pregled Explorer-a (📁) je verovatno mesto gde ćete provoditi najviše vremena, pa se udobno smestite
Ова могућност омогућава тренутан приступ било ком јавном репозиторијуму за преглед, уређивање или допринос. Ево два начина за отварање репозиторијума:
## Otvaranje GitHub repozitorijuma
### Начин 1: Клик-на-поинт
Pre interneta, istraživači su morali fizički da putuju do biblioteka kako bi pristupili dokumentima. GitHub repozitorijumi funkcionišu slično to su kolekcije koda koje se čuvaju na daljinu. VSCode.dev eliminiše tradicionalni korak preuzimanja repozitorijuma na lokalni računar pre uređivanja.
Ово је савршено када тек почињете у VSCode.dev и желите да отворите одређени репозиторијум. Једноставно и погодније за почетнике:
Ova mogućnost omogućava trenutni pristup bilo kom javnom repozitorijumu za pregled, uređivanje ili doprinos. Evo dva načina za otvaranje repozitorijuma:
**Ево како:**
### Metod 1: Klikni i otvori
1. Идите на [vscode.dev](https://vscode.dev) ако већ нисте тамо
2. Потражите дугме „Open Remote Repository“ на почетном екрану и кликните на њега
Ovo je savršeno kada počinjete od nule u VSCode.dev-u i želite da otvorite određeni repozitorijum. Jednostavno je i pogodno za početnike:
![Отварање удаљеног репозиторијума](../../../../translated_images/open-remote-repository.bd9c2598b8949e7f.sr.png)
**Kako to uraditi:**
3. Убаците било који URL GitHub репозиторијума (пробајте ово: `https://github.com/microsoft/Web-Dev-For-Beginners`)
4. Притисните Enter и гледајте како магија почиње!
1. Idite na [vscode.dev](https://vscode.dev) ako već niste tamo
2. Potražite dugme "Open Remote Repository" na početnom ekranu i kliknite na njega
3. Nalepite URL bilo kog GitHub repozitorijuma (probajte ovaj: `https://github.com/microsoft/Web-Dev-For-Beginners`)
4. Pritisnite Enter i gledajte magiju!
**Про савет - Пречица за Command Palette:**
**Pro saveti - Prečica za Command Palette:**
Желите да изгледате као мајстор кодирања? Испробајте ову пречицу: Ctrl+Shift+P (или Cmd+Shift+P на Mac) да отворите Command Palette:
Želite da se osećate kao čarobnjak za kodiranje? Probajte ovu prečicu na tastaturi: Ctrl+Shift+P (ili Cmd+Shift+P na Mac-u) za otvaranje Command Palette:
![Command Palette](../../../../translated_images/palette-menu.4946174e07f42622.sr.png)
**Command Palette je kao pretraživač za sve što možete da uradite:**
- Ukucajte "open remote" i pronaći će otvarač repozitorijuma za vas
- Pamti repozitorijume koje ste nedavno otvorili (super korisno!)
- Kada se naviknete na njega, osećaćete se kao da kodirate brzinom svetlosti
- To je u suštini VSCode.dev-ova verzija "Hej Siri, ali za kodiranje"
**Command Palette је као претраживач за све што можете да урадите:**
- Откуцајте „open remote“ и пронаћи ће опцију за отварање репозиторијума
- Памти недавно отворене репозиторијуме (врло практично!)
- Када се навикнете, осећаћете се као да програмирате светлосном брзином
- Ово је практично VSCode.dev верзија „Хеј Сири“, али за програмирање
### Metod 2: Tehnika modifikacije URL-a
### Начин 2: Техника измене URL-а
Kao što HTTP i HTTPS koriste različite protokole dok zadržavaju istu strukturu domena, VSCode.dev koristi obrazac URL-a koji odražava GitHub-ov sistem adresiranja. Bilo koji URL GitHub repozitorijuma može se modifikovati da se direktno otvori u VSCode.dev-u.
Баш као што HTTP и HTTPS користе различите протоколе, али задржавају исту доменску структуру, VSCode.dev користи образац URL-а који огледа систем адресирања GitHub-а. Било који GitHub репозиторијум URL може се изменити да би се директно отворио у VSCode.dev.
**Obrazac transformacije URL-a:**
**Образац трансформације URL-а:**
| Tip repozitorijuma | GitHub URL | VSCode.dev URL |
|----------------|---------------------|----------------|
| **Javni repozitorijum** | `github.com/microsoft/Web-Dev-For-Beginners` | `vscode.dev/github/microsoft/Web-Dev-For-Beginners` |
| **Lični projekat** | `github.com/your-username/my-project` | `vscode.dev/github/your-username/my-project` |
| **Bilo koji dostupni repo** | `github.com/their-username/awesome-repo` | `vscode.dev/github/their-username/awesome-repo` |
| Тип репозиторијума | GitHub URL | VSCode.dev URL |
|--------------------|---------------------|----------------|
| **Јавни репозиторијум** | `github.com/microsoft/Web-Dev-For-Beginners` | `vscode.dev/github/microsoft/Web-Dev-For-Beginners` |
| **Приватни пројекат** | `github.com/your-username/my-project` | `vscode.dev/github/your-username/my-project` |
| **Било који приступачан репо** | `github.com/their-username/awesome-repo` | `vscode.dev/github/their-username/awesome-repo` |
**Implementacija:**
- Zamenite `github.com` sa `vscode.dev/github`
- Zadržite sve ostale komponente URL-a nepromenjene
- Radi sa bilo kojim javno dostupnim repozitorijumom
- Omogućava trenutni pristup za uređivanje
**Како то ради:**
- Замените `github.com` са `vscode.dev/github`
- Све остале делове URL-а оставите непромењене
- Ради са било којим јавним репозиторијумом
- Омогућава тренутно уређивање
> 💡 **Savršen savet**: Dodajte u obeleživače VSCode.dev verzije vaših omiljenih repozitorijuma. Ja imam obeleživače poput "Uredi moj portfolio" i "Ispravi dokumentaciju" koji me direktno vode u režim uređivanja!
> 💡 **Савет који мења живот**: Убаците у обележиваче VSCode.dev верзије ваших омиљених репозиторијума. Ја имам обележиваче као што су „Edit My Portfolio“ и „Fix Documentation“ који ме одмах воде у режим уређивања!
**Koji metod treba da koristite?**
- **Interfejs način**: Odličan kada istražujete ili ne možete da se setite tačnih imena repozitorijuma
- **URL trik**: Savršen za munjevito brz pristup kada tačno znate gde idete
**Који начин да изаберете?**
- **Интерфејс начин**: Одличан када прелиставате или не памтите тачно име репозиторијума
- **Трик са URL-ом**: Савршен за светлосно брз приступ када тачно знате куда идете
## Rad sa fajlovima i projektima
### 🎯 Педагошки чек: Приступ развоју у облаку
Sada kada ste otvorili repozitorijum, hajde da počnemo sa radom! VSCode.dev vam pruža sve što vam je potrebno za kreiranje, uređivanje i organizovanje fajlova koda. Zamislite ga kao svoju digitalnu radionicu svaki alat je tačno tamo gde vam treba.
**Станите на тренутак и размислите**: Управо сте научили два начина приступа код репозиторијумима кроз веб прегледач. Ово представља темељну промену у начину рада развоја.
Hajde da zaronimo u svakodnevne zadatke koji će činiti većinu vašeg radnog toka kodiranja.
**Брза самопроцена**:
- Можете ли објаснити зашто веб-базирано уређивање елиминише традиционално „постављање развојног окружења“?
- Које предности техника измене URL-а нуди у односу на локално клонирање git-ом?
- Како овај приступ мења начин на који можете доприносити пројектима отвореног кода?
### Kreiranje novih fajlova
**Веза са стварним светом**: Велике компаније као што су GitHub, GitLab и Replit изграђене су око ових cloud-first принципа. Учите исте радне токове које користе професионални тимови за развој широм света.
Kao organizovanje nacrta u kancelariji arhitekte, kreiranje fajlova u VSCode.dev-u prati strukturiran pristup. Sistem podržava sve standardne tipove fajlova za veb razvoj.
**Изазовно питање**: Како ће развој у облаку променити начин на који се програмирање учи у школама? Разматрајте захтеве уређаја, управљање софтвером и могућности сарадње.
**Proces kreiranja fajlova:**
## Рад са фајловима и пројектима
1. Idite do ciljanog foldera u bočnoj traci Explorer-a
2. Pređite mišem preko imena foldera da biste otkrili ikonu "New File" (📄+)
3. Unesite ime fajla uključujući odgovarajući ekstenziju (`style.css`, `script.js`, `index.html`)
4. Pritisnite Enter da biste kreirali fajl
Са отвореним репозиторијумом, кренимо са израдом! VSCode.dev пружа све што вам треба да креирате, уређујете и организујете своје кодне фајлове. Замислите га као вашу дигиталну радионицу сваки алат је на правом месту.
**Konvencije za imenovanje:**
- Koristite opisna imena koja ukazuju na svrhu fajla
- Uključite ekstenzije fajlova za pravilno isticanje sintakse
- Pratite dosledne obrasce imenovanja kroz projekte
- Koristite mala slova i crtice umesto razmaka
Погледајмо свакодневне задатке који ће чинити већину вашег радног тока програмирања.
### Uređivanje i čuvanje fajlova
### Креирање нових фајлова
Ovde počinje prava zabava! Uređivač VSCode.dev-a je prepun korisnih funkcija koje čine kodiranje glatkim i intuitivnim. To je kao da imate zaista pametnog asistenta za pisanje, ali za kod.
Као што архитекта организује цртеже у свом заводу, креирање фајлова у VSCode.dev прати структуиран приступ. Систем подржава све стандардне типове веб развојних фајлова.
**Vaš radni tok uređivanja:**
**Процес креирања фајла:**
1. Kliknite na bilo koji fajl u Explorer-u da biste ga otvorili u glavnom prostoru
2. Počnite da kucate i gledajte kako vam VSCode.dev pomaže sa bojama, sugestijama i otkrivanjem grešaka
3. Sačuvajte svoj rad sa Ctrl+S (Windows/Linux) ili Cmd+S (Mac) iako se automatski čuva!
1. Идите до циљне фасцикле у бочном Explorer панелу
2. Прелазите мишем преко имена фасцикле да бисте видели иконицу „New File“ (📄+)
3. Унесите име фајла са одговарајућом екстензијом (`style.css`, `script.js`, `index.html`)
4. Притисните Enter да бисте креирали фајл
**Kul stvari koje se dešavaju dok kodirate:**
- Vaš kod se lepo obeležava bojama, pa je lakše za čitanje
- VSCode.dev predlaže dopune dok kucate (kao automatsko ispravljanje, ali mnogo pametnije)
- Hvata greške i tipografske greške pre nego što ih sačuvate
- Možete imati više otvorenih fajlova u karticama, baš kao u pretraživaču
- Sve se automatski čuva u pozadini
![Креирање новог фајла](../../../../translated_images/create-new-file.2814e609c2af9aeb.sr.png)
> ⚠️ **Brzi savet**: Iako automatsko čuvanje ima vašu podršku, pritiskanje Ctrl+S ili Cmd+S je i dalje dobra navika. Odmah čuva sve i pokreće neke dodatne korisne funkcije poput provere grešaka.
**Правила именовања:**
- Користите описна имена која показују сврху фајла
- Укључите екстензије ради исправног истицања синтаксе
- Пратите конзистентне обрасце именовања кроз пројекте
- Користите мале слове и цртице уместо размакâ
### Kontrola verzija sa Git-om
### Уређивање и чување фајлова
Kao što arheolozi prave detaljne zapise o slojevima iskopavanja, Git prati promene u vašem kodu tokom vremena. Ovaj sistem čuva istoriju projekta i omogućava vam da se vratite na prethodne verzije kada je to potrebno. VSCode.dev uključuje integrisanu funkcionalnost Git-a.
Овде почиње права забава! VSCode.dev уредник је препун корисних функција које чине програмирање глатким и интуитивним. Као да имате паметног асистента за писање, али за код.
**Interfejs za kontrolu izvora:**
**Ваш радни ток уређивања:**
1. Pristupite panelu za kontrolu izvora putem ikone 🌿 na traci aktivnosti
2. Izmenjeni fajlovi se pojavljuju u sekciji "Changes"
3. Kodiranje bojama ukazuje na tipove promena: zeleno za dodatke, crveno za brisanja
1. Кликните на било који фајл у Explorer-у да га отворите у главном простору
2. Почните да куцате и гледајте како вам VSCode.dev помаже бојама, предлозима и уочавањем грешака
3. Сачувајте рад са Ctrl+S (Windows/Linux) или Cmd+S (Mac) иако се аутоматски чува!
**Čuvanje vašeg rada (proces commit-a):**
![Уређивање фајла у VSCode.dev](../../../../translated_images/edit-a-file.52c0ee665ef19f08.sr.png)
**Фантастичне ствари које се дешавају док куцате:**
- Ваш код је прелепо обојен тако да се лако чита
- VSCode.dev предлаже допуне као аутокорекцију, али знатно паметније
- Уочава штампарске грешке пре него што сачувате
- Можете имати више отворених фајлова у картицама, као у прегледачу
- Све се аутоматски чува у позадини
> ⚠️ **Брзи савет**: Иако аутоматско чување ради за вас, навика да притиснете Ctrl+S или Cmd+S је добра. Одмах чува све и покреће додатне корисне функције као што је провера грешака.
### Контрола верзија са Git-ом
Као што археолози праве детаљне записе о слојевима ископавања, Git прати измене вашег кода током времена. Овај систем чува историју пројекта и омогућава вам да се вратите на претходне верзије по потреби. VSCode.dev има интегрисану Git функционалност.
**Интерфејс Source Control:**
1. Приступите панелу Source Control преко иконе 🌿 на Траци активности
2. Модификовани фајлови се приказују у одељку „Changes“
3. Боје означавају врсту измена: зелена за додатке, црвена за брисање
![Приказ измена у Source Control](../../../../translated_images/working-tree.c58eec08e6335c79.sr.png)
**Чување рада (радни ток комита):**
```mermaid
flowchart TD
A[Make changes to files] --> B[View changes in Source Control]
B --> C[Stage changes by clicking +]
C --> D[Write descriptive commit message]
D --> E[Click checkmark to commit]
E --> F[Changes pushed to GitHub]
A[Направите измене у фајловима] --> B[Погледајте измене у Контроли извора]
B --> C[Означите измене кликом на +]
C --> D[Напишите описну поруку комита]
D --> E[Кликните на ознаку да бисте комитовали]
E --> F[Измене послате на GitHub]
```
```mermaid
stateDiagram-v2
[*] --> Modified: Уреди датотеке
Modified --> Staged: Кликни + за сцењивање
Staged --> Modified: Кликни - за уклањање са сцењивања
Staged --> Committed: Додај поруку и изврши комитовање
Committed --> [*]: Синхронизуј са GitHub-ом
state Committed {
[*] --> LocalCommit
LocalCommit --> RemotePush: Ауто-синхронизација
}
```
**Ево корак по корак:**
- Кликните икону „+“ поред фајлова које желите да сачувате (овиме их „стежете“)
- Дупло проверите да ли сте задовољни свим својим припремљеним изменама
- Напишите кратку белешку која објашњава шта сте урадили (ово је ваша „порука комита“)
- Кликните на дугме са квачицом да сачувате све на GitHub
- Ако промените мишљење о нечему, икона за опоравак вам омогућава да одбаците измене
**Evo vašeg korak-po-korak procesa:**
- Kliknite na "+" ikonu pored fajlova koje želite da sačuvate (to ih "postavlja")
- Proverite da li ste zadovoljni svim postavljenim promenama
- Napišite kratku belešku koja objašnjava šta ste uradili (to je vaša "commit poruka")
- Kliknite na dugme sa kvačicom da biste sve sačuvali na GitHub-u
- Ako se predomislite oko nečega, ikona za poništavanje vam omogućava da odbacite promene
**Писање добрих комит порука (ово је лакше него што мислите!):**
- Само опишите шта сте урадили, као „Додај контакт форму“ или „Поправи покварену навигацију“
- Држите то кратко и јасно као дужина твита, а не есеја
- Почните са глаголима као што су „Додај“, „Поправи“, „Ажурирај“ или „Уклони“
- **Добри примери**: „Додај респонзивни навигациони мени“, „Поправи проблеме са мобилним изгледом“, „Ажурирај боје за бољу приступачност“
**Pisanje dobrih commit poruka (lakše je nego što mislite!):**
- Samo opišite šta ste uradili, kao "Dodaj kontakt formu" ili "Ispravi pokvarenu navigaciju"
- Neka bude kratko i jasno mislite na dužinu tvita, ne eseja
- Počnite sa glagolima kao što su "Dodaj", "Ispravi", "Ažuriraj" ili "Ukloni"
- **Dobri primeri**: "Dodaj responzivni meni za navigaciju", "Ispravi probleme sa mobilnim izgledom", "Ažuriraj boje za bolju pristupačnost"
> 💡 **Брзи савет за навигацију**: Користите хамбургер мени (☰) у горњем левом углу да се вратите до свог GitHub репозиторијума и видите своје комитоване измене онлајн. То је као портал између вашег уређивачког окружења и домаћина вашег пројекта на GitHub-у!
> 💡 **Brzi savet za navigaciju**: Koristite meni hamburger (☰) u gornjem levom uglu da se vratite na vaš GitHub repozitorijum i vidite svoje sačuvane promene online. To je kao portal između vašeg okruženja za uređivanje i matične stranice vašeg projekta na GitHub-u!
## Побољшање функционалности путем екстензија
## Poboljšanje funkcionalnosti sa ekstenzijama
Као што радионица мајстора садржи специјализоване алате за различите задатке, тако се VSCode.dev може прилагодити екстензијама које додају специфичне могућности. Ови додатаци које развија заједница одговарају уобичајеним потребама развоја као што су форматирање кода, преглед у реалном времену и напредна Git интеграција.
Baš kao što radionica zanatlije sadrži specijalizovane alate za različite zadatke, VSCode.dev se može prilagoditi ekstenzijama koje dodaju specifične funkcionalnosti. Ovi dodaci koje razvija zajednica rešavaju uobičajene izazove u razvoju, kao što su formatiranje koda, pregled uživo i poboljšana integracija sa Git-om.
Marketplace екстензија садржи хиљаде бесплатних алата које су направили програмери широм света. Свака екстензија решава одређене изазове у раду, омогућавајући вам да направите персонализовано развојно окружење које одговара вашим конкретним потребама и преференцама.
Tržište ekstenzija sadrži hiljade besplatnih alata koje su kreirali programeri širom sveta. Svaka ekstenzija rešava određene izazove u radnom toku, omogućavajući vam da izgradite personalizovano razvojno okruženje prilagođeno vašim specifičnim potrebama i preferencijama.
```mermaid
mindmap
root((Екосистем додатака))
Essential Categories
Productivity
Live Server
Auto Rename Tag
Bracket Pair Colorizer
GitLens
Code Quality
Prettier
ESLint
Spell Checker
Error Lens
Language Support
HTML CSS Support
JavaScript ES6
Python Extension
Markdown Preview
Themes & UI
Dark+ Modern
Material Icon Theme
Peacock
Rainbow Brackets
Discovery Methods
Popular Rankings
Download Counts
User Ratings
Recent Updates
Community Reviews
Recommendations
Workspace Suggestions
Language-based
Workflow-specific
Team Standards
```
### Проналажење савршених екстензија
### Pronalaženje savršenih ekstenzija
Marketplace екстензија је изузетно добро организован, па се нећете изгубити док тражите оно што вам је потребно. Дизајниран је да вам помогне да откријете и специфичне алате и кул ствари за које нисте ни знали да постоје!
Tržište ekstenzija je zaista dobro organizovano, tako da se nećete izgubiti dok tražite ono što vam treba. Dizajnirano je da vam pomogne da otkrijete i specifične alate i zanimljive stvari za koje niste ni znali da postoje!
**Како доћи до marketplace-а:**
**Pristup tržištu:**
1. Кликните на иконицу Екстензија (🧩) у Activity Bar-у
2. Прегледајте или претражујте нешто конкретно
3. Кликните на нешто што вам изгледа занимљиво да сазнате више
1. Kliknite na ikonu Ekstenzije (🧩) na traci aktivnosti
2. Pregledajte ili potražite nešto specifično
3. Kliknite na bilo šta što vam izgleda zanimljivo da saznate više o tome
![Extension marketplace interface](../../../../translated_images/extensions.eca0e0c7f59a10b5.sr.png)
**Šta ćete tamo videti:**
**Шта ћете видети тамо:**
| Sekcija | Šta sadrži | Zašto je korisno |
| Одељак | Шта садржи | Зашто је корисно |
|----------|---------|----------|
| **Instalirano** | Ekstenzije koje ste već dodali | Vaš lični alat za
- Svaka ekstenzija prikazuje ocene, broj preuzimanja i recenzije stvarnih korisnika
- Dobijate snimke ekrana i jasne opise šta svaka ekstenzija radi
- Sve je jasno označeno informacijama o kompatibilnosti
- Predložene su slične ekstenzije kako biste mogli da uporedite opcije
| **Инсталиране** | Екстензије које сте већ додали | Ваш лични сет алата за кодирање |
| **Популарне** | Омиле свим корисницима | Оне које највише програмирача користи |
| **Препоручене** | Паметни предлози за ваш пројекат | Корисне препоруке VSCode.dev-а |
### Instaliranje ekstenzija (Veoma je lako!)
**Шта олакшава прегледање:**
- Свака екстензија приказује оцене, број прегледа и стварне корисничке рецензије
- Добијате снимке екрана и јасне описе шта свака ради
- Све је јасно означено са информацијама о компатибилности
- Сличне екстензије су предложене да бисте упоредили опције
Dodavanje novih funkcija vašem editoru je jednostavno kao klik na dugme. Ekstenzije se instaliraju za nekoliko sekundi i odmah počinju da rade bez ponovnog pokretanja, bez čekanja.
### Инсталирање екстензија (врло је једноставно!)
**Evo šta treba da uradite:**
Додавање нових могућности вашем уређивачу је као кликовање на дугме. Екстензије се инсталирају за неколико секунди и одмах почињу да функционишу без рестартовања, без чекања.
1. Potražite ono što želite (probajte da pretražite "live server" ili "prettier")
2. Kliknite na onu koja vam se čini dobrom da biste videli više detalja
3. Pročitajte šta radi i proverite ocene
4. Kliknite na plavo dugme "Install" i gotovi ste!
**Ево шта треба да урадите:**
![Instaliranje ekstenzija](../../../../8-code-editor/images/install-extension.gif)
1. Потражите оно што желите (пробајте „live server“ или „prettier“)
2. Кликните на ону која вам делује добро да видите детаље
3. Прочитајте шта ради и проверите оцене
4. Притисните плаво дугме „Install“ и готови сте!
**Šta se dešava iza kulisa:**
- Ekstenzija se automatski preuzima i podešava
- Nove funkcije se odmah pojavljuju u vašem interfejsu
- Sve počinje da radi odmah (ozbiljno, toliko je brzo!)
- Ako ste prijavljeni, ekstenzija se sinhronizuje na svim vašim uređajima
![Installing extensions](../../../../8-code-editor/images/install-extension.gif)
**Neke ekstenzije koje bih preporučio za početak:**
- **Live Server**: Gledajte kako se vaša veb stranica ažurira u realnom vremenu dok kodirate (ovo je magično!)
- **Prettier**: Automatski čini vaš kod čistim i profesionalnim
- **Auto Rename Tag**: Promenite jedan HTML tag i njegov partner se automatski ažurira
- **Bracket Pair Colorizer**: Obojava zagrade tako da se nikada ne izgubite
- **GitLens**: Poboljšava vaše Git funkcije sa mnoštvom korisnih informacija
**Шта се дешава у позадини:**
- Екстензија се аутоматски преузима и подешава
- Нове функције одмах постају видљиве у интерфејсу
- Све почне да ради одмах (озбиљно, тако је брзо!)
- Ако сте пријављени, екстензија се синхронизује на свим вашим уређајима
### Prilagođavanje vaših ekstenzija
**Неке екстензије које бих вам препоручио да почнете са њима:**
- **Live Server**: Погледајте како се ваша веб-страница освежава у реалном времену док кодете (ово је чаробно!)
- **Prettier**: Аутоматски чисти и професионално форматира ваш код
- **Auto Rename Tag**: Промена једног HTML тега аутоматски мења и његов пар
- **Bracket Pair Colorizer**: Бојом означава заграде да се никада не изгубите
- **GitLens**: Побољшава Git могућности са мноштвом корисних информација
Većina ekstenzija dolazi sa podešavanjima koja možete prilagoditi kako bi radile tačno onako kako vi želite. Zamislite to kao podešavanje sedišta i ogledala u automobilu svako ima svoje preferencije!
### Прилагођавање ваших екстензија
**Podešavanje ekstenzija:**
Већина екстензија долази са подешавањима која можете мењати да бисте их учинили управо онаквим какве желите. Замислите то као подешавање седишта и ретровизора у аутомобилу свако има своје преференције!
1. Pronađite instaliranu ekstenziju u panelu Ekstenzije
2. Potražite malu ikonicu zupčanika (⚙️) pored njenog imena i kliknite na nju
3. Izaberite "Extension Settings" iz padajućeg menija
4. Podesite opcije dok ne budu savršeno prilagođene vašem načinu rada
**Подешавање екстензија:**
![Prilagođavanje podešavanja ekstenzija](../../../../translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.sr.png)
1. Пронађите инсталирану екстензију у панелу Екстензија
2. Потражите малу икону зупчаника (⚙️) поред имена и кликните на њу
3. Изаберите „Extension Settings“ из падајућег менија
4. Подесите опције док не осетите да вам одговара за рад
**Uobičajene stvari koje biste mogli da prilagodite:**
- Kako se vaš kod formatira (tabovi vs razmaci, dužina linije, itd.)
- Koje prečice na tastaturi pokreću različite akcije
- Sa kojim tipovima fajlova ekstenzija treba da radi
- Uključivanje ili isključivanje određenih funkcija radi preglednosti
![Customizing extension settings](../../../../translated_images/extension-settings.21c752ae4f4cdb78.sr.png)
### Organizovanje vaših ekstenzija
**Уобичајене ствари које можете желети да подесите:**
- Како се ваш код форматира (табови уместо размаке, дужина линије, итд.)
- Које тастатурне пречице активирају одређене акције
- Са којим типовима фајлова екстензија треба да ради
- Укључивање или искључивање специфичних функција ради јасноће
Kako budete otkrivali više zanimljivih ekstenzija, želećete da vaša kolekcija bude uredna i da radi glatko. VSCode.dev čini upravljanje ovim veoma jednostavnim.
### Одржавање ваше колекције екстензија организованом
**Opcije za upravljanje ekstenzijama:**
Док откривате све више кул екстензија, желећете да их држите уредним и да све добро ради. VSCode.dev ово веома лако омогућава.
| Šta možete da uradite | Kada je korisno | Savet |
**Опције за управљање екстензијама:**
| Шта можете урадити | Када је корисно | Про савет |
|--------|---------|----------|
| **Onemogući** | Kada testirate da li ekstenzija izaziva probleme | Bolje nego da je deinstalirate ako mislite da će vam ponovo trebati |
| **Deinstaliraj** | Potpuno uklanjanje ekstenzija koje vam nisu potrebne | Održava vaše okruženje čistim i brzim |
| **Ažuriraj** | Dobijanje najnovijih funkcija i ispravki grešaka | Obično se dešava automatski, ali vredi proveriti |
| **Онемогући** | Тестирање да ли екстензија узрокује проблеме | Боље од деинсталације ако можда желите касније назад |
| **Деинсталирај** | Потпуно уклањање екстензија које не користите | Чува ваше окружење чистим и брзим |
| **Ажурирај** | Добијање најновијих функција и исправки | Обично се дешава аутоматски, али вреди проверити |
**Како ја волим да управљам екстензијама:**
- Сваких неколико месеци прегледам шта сам инсталирао и уклањам оно што не користим
- Држим екстензије ажурним да бих имао најновија побољшања и безбедносне исправке
- Ако нешто делује споро, привремено онемогућим екстензије да видим да ли је то узрок
- Читам напомене о ажурирањима када екстензије добију велике надоградње понекад имају кул нове функције!
> ⚠️ **Савет за перформансе**: Екстензије су одличне, али превише њих може успорити систем. Фокусирајте се на оне које вам заиста олакшавају живот и не бојте се да уклоните оне које никада не користите.
### 🎯 Педагошки пресек: Прилагођавање развојног окружења
**Разумевање архитектуре**: Научили сте како да прилагодите професионално развојно окружење коришћењем екстензија које је направила заједница. Ово одражава начин на који корпоративни тимови граде стандардизоване алате.
**Кључни концепти које сте савладали**:
- **Проналажење екстензија**: Откривање алата који решавају конкретне изазове развоја
- **Конфигурисање окружења**: Прилагођавање алата преференцама појединца или тима
- **Оптимизација перформанси**: Баланс између могућности и перформанси система
- **Сарадња заједнице**: Коришћење алата које је креирала глобална заједница програмера
**Kako ja volim da upravljam ekstenzijama:**
- Svakih nekoliko meseci pregledam šta sam instalirao i uklonim sve što ne koristim
- Održavam ekstenzije ažuriranim kako bih dobio najnovija poboljšanja i sigurnosne ispravke
- Ako nešto deluje sporo, privremeno onemogućim ekstenzije da vidim da li je neka od njih uzrok
- Čitam beleške o ažuriranjima kada ekstenzije dobiju velike promene ponekad ima sjajnih novih funkcija!
**Индустријска веза**: Екосистеми екстензија покрећу велике развојне платформе попут VS Code, Chrome DevTools и модерних IDE алата. Разумевање како оцењивати, инсталирати и конфигурисати екстензије је кључно за професионалне развојне токове рада.
**Питање за размишљање**: Како бисте приступили подешавању стандардизованог развојног окружења за тим од 10 програмера? Размотрите доследност, перформансе и индивидуалне преференце.
## 📈 Ваш временски оквир савладавања развоја у облаку
```mermaid
timeline
title Професионално путовање развоја у облаку
section Основе платформе
Разумевање развоја у облаку
: Савладајте концепте уређивања заснованог на вебу
: Повежите обрасце интеграције са ГитХаб-ом
: Кретати се кроз професионалне интерфејсе
section Мастерство радног тока
Управљање фајловима и пројектима
: Креирајте организоване структуре пројеката
: Савладајте предности истакнућа синтаксе
: Руководите радним токовима са више фајлова
Интеграција контроле верзија
: Разумите визуализацију Гита
: Вежбајте стандарде порука комита
: Савладајте праћење промена у радним токовима
section Прилагођавање окружења
Екосистем екстензија
: Откријте екстензије за продуктивност
: Конфигуришите развојне преференције
: Оптимизујте перформансе у односу на функционалност
Професионално подешавање
: Изградите конзистентне радне токове
: Креирајте поново употребљиве конфигурације
: Успоставите тимске стандарде
section Спремност за индустрију
Развој са приоритетом на облаку
: Савладајте праксе удаљеног развоја
: Разумите сарадничке радне токове
: Изграђујте вештине независне од платформе
Професионалне праксе
: Пратите индустријске стандарде
: Креирајте одрживе радне токове
: Припремите се за тимске средине
```
**🎓 Важан корак дипломирања**: Успешно сте савладали развој у облаку користећи исте алате и радне токове које употребљавају професионални програмери у водећим технолошким компанијама. Ове вештине представљају будућност развоја софтвера.
> ⚠️ **Saveti za performanse**: Ekstenzije su sjajne, ali previše njih može usporiti rad. Fokusirajte se na one koje vam zaista olakšavaju život i ne bojte se da deinstalirate one koje nikada ne koristite.
**🔄 Следећи ниво могућности**:
- Спремни да истражите напредне cloud development платформе (Codespaces, GitPod)
- Припремљени за рад у расподељеним развојним тимовима
- Опремљени за допринос open source пројектима широм света
- Основе постављене за модерне DevOps и праксе континуиране интеграције
## Izazov sa GitHub Copilot Agent 🚀
## GitHub Copilot Agent изазов 🚀
Kao što NASA koristi strukturirani pristup za svemirske misije, ovaj izazov uključuje sistematsku primenu veština VSCode.dev u kompletnom radnom procesu.
Као што NASA користи структуриран приступ за свемирске мисије, овај изазов укључује систематску примену вештина VSCode.dev у комплетном сценарију рада.
**Cilj:** Pokažite veštinu u radu sa VSCode.dev uspostavljanjem sveobuhvatnog radnog procesa za veb razvoj.
**Циљ:** Покажите вештину рада са VSCode.dev тако што ћете формирати свеобухватан веб развојни радни ток.
**Zahtevi projekta:** Koristeći pomoć u Agent režimu, završite sledeće zadatke:
1. Forkujte postojeći repozitorijum ili kreirajte novi
2. Uspostavite funkcionalnu strukturu projekta sa HTML, CSS i JavaScript fajlovima
3. Instalirajte i konfigurišite tri ekstenzije koje poboljšavaju razvoj
4. Vežbajte kontrolu verzija sa opisnim porukama o izmenama
5. Eksperimentišite sa kreiranjem i modifikacijom grana za funkcije
6. Dokumentujte proces i naučene lekcije u README.md fajlu
**Захтеви пројекта:** Уз помоћ агент режима, урадите следеће:
1. Форкујте постојећи репозиторијум или направите нови
2. Формирајте функционалну структуру пројекта са HTML, CSS и JavaScript фајловима
3. Инсталирајте и конфигуришите три екстензије које унапређују развој
4. Вежбајте контролу верзија са описним комит порукама
5. Испробајте креирање и модификацију фичер грана
6. Документовати процес и научено у README.md фајлу
Ova vežba konsoliduje sve VSCode.dev koncepte u praktičan radni proces koji se može primeniti na buduće projekte razvoja.
Ова вежба консолидује све VSCode.dev концепте у практични радни ток који можете применити у будућим пројектима.
Saznajte više o [agent režimu](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) ovde.
Сазнајте више о [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) овде.
## Zadatak
## Задатак
Vreme je da ove veštine testirate u praksi! Imam praktičan projekat koji će vam omogućiti da vežbate sve što smo pokrili: [Kreirajte veb sajt za biografiju koristeći VSCode.dev](./assignment.md)
Време је да ове вештине ставите на прави тест! Имам практичан пројекат који ће вам омогућити да вежбате све што смо прошли: [Креирајте веб сајт за резиме користећи VSCode.dev](./assignment.md)
Ovaj zadatak vas vodi kroz proces izrade profesionalnog veb sajta za biografiju u potpunosti u vašem pretraživaču. Koristićete sve funkcije VSCode.dev koje smo istražili, a na kraju ćete imati i sjajan veb sajt i čvrsto samopouzdanje u vaš novi radni proces.
Овај задатак ће вас провести кроз прављење професионалног веб сајта за резиме у потпуности у вашем прегледачу. Користићете све функције VSCode.dev-а које смо истражили, а на крају ћете имати и сјајан сајт и чврсто поверење у свој нови радни ток.
## Nastavite da istražujete i razvijate svoje veštine
## Наставите да истражујете и развијате своје вештине
Sada imate solidnu osnovu, ali postoji još mnogo sjajnih stvari koje možete otkriti! Evo nekoliko resursa i ideja za unapređenje vaših veština sa VSCode.dev:
Сада имате солидну основу, али има још много кул ствари које треба открити! Ево неких ресурса и идеја за унапређење ваших VSCode.dev вештина:
**Zvanična dokumentacija koju vredi sačuvati:**
- [VSCode Web Dokumentacija](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) Kompletan vodič za uređivanje u pretraživaču
- [GitHub Codespaces](https://docs.github.com/en/codespaces) Kada želite još više snage u oblaku
**Званична документација коју вреди оставити у фаворитима:**
- [VSCode Web Documentation](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) Потпуни водич за уређивање у прегледачу
- [GitHub Codespaces](https://docs.github.com/en/codespaces) За када желите још већу снагу у облаку
**Zanimljive funkcije za dalje istraživanje:**
- **Prečice na tastaturi**: Naučite kombinacije tastera koje će vas učiniti majstorom kodiranja
- **Podešavanja radnog prostora**: Postavite različita okruženja za različite vrste projekata
- **Radni prostori sa više korena**: Radite na više repozitorijuma istovremeno (veoma korisno!)
- **Integracija terminala**: Pristupite alatima komandne linije direktno u vašem pretraživaču
**Кул функције за следећу пробу:**
- **Тастатурне пречице**: Научите комбинције тастера које ће вас учинити кодирајућим нинџом
- **Подешавања радног простора**: Поставите различита окружења за различите врсте пројеката
- **Workspace са више корена**: Ради на више репозиторијума истовремено (врло корисно!)
- **Интеграција терминала**: Приступите командној линији директно у прегледачу
**Ideje za vežbanje:**
- Pridružite se nekim projektima otvorenog koda i doprinesite koristeći VSCode.dev sjajan način da uzvratite zajednici!
- Isprobajte različite ekstenzije kako biste pronašli savršeno podešavanje
- Kreirajte šablone projekata za vrste sajtova koje najčešće pravite
- Vežbajte Git radne procese kao što su grananje i spajanje ove veštine su zlata vredne u timskim projektima
**Идеје за вежбање:**
- Укључите се у неке open-source пројекте и допринесите користећи VSCode.dev одличан начин да узвратите!
- Испробајте различите екстензије да пронађете своју идеалну конфигурацију
- Креирајте шаблоне пројеката за типове сајтова на којима најчешће радите
- Вежбајте Git радне токове попут гранања и спајања ове вештине су прави златни фонд за тимске пројекте
---
**Savladali ste razvoj u pretraživaču!** 🎉 Kao što je izum prenosivih instrumenata omogućio naučnicima da sprovode istraživanja na udaljenim lokacijama, VSCode.dev omogućava profesionalno kodiranje sa bilo kog uređaja povezanog na internet.
**Савладали сте развој у прегледачу!** 🎉 Као што је изум преносивих инструмената омогућио научницима да истражују удаљене локалитете, VSCode.dev вам омогућава професионално кодирање са било ког уређаја повезаног на интернет.
Ove veštine odražavaju trenutne industrijske prakse mnogi profesionalni programeri koriste okruženja za razvoj u oblaku zbog njihove fleksibilnosti i pristupačnosti. Naučili ste radni proces koji se može primeniti od individualnih projekata do velikih timskih saradnji.
Ове вештине одражавају савремену индустријску праксу многи професионални програмирачи користе развојна окружења у облаку због флексибилности и приступачности. Научили сте радни ток који се може применити од индивидуалних пројеката до великих тимских сарадњи.
Primenite ove tehnike na vašem sledećem projektu razvoja! 🚀
Примените ове технике у свом следећем развојном пројекту! 🚀
---
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Изјава о одрицању одговорности**:
Овај документ је преведен помоћу АИ преводилачке услуге [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде тачан, молимо вас да имате у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешна тумачења настала коришћењем овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -78,7 +78,7 @@ CO_OP_TRANSLATOR_METADATA:
4. **Напишите** поруку за commit: "Додат почетни HTML структура"
5. **Кликните** "Commit new file" да бисте сачували промене
![Креирање почетног фајла на GitHub-у](../../../../translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.sr.png)
![Креирање почетног фајла на GitHub-у](../../../../translated_images/new-file-github.com.c886796d800e8056.sr.png)
**Ево шта ова почетна поставка постиже:**
- **Успоставља** правилну HTML5 структуру документа са семантичким елементима
@ -104,7 +104,7 @@ CO_OP_TRANSLATOR_METADATA:
**Индикатор успеха**: Требало би да видите фајлове вашег пројекта у бочној траци Explorer-а и `index.html` доступан за уређивање у главном уређивачком простору.
![Пројекат учитан у VSCode.dev](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.sr.png)
![Пројекат учитан у VSCode.dev](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7fe.sr.png)
**Шта ћете видети у интерфејсу:**
- **Бочна трака Explorer-а**: **Приказује** фајлове и структуру фасцикли вашег репозиторијума
@ -448,7 +448,7 @@ li:before {
**Одмах након инсталације:**
Када је CodeSwing инсталиран, видећете живи преглед вашег веб-сајта за резиме који се појављује у уређивачу. Ово вам омогућава да видите тачно како ваш сајт изгледа док правите промене.
![CodeSwing екстензија приказује живи преглед](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.sr.png)
![CodeSwing екстензија приказује живи преглед](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.sr.png)
**Разумевање побољшаног интерфејса:**
- **Подељен приказ**: **Приказује** ваш код са једне стране и живи преглед са друге

File diff suppressed because it is too large Load Diff

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "8b9d0562ea649b6012d1a67acc630681",
"translation_date": "2025-10-24T23:00:35+00:00",
"original_hash": "fea3a0fceb8ad86fd640c09cf63a2aac",
"translation_date": "2026-01-07T07:32:06+00:00",
"source_file": "README.md",
"language_code": "sr"
}
@ -17,246 +17,261 @@ CO_OP_TRANSLATOR_METADATA:
[![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Fork&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Star&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/stargazers/)
[![](https://dcbadge.vercel.app/api/server/ByRwuEEgH4)](https://discord.gg/zxKYvhSnVp?WT.mc_id=academic-000002-leestott)
[![Microsoft Foundry Discord](https://dcbadge.limes.pink/api/server/nTYy5BXMWG)](https://discord.gg/nTYy5BXMWG)
# Веб развој за почетнике - Курикулум
# Веб развој за почетнике - Наставни план
Научите основе веб развоја уз наш свеобухватни 12-недељни курс који су креирали Microsoft Cloud Advocates. Свака од 24 лекције обухвата JavaScript, CSS и HTML кроз практичне пројекте као што су тераријуми, екстензије за претраживач и свемирске игре. Укључите се у квизове, дискусије и практичне задатке. Унапредите своје вештине и оптимизујте задржавање знања уз нашу ефикасну педагогију засновану на пројектима. Започните своје путовање у свет програмирања већ данас!
Научите основе веб развоја уз наш свеобухватни курс од 12 недеља који воде Microsoft Cloud Advocates. Свих 24 лекције дубински истражује JavaScript, CSS и HTML кроз практичне пројекте као што су тераријуми, проширења прегледача и свемирске игре. Укључите се у квизове, дискусије и практичне задатке. Побољшајте своје вештине и оптимизујте задржавање знања уз нашу ефикасну педагогију засновану на пројектима. Започните своје кодирање већ данас!
Придружите се Azure AI Foundry Discord заједници
[![Microsoft Azure AI Foundry Discord](https://dcbadge.limes.pink/api/server/ByRwuEEgH4)](https://discord.com/invite/ByRwuEEgH4)
[![Microsoft Foundry Discord](https://dcbadge.limes.pink/api/server/nTYy5BXMWG)](https://discord.gg/nTYy5BXMWG)
Пратите ове кораке да бисте започели коришћење ових ресурса:
1. **Fork-ујте репозиторијум**: Кликните [![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/fork)
2. **Клонирајте репозиторијум**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
3. [**Придружите се Azure AI Foundry Discord и упознајте стручњаке и друге програмере**](https://discord.com/invite/ByRwuEEgH4)
Пратите ове кораке да бисте започели коришћењем ових ресурса:
1. **Прављење форка репозиторијума**: Кликните [![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/fork)
2. **Клонирање репозиторијума**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
3. [**Придружите се Azure AI Foundry Discord-у и упознајте експерте и друге програмере**](https://discord.com/invite/ByRwuEEgH4)
### 🌐 Подршка за више језика
#### Подржано преко GitHub Action (аутоматски и увек ажурирано)
#### Подржано преко GitHub Action-а (аутоматски и увек ажурирано)
<!-- CO-OP TRANSLATOR LANGUAGES TABLE START -->
[Арапски](../ar/README.md) | [Бенгалски](../bn/README.md) | [Бугарски](../bg/README.md) | [Бурмански (Мјанмар)](../my/README.md) | [Кинески (поједностављени)](../zh/README.md) | [Кинески (традиционални, Хонг Конг)](../hk/README.md) | [Кинески (традиционални, Макао)](../mo/README.md) | [Кинески (традиционални, Тајван)](../tw/README.md) | [Хрватски](../hr/README.md) | [Чешки](../cs/README.md) | [Дански](../da/README.md) | [Холандски](../nl/README.md) | [Естонски](../et/README.md) | [Фински](../fi/README.md) | [Француски](../fr/README.md) | [Немачки](../de/README.md) | [Грчки](../el/README.md) | [Хебрејски](../he/README.md) | [Хинди](../hi/README.md) | [Мађарски](../hu/README.md) | [Индонежански](../id/README.md) | [Италијански](../it/README.md) | [Јапански](../ja/README.md) | [Корејски](../ko/README.md) | [Литвански](../lt/README.md) | [Малајски](../ms/README.md) | [Марати](../mr/README.md) | [Непалски](../ne/README.md) | [Норвешки](../no/README.md) | [Персијски (фарси)](../fa/README.md) | [Пољски](../pl/README.md) | [Португалски (Бразил)](../br/README.md) | [Португалски (Португал)](../pt/README.md) | [Пенџапски (Гурмуки)](../pa/README.md) | [Румунски](../ro/README.md) | [Руски](../ru/README.md) | [Српски (ћирилица)](./README.md) | [Словачки](../sk/README.md) | [Словеначки](../sl/README.md) | [Шпански](../es/README.md) | [Свахили](../sw/README.md) | [Шведски](../sv/README.md) | [Тагалог (Филипински)](../tl/README.md) | [Тамилски](../ta/README.md) | [Тајландски](../th/README.md) | [Турски](../tr/README.md) | [Украјински](../uk/README.md) | [Урду](../ur/README.md) | [Вијетнамски](../vi/README.md)
[Arabic](../ar/README.md) | [Bengali](../bn/README.md) | [Bulgarian](../bg/README.md) | [Burmese (Myanmar)](../my/README.md) | [Chinese (Simplified)](../zh/README.md) | [Chinese (Traditional, Hong Kong)](../hk/README.md) | [Chinese (Traditional, Macau)](../mo/README.md) | [Chinese (Traditional, Taiwan)](../tw/README.md) | [Croatian](../hr/README.md) | [Czech](../cs/README.md) | [Danish](../da/README.md) | [Dutch](../nl/README.md) | [Estonian](../et/README.md) | [Finnish](../fi/README.md) | [French](../fr/README.md) | [German](../de/README.md) | [Greek](../el/README.md) | [Hebrew](../he/README.md) | [Hindi](../hi/README.md) | [Hungarian](../hu/README.md) | [Indonesian](../id/README.md) | [Italian](../it/README.md) | [Japanese](../ja/README.md) | [Kannada](../kn/README.md) | [Korean](../ko/README.md) | [Lithuanian](../lt/README.md) | [Malay](../ms/README.md) | [Malayalam](../ml/README.md) | [Marathi](../mr/README.md) | [Nepali](../ne/README.md) | [Nigerian Pidgin](../pcm/README.md) | [Norwegian](../no/README.md) | [Persian (Farsi)](../fa/README.md) | [Polish](../pl/README.md) | [Portuguese (Brazil)](../br/README.md) | [Portuguese (Portugal)](../pt/README.md) | [Punjabi (Gurmukhi)](../pa/README.md) | [Romanian](../ro/README.md) | [Russian](../ru/README.md) | [Serbian (Cyrillic)](./README.md) | [Slovak](../sk/README.md) | [Slovenian](../sl/README.md) | [Spanish](../es/README.md) | [Swahili](../sw/README.md) | [Swedish](../sv/README.md) | [Tagalog (Filipino)](../tl/README.md) | [Tamil](../ta/README.md) | [Telugu](../te/README.md) | [Thai](../th/README.md) | [Turkish](../tr/README.md) | [Ukrainian](../uk/README.md) | [Urdu](../ur/README.md) | [Vietnamese](../vi/README.md)
> **Волите да клонирате локално?**
> Овај репозиторијум укључује преко 50 превода на језике што значајно повећава величину преузимања. Да бисте клонирали без превода, користите sparse checkout:
> ```bash
> git clone --filter=blob:none --sparse https://github.com/microsoft/Web-Dev-For-Beginners.git
> cd Web-Dev-For-Beginners
> git sparse-checkout set --no-cone '/*' '!translations' '!translated_images'
> ```
> Ово вам даје све што вам треба за завршетак курса са знатно бржим преузимањем.
<!-- CO-OP TRANSLATOR LANGUAGES TABLE END -->
**Ако желите да се подрже додатни језици, списак је доступан [овде](https://github.com/Azure/co-op-translator/blob/main/getting_started/supported-languages.md)**
**Ако желите додатну подршку за језике превода, списак подржаних језика налази се [овде](https://github.com/Azure/co-op-translator/blob/main/getting_started/supported-languages.md)**
[![Open in Visual Studio Code](https://img.shields.io/static/v1?logo=visualstudiocode&label=&message=Open%20in%20Visual%20Studio%20Code&labelColor=2c2c32&color=007acc&logoColor=007acc)](https://open.vscode.dev/microsoft/Web-Dev-For-Beginners)
[![Отвори у Visual Studio Code](https://img.shields.io/static/v1?logo=visualstudiocode&label=&message=Open%20in%20Visual%20Studio%20Code&labelColor=2c2c32&color=007acc&logoColor=007acc)](https://open.vscode.dev/microsoft/Web-Dev-For-Beginners)
#### 🧑‍🎓 _Да ли сте студент?_
Посетите [**Student Hub страницу**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) где ћете пронаћи ресурсе за почетнике, студентске пакете, па чак и начине да добијете бесплатан ваучер за сертификат. Ово је страница коју треба да сачувате и повремено проверавате, јер се садржај мења сваког месеца.
Посетите [**Student Hub страницу**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) где ћете наћи ресурсе за почетнике, студентске пакете, па чак и начине да добијете бесплатан ваучер за сертификат. Ову страницу вреди означити и повремено проверавати јер месечно мењамо садржај.
### 📣 Обавештење - Нови изазови са GitHub Copilot Agent модом!
### 📣 Обавештење - Нови изазови за GitHub Copilot Agent режим!
Додат је нови изазов, потражите "GitHub Copilot Agent Challenge 🚀" у већини поглавља. То је нови изазов за вас који треба да завршите користећи GitHub Copilot и Agent мод. Ако раније нисте користили Agent мод, он је способан не само да генерише текст, већ и да креира и уређује фајлове, извршава команде и још много тога.
Додат је нови изазов, потражите "GitHub Copilot Agent Challenge 🚀" у већини поглавља. То је нови изазов који треба да завршите користећи GitHub Copilot и Agent режим. Ако раније нисте користили Agent режим, он није само способан да генерише текст већ и да креира и уређује датотеке, извршава команде и још много тога.
### 📣 Обавештење - _Нови пројекат за креирање уз помоћ генеративне вештачке интелигенције_
### 📣 Обавештење - _Нови пројекат који се гради уз помоћ Генеративне вештачке интелигенције_
Додат је нови пројекат AI асистента, погледајте [пројекат](./09-chat-project/README.md)
Нови АИ асистент пројекат управо додат, погледајте [пројекат](./9-chat-project/README.md)
### 📣 Обавештење - _Нови курикулум_ о генеративној вештачкој интелигенцији за JavaScript је управо објављен
### 📣 Обавештење - _Нови наставни план_ о Генеративној вештачкој интелигенцији за JavaScript управо објављен
Не пропустите наш нови курикулум о генеративној вештачкој интелигенцији!
Не пропустите наш нови курс о Генеративној вештачкој интелигенцији!
Посетите [https://aka.ms/genai-js-course](https://aka.ms/genai-js-course) да започнете!
![Background](../../translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.sr.png)
![Позадина](../../translated_images/background.148a8d43afde5730.sr.png)
- Лекције обухватају све од основа до RAG.
- Комуницирајте са историјским ликовима користећи GenAI и нашу придружену апликацију.
- Забавна и занимаљива приповест, путоваћете кроз време!
- Лекције које покривају све, од основа до RAG.
- Интеракција са историјским личностима уз помоћ GenAI и наше пратеће апликације.
- Забавна и ангажујућа нарација, путоваћете кроз време!
![лик](../../translated_images/character.5c0dd8e067ffd693.sr.png)
![character](../../translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.sr.png)
Свака лекција укључује задатак за завршетак, проверу знања и изазов који ће вас водити кроз учење тема као што су:
- Креирање упита и инжењеринг упита
Свака лекција укључује задатак за завршетак, проверу знања и изазов који вас води у учењу тема као што су:
- Написи и инженеринг упита
- Генерисање апликација за текст и слике
- Апликације за претрагу
Посетите [https://aka.ms/genai-js-course](../../[https:/aka.ms/genai-js-course) да започнете!
## 🌱 Почетак рада
## 🌱 Почетак
> **Наставници**, укључили смо [неке предлоге](for-teachers.md) како користити овај наставни план. Волео би да добијемо вашу повратну информацију [у нашем форуму за дискусију](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner)!
> **Наставници**, [укључили смо неке предлоге](for-teachers.md) о томе како да користите овај курикулум. Волели бисмо да чујемо ваше повратне информације [у нашем форуму за дискусију](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner)!
**[Ученици](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**, за сваку лекцију започните са квизом пре предавања, затим прочитајте материјал за предавање, извршите разне активности и проверите своје разумевање са квизом након предавања.
**[Ученици](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**, за сваку лекцију, започните са квизом пре предавања, наставите са читањем материјала за предавање, завршите разне активности и проверите своје разумевање кроз квиз након предавања.
Да бисте побољшали своје искуство учења, повежите се са својим вршњацима да заједно радите на пројектима! Дискусије су охрабрене у нашем [форуму за дискусију](https://github.com/microsoft/Web-Dev-For-Beginners/discussions) где ће бити доступан тим модератора за одговарање на ваша питања.
Да бисте побољшали своје искуство учења, повежите се са својим вршњацима како бисте заједно радили на пројектима! Дискусије су охрабрене у нашем [форуму за дискусију](https://github.com/microsoft/Web-Dev-For-Beginners/discussions) где ће наш тим модератора бити доступан да одговори на ваша питања.
За даље усавршавање, топло препоручујемо да истражите [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) за додатне материјале за учење.
Да бисте додатно унапредили своје образовање, топло препоручујемо да истражите [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) за додатне материјале за учење.
### 📋 Подеси своје окружење
### 📋 Постављање вашег окружења
Овај наставни план има спремно окружење за развој! Када почнете, можете изабрати да покренете наставни план у [Codespace-у](https://github.com/features/codespaces/) (_окружење засновано на прегледачу, без потребе инсталације_), или локално на свом рачунару користећи текст едитор као што је [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
Овај курикулум има спремно окружење за развој! Када започнете, можете изабрати да покренете курикулум у [Codespace](https://github.com/features/codespaces/) (_окружење засновано на претраживачу, без потребе за инсталацијом_), или локално на вашем рачунару користећи текст едитор као што је [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
#### Креирајте свој репозиторијум
Да бисте лако сачували свој рад, препоручујемо да креирате своју копију овог репозиторијума. То можете урадити кликом на дугме **Use this template** на врху странице. Ово ће креирати нови репозиторијум на вашем GitHub налогу са копијом курикулума.
#### Креирај свој репозиторијум
Да бисте лако сачували свој рад, препоручује се да направите своју копију овог репозиторијума. То можете урадити кликом на дугме **Use this template** на врху странице. Ово ће креирати нови репозиторијум на вашем GitHub налогу са копијом наставног плана.
Пратите ове кораке:
1. **Fork-ујте репозиторијум**: Кликните на дугме "Fork" у горњем десном углу ове странице.
2. **Клонирајте репозиторијум**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
1. **Направи форк репозиторијума**: Кликните на дугме "Fork" у горњем десном углу ове странице.
2. **Клонирај репозиторијум**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
#### Покретање курикулума у Codespace-у
#### Покретање наставног плана у Codespace-у
У вашој копији овог репозиторијума који сте креирали, кликните на дугме **Code** и изаберите **Open with Codespaces**. Ово ће креирати нови Codespace за вас у коме можете радити.
У својој копији овог репозиторијума коју сте направили, кликните на дугме **Code** и изаберите **Open with Codespaces**. Ово ће креирати нови Codespace у којем ћете радити.
![Codespace](../../translated_images/createcodespace.0238bbf4d7a8d955fa8fa7f7b6602a3cb6499a24708fbee589f83211c5a613b7.sr.png)
![Codespace](../../translated_images/createcodespace.0238bbf4d7a8d955.sr.png)
#### Покретање курикулума локално на вашем рачунару
#### Покретање наставног плана локално на вашем рачунару
Да бисте покренули овај курикулум локално на вашем рачунару, биће вам потребан текст едитор, претраживач и алат за командну линију. Наша прва лекција, [Увод у програмске језике и алате](../../1-getting-started-lessons/1-intro-to-programming-languages), ће вас провести кроз разне опције за сваки од ових алата како бисте изабрали оно што вам највише одговара.
Да бисте покренули овај наставни план локално на вашем рачунару, потребан вам је текст едитор, прегледач и командна линија. Наша прва лекција, [Увод у програмске језике и алате](../../1-getting-started-lessons/1-intro-to-programming-languages), ће вас провести кроз различите опције за сваки од ових алата како бисте изабрали шта вам највише одговара.
Наша препорука је да користите [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) као ваш едитор, који такође има уграђен [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon). Можете преузети Visual Studio Code [овде](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
Препоручујемо коришћење [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) као едитора, који има уграђени и [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon). Visual Studio Code можете преузети [овде](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon).
1. Клонирајте свој репозиторијум на ваш рачунар. То можете урадити кликом на дугме **Code** и копирањем URL-а:
1. Клонирајте свој репозиторијум на свој рачунар. То можете учинити кликом на дугме **Code** и копирањем URL-а:
[CodeSpace](./images/createcodespace.png)
Затим, отворите [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) унутар [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) и покрените следећу команду, замењујући `<your-repository-url>` са URL-ом који сте управо копирали:
Затим, отворите [Терминал](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) у оквиру [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) и покрените следећу команду, замењујући `<your-repository-url>` URL-ом који сте управо копирали:
```bash
git clone <your-repository-url>
```
2. Отворите фасциклу у Visual Studio Code-у. Ово можете урадити тако што ћете кликнути на **File** > **Open Folder** и изабрати фасциклу коју сте управо клонирали.
2. Отворите фасциклу у Visual Studio Code. То можете урадити кликом на **File** > **Open Folder** и одабиром фасцикле коју сте управо клонирали.
> Препоручени додатци за Visual Studio Code:
> Препоручене Visual Studio Code проширења:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - za pregled HTML stranica unutar Visual Studio Code-a
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - za brže pisanje koda
## 📂 Svaka lekcija uključuje:
- opcionalnu sketchnote
- opcionalni dodatni video
- kviz za zagrevanje pre lekcije
- pisanu lekciju
- za lekcije zasnovane na projektima, vodiče korak po korak kako izgraditi projekat
- provere znanja
- izazov
- dodatno čitanje
- zadatak
- [kviz nakon lekcije](https://ff-quizzes.netlify.app/web/)
> **Napomena o kvizovima**: Svi kvizovi se nalaze u folderu Quiz-app, ukupno 48 kvizova sa po tri pitanja. Dostupni su [ovde](https://ff-quizzes.netlify.app/web/), aplikacija za kviz može se pokrenuti lokalno ili postaviti na Azure; pratite uputstva u folderu `quiz-app`.
## 🗃️ Lekcije
| | Naziv projekta | Naučeni koncepti | Ciljevi učenja | Povezana lekcija | Autor |
| :-: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
| 01 | Početak | Uvod u programiranje i alati za rad | Naučite osnovne principe većine programskih jezika i o softveru koji pomaže profesionalnim programerima u njihovom poslu | [Uvod u programske jezike i alate za rad](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | Početak | Osnove GitHub-a, uključujući rad u timu | Kako koristiti GitHub u vašem projektu, kako sarađivati sa drugima na kodnoj bazi | [Uvod u GitHub](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | Početak | Pristupačnost | Naučite osnove web pristupačnosti | [Osnove pristupačnosti](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | Osnove JS | Tipovi podataka u JavaScript-u | Osnove tipova podataka u JavaScript-u | [Tipovi podataka](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | Osnove JS | Funkcije i metode | Naučite o funkcijama i metodama za upravljanje logikom aplikacije | [Funkcije i metode](./2-js-basics/2-functions-methods/README.md) | Jasmine i Christopher |
| 06 | Osnove JS | Donošenje odluka u JS | Naučite kako kreirati uslove u vašem kodu koristeći metode za donošenje odluka | [Donošenje odluka](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | Osnove JS | Nizovi i petlje | Rad sa podacima koristeći nizove i petlje u JavaScript-u | [Nizovi i petlje](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [Terarijum](./3-terrarium/solution/README.md) | HTML u praksi | Kreirajte HTML za izradu online terarijuma, fokusirajući se na izradu rasporeda | [Uvod u HTML](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [Terarijum](./3-terrarium/solution/README.md) | CSS u praksi | Kreirajte CSS za stilizovanje online terarijuma, fokusirajući se na osnove CSS-a uključujući pravljenje responzivne stranice | [Uvod u CSS](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Terarijum](./3-terrarium/solution/README.md) | JavaScript zatvaranja, manipulacija DOM-a | Kreirajte JavaScript kako bi terarijum funkcionisao kao interfejs za prevlačenje i ispuštanje, fokusirajući se na zatvaranja i manipulaciju DOM-a | [JavaScript zatvaranja, manipulacija DOM-a](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [Igra kucanja](./4-typing-game/solution/README.md) | Kreiranje igre kucanja | Naučite kako koristiti događaje tastature za upravljanje logikom vaše JavaScript aplikacije | [Programiranje vođeno događajima](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [Ekstenzija za zeleni pretraživač](./5-browser-extension/solution/README.md) | Rad sa pretraživačima | Naučite kako pretraživači funkcionišu, njihovu istoriju i kako postaviti osnovne elemente ekstenzije za pretraživač | [O pretraživačima](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [Ekstenzija za zeleni pretraživač](./5-browser-extension/solution/README.md) | Kreiranje forme, pozivanje API-ja i čuvanje promenljivih u lokalnom skladištu | Kreirajte JavaScript elemente vaše ekstenzije za pretraživač kako biste pozvali API koristeći promenljive sačuvane u lokalnom skladištu | [API-ji, forme i lokalno skladište](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [Ekstenzija za zeleni pretraživač](./5-browser-extension/solution/README.md) | Pozadinski procesi u pretraživaču, web performanse | Koristite pozadinske procese pretraživača za upravljanje ikonom ekstenzije; naučite o web performansama i nekim optimizacijama | [Pozadinski zadaci i performanse](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [Svemirska igra](./6-space-game/solution/README.md) | Napredniji razvoj igara sa JavaScript-om | Naučite o nasleđivanju koristeći klase i kompoziciju, kao i o Pub/Sub šablonu, kao pripremu za izradu igre | [Uvod u napredni razvoj igara](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [Svemirska igra](./6-space-game/solution/README.md) | Crtanje na platnu | Naučite o Canvas API-ju, koji se koristi za crtanje elemenata na ekranu | [Crtanje na platnu](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [Svemirska igra](./6-space-game/solution/README.md) | Pomicanje elemenata po ekranu | Otkrijte kako elementi mogu dobiti pokret koristeći kartezijanske koordinate i Canvas API | [Pomicanje elemenata](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [Svemirska igra](./6-space-game/solution/README.md) | Detekcija sudara | Omogućite sudaranje elemenata i njihovu međusobnu reakciju koristeći pritiske na tastaturi i obezbedite funkciju hlađenja za performanse igre | [Detekcija sudara](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [Svemirska igra](./6-space-game/solution/README.md) | Brojanje poena | Izvršite matematičke proračune na osnovu statusa i performansi igre | [Brojanje poena](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [Svemirska igra](./6-space-game/solution/README.md) | Završavanje i ponovno pokretanje igre | Naučite o završavanju i ponovnom pokretanju igre, uključujući čišćenje resursa i resetovanje vrednosti promenljivih | [Završni uslov](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [Bankarska aplikacija](./7-bank-project/solution/README.md) | HTML šabloni i rute u web aplikaciji | Naučite kako kreirati osnovu arhitekture veb sajta sa više stranica koristeći rute i HTML šablone | [HTML šabloni i rute](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [Bankarska aplikacija](./7-bank-project/solution/README.md) | Kreiranje forme za prijavu i registraciju | Naučite kako kreirati forme i rukovati procedurama validacije rutina | [Forme](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [Bankarska aplikacija](./7-bank-project/solution/README.md) | Metode za preuzimanje i korišćenje podataka | Kako podaci teku u i iz vaše aplikacije, kako ih preuzeti, sačuvati i obraditi | [Podaci](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [Bankarska aplikacija](./7-bank-project/solution/README.md) | Koncepti upravljanja stanjem | Naučite kako vaša aplikacija zadržava stanje i kako ga programerski upravljati | [Upravljanje stanjem](./7-bank-project/4-state-management/README.md) | Yohan |
| 25 | [Pretraživač/VScode kod](../../8-code-editor) | Rad sa VScode-om | Naučite kako koristiti editor koda| [Koristite VScode editor koda](./8-code-editor/1-using-a-code-editor/README.md) | Chris |
| 26 | [AI asistenti](./9-chat-project/README.md) | Rad sa AI | Naučite kako kreirati sopstvenog AI asistenta | [Projekat AI asistenta](./9-chat-project/README.md) | Chris |
## 🏫 Pedagogija
Naš kurikulum je dizajniran sa dva ključna pedagoška principa:
* učenje zasnovano na projektima
* česti kvizovi
Program podučava osnove JavaScript-a, HTML-a i CSS-a, kao i najnovije alate i tehnike koje koriste današnji web programeri. Studenti će imati priliku da steknu praktično iskustvo kroz izradu igre kucanja, virtuelnog terarijuma, ekološke ekstenzije za pretraživač, igre u stilu svemirskih invazija i bankarske aplikacije za preduzeća. Na kraju serije, studenti će steći solidno razumevanje web razvoja.
> 🎓 Prve lekcije iz ovog kurikuluma možete pohađati kao [Put učenja](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) na Microsoft Learn!
Osiguravanjem da sadržaj bude usklađen sa projektima, proces učenja postaje zanimljiviji za studente, a zadržavanje koncepta se povećava. Takođe smo napisali nekoliko početnih lekcija o osnovama JavaScript-a kako bismo uveli koncepte, u kombinaciji sa video zapisima iz kolekcije "[Serija za početnike: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)", čiji su neki autori doprineli ovom kurikulumu.
Pored toga, kviz sa niskim rizikom pre časa postavlja nameru studenta prema učenju teme, dok drugi kviz nakon časa osigurava dalju retenciju. Ovaj kurikulum je dizajniran da bude fleksibilan i zabavan i može se pohađati u celini ili delimično. Projekti počinju mali i postaju sve složeniji do kraja 12-nedeljnog ciklusa.
Iako smo namerno izbegli uvođenje JavaScript okvira kako bismo se koncentrisali na osnovne veštine potrebne kao web programer pre usvajanja okvira, dobar sledeći korak nakon završetka ovog kurikuluma bio bi učenje o Node.js-u putem druge kolekcije video zapisa: "[Serija za početnike: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)".
> Posetite naš [Kodeks ponašanja](CODE_OF_CONDUCT.md) i smernice za [Doprinos](CONTRIBUTING.md). Cenimo vaše konstruktivne povratne informacije!
## 🧭 Pristup van mreže
Možete pokrenuti ovu dokumentaciju van mreže koristeći [Docsify](https://docsify.js.org/#/). Forkujte ovaj repo, [instalirajte Docsify](https://docsify.js.org/#/quickstart) na vašem lokalnom računaru, a zatim u root folderu ovog repo-a, ukucajte `docsify serve`. Veb-sajt će biti poslužen na portu 3000 na vašem localhost-u: `localhost:3000`.
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - за преглед HTML страница унутар Visual Studio Code-а
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - помоћ при бржем писању кода
## 📂 Сваки час укључује:
- опционални скицнот
- опционални додатни видео
- квиз за загревање пре часа
- писани час
- за часове засноване на пројектима, корак по корак водиче како направити пројекат
- провере знања
- изазов
- додатно читање
- задатак
- [квиз после часа](https://ff-quizzes.netlify.app/web/)
> **Напомена о квизовима**: Сви квизови се налазе у фасцикли Quiz-app, укупно 48 квизова са по три питања. Доступни су [овде](https://ff-quizzes.netlify.app/web/), апликацију за квиз можете покренути локално или је депловати на Azure; пратите упутства у фасцикли `quiz-app`.
## 🗃️ Часови
| | Назив пројекта | Концепти који се уче | Циљеви учења | Повољни час | Аутор |
| :-: | :-------------------------------------------------------: | :------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :--------------------: |
| 01 | Почетак рада | Увод у програмирање и алати струке | Научите основне основе које стоје иза већине програмских језика и о софтверу који помаже професионалним програмерима у раду | [Увод у програмске језике и алате струке](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | Почетак рада | Основе GitHub-а, укључујући рад у тиму | Како користити GitHub у вашем пројекту, како сарађивати са другима на коду | [Увод у GitHub](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | Почетак рада | Приступачност | Научите основе веб приступачности | [Основе приступачности](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | Основе JS | Типови података у JavaScript | Основе типова података у JavaScript | [Типови података](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | Основе JS | Функције и методе | Научите о функцијама и методама за управљање логичким током апликације | [Функције и методе](./2-js-basics/2-functions-methods/README.md) | Jasmine и Christopher |
| 06 | Основе JS | Доношење одлука са JS | Научите како да креирате услове у вашем коду користећи методе доношења одлука | [Доношење одлука](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | Основе JS | Низови и петље | Рад са подацима користећи низове и петље у JavaScript | [Низови и петље](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [Тераријум](./3-terrarium/solution/README.md) | Практичан HTML | Креирање HTML-а за онлајн тераријум, фокусирајући се на прављење распореда | [Увод у HTML](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [Тераријум](./3-terrarium/solution/README.md) | Практичан CSS | Креирање CSS-а за стилизацију онлајн тераријума, укључујући основе CSS и прављење странице прилагодљивом | [Увод у CSS](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Тераријум](./3-terrarium/solution/README.md) | JavaScript затварања, манипулација DOM-ом | Креирање JavaScript-а за прављење тераријума који функционише као drag/drop интерфејс, фокус на затварања и манипулацију DOM-ом | [JavaScript затварања, манипулација DOM-ом](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [Typing Game](./4-typing-game/solution/README.md) | Прављење игре куцања | Научите како да користите догађаје са тастатуре да покрећете логику ваше JavaScript апликације | [Програмирање илијано догађајима](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Рад са прегледачима | Научите како прегледачи раде, њихову историју, и како да направите прве елементе проширења прегледача | [О прегледачима](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Креирање форме, позив API-ја и чување у локалну меморију | Креирање JavaScript елемената за проширење прегледача за позив API-ја користећи променљиве из локалне меморије | [API-ји, форме и локална меморија](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [Green Browser Extension](./5-browser-extension/solution/README.md) | Позадински процеси у прегледачу, веб перформансе | Користите позадинске процесе прегледача за управљање иконом проширења; научите о веб перформансама и оптимизацијама | [Позадински задаци и перформансе](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [Space Game](./6-space-game/solution/README.md) | Напредније развијање игара у JavaScript-у | Научите о Наслеђивању користећи класе и композицију и модел Pub/Sub, као припрема за прављење игре | [Увод у напредни развој игара](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [Space Game](./6-space-game/solution/README.md) | Цртање на канвасу | Научите о Canvas API-ју који се користи за цртање елемената на екран | [Цртање на канвасу](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [Space Game](./6-space-game/solution/README.md) | Померање елемената по екрану | Откријте како елементи могу добити кретање користећи картеријеве координате и Canvas API | [Померање елемената](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [Space Game](./6-space-game/solution/README.md) | Детекција судара | Учини да се елементи сударају и реагују користећи притиске тастера и обезбедите cooldown функцију за боље перформансе игре | [Детекција судара](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [Space Game](./6-space-game/solution/README.md) | Вођење резултата | Изводите математичке прорачуне на основу статуса и перформанси игре | [Вођење резултата](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [Space Game](./6-space-game/solution/README.md) | Завршавање и поновно покретање игре | Научите о завршавању и поновном покретању игре, укључујући чишћење ресурса и ресетовање вредности променљивих | [Услов завршетка](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [Banking App](./7-bank-project/solution/README.md) | HTML шаблони и руте у веб апликацији | Научите како створити скелет архитектуре вишестраначног сајта коришћењем рутовања и HTML шаблона | [HTML шаблони и руте](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [Banking App](./7-bank-project/solution/README.md) | Прављење форме за пријаву и регистрацију | Научите о прављењу форми и руковању валидацијом | [Форме](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [Banking App](./7-bank-project/solution/README.md) | Начини дохватања и коришћења података | Како подаци улазе у ваш апликативни систем и излазе из њега, како их дохватити, чувати и одбацити | [Подаци](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [Banking App](./7-bank-project/solution/README.md) | Концепти управљања стањем | Научите како ваш апликативни систем задржава стање и како га програмирати | [Управљање стањем](./7-bank-project/4-state-management/README.md) | Yohan |
| 25 | [Browser/VScode Code](../../8-code-editor) | Рад са VScode | Научите како да користите уређивач кода | [Користите VScode Code Editor](./8-code-editor/1-using-a-code-editor/README.md) | Chris |
| 26 | [AI Assistants](./9-chat-project/README.md) | Рад са вештачком интелигенцијом | Научите како да направите свог AI помоћника | [Пројекат AI асистента](./9-chat-project/README.md) | Chris |
## 🏫 Педагогија
Наш наставни план и програм је осмишљен уз две кључне педагошке принципе:
* учење засновано на пројектима
* чести квизови
Програм учи основе JavaScript-а, HTML-а и CSS-а, као и најновије алате и технике које користе савремени веб програмери. Студенти ће имати прилику да стекну практично искуство прављењем игре куцања, виртуелног тераријума, еколошки прихватљивог проширења за прегледач, игре у стилу освајача свемира и банкарске апликације за пословање. До краја серије, студенти ће имати чврсто разумевање веб развоја.
> 🎓 Прве часове овог курикулума можете пратити као [Learn Path](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) на Microsoft Learn!
Обезбеђивањем усклађености садржаја са пројектима, процес учења постаје занимљивији за студенте и повећава њихово задржавање појмова. Такође смо написали неколико почетних часова о основама JavaScript-а који уводе појмове, у пару са видео записом из колекције видео туторијала "[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)", чији су неки аутори допринели овом курикулуму.
Поред тога, квиз са ниским улазним захтевима пре часа поставља циљ студента у односу на учење теме, док други квиз после часа осигурава даље задржавање знања. Овај курикулум је развијен да буде флексибилан и забаван и може се похађати у целости или делимично. Пројекти почињу мали и постају све сложенији до краја 12-недељног циклуса.
Иако намерно нисмо увели JavaScript фрејмворке јер смо се фокусирали на основне вештине неопходне веб програмеру пре усвајања фрејмворка, добар следећи корак за завршетак овог курикулума био би учење о Node.js кроз другу колекцију видео записа: "[Beginner Series to: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)".
> Посетите наша упутства [Code of Conduct](CODE_OF_CONDUCT.md) и [Contributing](CONTRIBUTING.md). Добродошли су ваши конструктивни коментари!
## 🧭 Приступ ван мреже
Ову документацију можете користити ван мреже помоћу [Docsify](https://docsify.js.org/#/). Форкујте овај репозиторијум, [инсталирајте Docsify](https://docsify.js.org/#/quickstart) на вашем локалном рачунару, а затим у главној фасцикли овог репозиторијума укуцајте `docsify serve`. Вебсајт ће бити доступан на порту 3000 на вашем локалхосту: `localhost:3000`.
## 📘 PDF
PDF svih lekcija možete pronaći [ovde](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf).
ПДФ свих часова се може пронаћи [овде](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf).
## 🎒 Ostali kursevi
Naš tim proizvodi i druge kurseve! Pogledajte:
## 🎒 Остали курсеви
Наш тим производи и друге курсеве! Погледајте:
### Azure / Edge / MCP / Agents
[![AZD za početnike](https://img.shields.io/badge/AZD%20for%20Beginners-0078D4?style=for-the-badge&labelColor=E5E7EB&color=0078D4)](https://github.com/microsoft/AZD-for-beginners?WT.mc_id=academic-105485-koreyst)
[![Edge AI za početnike](https://img.shields.io/badge/Edge%20AI%20za%20početnike-00B8E4?style=for-the-badge&labelColor=E5E7EB&color=00B8E4)](https://github.com/microsoft/edgeai-for-beginners?WT.mc_id=academic-105485-koreyst)
[![MCP za početnike](https://img.shields.io/badge/MCP%20za%20početnike-009688?style=for-the-badge&labelColor=E5E7EB&color=009688)](https://github.com/microsoft/mcp-for-beginners?WT.mc_id=academic-105485-koreyst)
[![AI agenti za početnike](https://img.shields.io/badge/AI%20agenti%20za%20početnike-00C49A?style=for-the-badge&labelColor=E5E7EB&color=00C49A)](https://github.com/microsoft/ai-agents-for-beginners?WT.mc_id=academic-105485-koreyst)
<!-- CO-OP TRANSLATOR OTHER COURSES START -->
### LangChain
[![LangChain4j for Beginners](https://img.shields.io/badge/LangChain4j%20for%20Beginners-22C55E?style=for-the-badge&&labelColor=E5E7EB&color=0553D6)](https://aka.ms/langchain4j-for-beginners)
[![LangChain.js for Beginners](https://img.shields.io/badge/LangChain.js%20for%20Beginners-22C55E?style=for-the-badge&labelColor=E5E7EB&color=0553D6)](https://aka.ms/langchainjs-for-beginners?WT.mc_id=m365-94501-dwahlin)
---
### Serija o generativnoj veštačkoj inteligenciji
[![Generativna veštačka inteligencija za početnike](https://img.shields.io/badge/Generativna%20veštačka%20inteligencija%20za%20početnike-8B5CF6?style=for-the-badge&labelColor=E5E7EB&color=8B5CF6)](https://github.com/microsoft/generative-ai-for-beginners?WT.mc_id=academic-105485-koreyst)
[![Generativna veštačka inteligencija (.NET)](https://img.shields.io/badge/Generativna%20veštačka%20inteligencija%20(.NET)-9333EA?style=for-the-badge&labelColor=E5E7EB&color=9333EA)](https://github.com/microsoft/Generative-AI-for-beginners-dotnet?WT.mc_id=academic-105485-koreyst)
[![Generativna veštačka inteligencija (Java)](https://img.shields.io/badge/Generativna%20veštačka%20inteligencija%20(Java)-C084FC?style=for-the-badge&labelColor=E5E7EB&color=C084FC)](https://github.com/microsoft/generative-ai-for-beginners-java?WT.mc_id=academic-105485-koreyst)
[![Generativna veštačka inteligencija (JavaScript)](https://img.shields.io/badge/Generativna%20veštačka%20inteligencija%20(JavaScript)-E879F9?style=for-the-badge&labelColor=E5E7EB&color=E879F9)](https://github.com/microsoft/generative-ai-with-javascript?WT.mc_id=academic-105485-koreyst)
### Azure / Edge / MCP / Agents
[![AZD for Beginners](https://img.shields.io/badge/AZD%20for%20Beginners-0078D4?style=for-the-badge&labelColor=E5E7EB&color=0078D4)](https://github.com/microsoft/AZD-for-beginners?WT.mc_id=academic-105485-koreyst)
[![Edge AI for Beginners](https://img.shields.io/badge/Edge%20AI%20for%20Beginners-00B8E4?style=for-the-badge&labelColor=E5E7EB&color=00B8E4)](https://github.com/microsoft/edgeai-for-beginners?WT.mc_id=academic-105485-koreyst)
[![MCP for Beginners](https://img.shields.io/badge/MCP%20for%20Beginners-009688?style=for-the-badge&labelColor=E5E7EB&color=009688)](https://github.com/microsoft/mcp-for-beginners?WT.mc_id=academic-105485-koreyst)
[![AI Agents for Beginners](https://img.shields.io/badge/AI%20Agents%20for%20Beginners-00C49A?style=for-the-badge&labelColor=E5E7EB&color=00C49A)](https://github.com/microsoft/ai-agents-for-beginners?WT.mc_id=academic-105485-koreyst)
---
### Osnovno učenje
[![Mašinsko učenje za početnike](https://img.shields.io/badge/Mašinsko%20učenje%20za%20početnike-22C55E?style=for-the-badge&labelColor=E5E7EB&color=22C55E)](https://aka.ms/ml-beginners?WT.mc_id=academic-105485-koreyst)
[![Nauka o podacima za početnike](https://img.shields.io/badge/Nauka%20o%20podacima%20za%20početnike-84CC16?style=for-the-badge&labelColor=E5E7EB&color=84CC16)](https://aka.ms/datascience-beginners?WT.mc_id=academic-105485-koreyst)
[![Veštačka inteligencija za početnike](https://img.shields.io/badge/Veštačka%20inteligencija%20za%20početnike-A3E635?style=for-the-badge&labelColor=E5E7EB&color=A3E635)](https://aka.ms/ai-beginners?WT.mc_id=academic-105485-koreyst)
[![Sajber bezbednost za početnike](https://img.shields.io/badge/Sajber%20bezbednost%20za%20početnike-F97316?style=for-the-badge&labelColor=E5E7EB&color=F97316)](https://github.com/microsoft/Security-101?WT.mc_id=academic-96948-sayoung)
[![Web razvoj za početnike](https://img.shields.io/badge/Web%20razvoj%20za%20početnike-EC4899?style=for-the-badge&labelColor=E5E7EB&color=EC4899)](https://aka.ms/webdev-beginners?WT.mc_id=academic-105485-koreyst)
[![IoT za početnike](https://img.shields.io/badge/IoT%20za%20početnike-14B8A6?style=for-the-badge&labelColor=E5E7EB&color=14B8A6)](https://aka.ms/iot-beginners?WT.mc_id=academic-105485-koreyst)
[![Razvoj XR za početnike](https://img.shields.io/badge/Razvoj%20XR%20za%20početnike-38BDF8?style=for-the-badge&labelColor=E5E7EB&color=38BDF8)](https://github.com/microsoft/xr-development-for-beginners?WT.mc_id=academic-105485-koreyst)
### Сериија генеративне вештачке интелигенције
[![Generative AI for Beginners](https://img.shields.io/badge/Generative%20AI%20for%20Beginners-8B5CF6?style=for-the-badge&labelColor=E5E7EB&color=8B5CF6)](https://github.com/microsoft/generative-ai-for-beginners?WT.mc_id=academic-105485-koreyst)
[![Generative AI (.NET)](https://img.shields.io/badge/Generative%20AI%20(.NET)-9333EA?style=for-the-badge&labelColor=E5E7EB&color=9333EA)](https://github.com/microsoft/Generative-AI-for-beginners-dotnet?WT.mc_id=academic-105485-koreyst)
[![Generative AI (Java)](https://img.shields.io/badge/Generative%20AI%20(Java)-C084FC?style=for-the-badge&labelColor=E5E7EB&color=C084FC)](https://github.com/microsoft/generative-ai-for-beginners-java?WT.mc_id=academic-105485-koreyst)
[![Generative AI (JavaScript)](https://img.shields.io/badge/Generative%20AI%20(JavaScript)-E879F9?style=for-the-badge&labelColor=E5E7EB&color=E879F9)](https://github.com/microsoft/generative-ai-with-javascript?WT.mc_id=academic-105485-koreyst)
---
### Основно учење
[![ML for Beginners](https://img.shields.io/badge/ML%20for%20Beginners-22C55E?style=for-the-badge&labelColor=E5E7EB&color=22C55E)](https://aka.ms/ml-beginners?WT.mc_id=academic-105485-koreyst)
[![Data Science for Beginners](https://img.shields.io/badge/Data%20Science%20for%20Beginners-84CC16?style=for-the-badge&labelColor=E5E7EB&color=84CC16)](https://aka.ms/datascience-beginners?WT.mc_id=academic-105485-koreyst)
[![AI for Beginners](https://img.shields.io/badge/AI%20for%20Beginners-A3E635?style=for-the-badge&labelColor=E5E7EB&color=A3E635)](https://aka.ms/ai-beginners?WT.mc_id=academic-105485-koreyst)
[![Cybersecurity for Beginners](https://img.shields.io/badge/Cybersecurity%20for%20Beginners-F97316?style=for-the-badge&labelColor=E5E7EB&color=F97316)](https://github.com/microsoft/Security-101?WT.mc_id=academic-96948-sayoung)
[![Web Dev for Beginners](https://img.shields.io/badge/Web%20Dev%20for%20Beginners-EC4899?style=for-the-badge&labelColor=E5E7EB&color=EC4899)](https://aka.ms/webdev-beginners?WT.mc_id=academic-105485-koreyst)
[![IoT for Beginners](https://img.shields.io/badge/IoT%20for%20Beginners-14B8A6?style=for-the-badge&labelColor=E5E7EB&color=14B8A6)](https://aka.ms/iot-beginners?WT.mc_id=academic-105485-koreyst)
[![XR Development for Beginners](https://img.shields.io/badge/XR%20Development%20for%20Beginners-38BDF8?style=for-the-badge&labelColor=E5E7EB&color=38BDF8)](https://github.com/microsoft/xr-development-for-beginners?WT.mc_id=academic-105485-koreyst)
### Serija o Copilot-u
[![Copilot za AI programiranje u paru](https://img.shields.io/badge/Copilot%20za%20AI%20programiranje%20u%20paru-FACC15?style=for-the-badge&labelColor=E5E7EB&color=FACC15)](https://aka.ms/GitHubCopilotAI?WT.mc_id=academic-105485-koreyst)
[![Copilot za C#/.NET](https://img.shields.io/badge/Copilot%20za%20C%23/.NET-FBBF24?style=for-the-badge&labelColor=E5E7EB&color=FBBF24)](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers?WT.mc_id=academic-105485-koreyst)
[![Copilot avantura](https://img.shields.io/badge/Copilot%20avantura-FDE68A?style=for-the-badge&labelColor=E5E7EB&color=FDE68A)](https://github.com/microsoft/CopilotAdventures?WT.mc_id=academic-105485-koreyst)
---
### Сериија Copilot
[![Copilot for AI Paired Programming](https://img.shields.io/badge/Copilot%20for%20AI%20Paired%20Programming-FACC15?style=for-the-badge&labelColor=E5E7EB&color=FACC15)](https://aka.ms/GitHubCopilotAI?WT.mc_id=academic-105485-koreyst)
[![Copilot for C#/.NET](https://img.shields.io/badge/Copilot%20for%20C%23/.NET-FBBF24?style=for-the-badge&labelColor=E5E7EB&color=FBBF24)](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers?WT.mc_id=academic-105485-koreyst)
[![Copilot Adventure](https://img.shields.io/badge/Copilot%20Adventure-FDE68A?style=for-the-badge&labelColor=E5E7EB&color=FDE68A)](https://github.com/microsoft/CopilotAdventures?WT.mc_id=academic-105485-koreyst)
<!-- CO-OP TRANSLATOR OTHER COURSES END -->
## Dobijanje pomoći
## Подаци о помоћи
Ako se zaglavite ili imate pitanja o izradi AI aplikacija, pridružite se:
Ако вам затреба помоћ или имате питања о прављењу апликација са вештачком интелигенцијом. Придружите се другима који уче и искусним програмерима у дискусијама о MCP. То је подржавајућа заједница где су питања добродошла, а знање слободно дели.
[![Azure AI Foundry Discord](https://img.shields.io/badge/Discord-Azure_AI_Foundry_Community_Discord-blue?style=for-the-badge&logo=discord&color=5865f2&logoColor=fff)](https://aka.ms/foundry/discord)
[![Microsoft Foundry Discord](https://dcbadge.limes.pink/api/server/nTYy5BXMWG)](https://discord.gg/nTYy5BXMWG)
Ako imate povratne informacije o proizvodu ili greške tokom izrade, posetite:
Ако имате повратне информације о производу или грешке током програмирања посетите:
[![Azure AI Foundry Developer Forum](https://img.shields.io/badge/GitHub-Azure_AI_Foundry_Developer_Forum-blue?style=for-the-badge&logo=github&color=000000&logoColor=fff)](https://aka.ms/foundry/forum)
[![Microsoft Foundry Developer Forum](https://img.shields.io/badge/GitHub-Microsoft_Foundry_Developer_Forum-blue?style=for-the-badge&logo=github&color=000000&logoColor=fff)](https://aka.ms/foundry/forum)
## Licenca
## Лиценца
Ovaj repozitorijum je licenciran pod MIT licencom. Pogledajte [LICENSE](../../LICENSE) datoteku za više informacija.
Овај репозиторијум је лиценциран под MIT лиценцом. Погледајте датотеку [LICENSE](../../LICENSE) за више информација.
---
**Одрицање од одговорности**:
Овај документ је преведен помоћу услуге за превођење уз помоћ вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на изворном језику треба сматрати меродавним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Одрицање одговорности**:
Овај документ је преведен коришћењем AI сервиса за превођење [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде тачан, имајте у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом матерњем језику треба сматрати ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешне тумачења проистекла из употребе овог превода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->

@ -42,10 +42,10 @@ CO_OP_TRANSLATOR_METADATA:
- Moodle Cloud има ограничену подршку за Common Cartridge. Преферирајте горњу Moodle датотеку, која се такође може учитати у Canvas.
- Након увоза, прегледајте модуле, датуме предаје и подешавања квизова како би одговарали вашем распореду термина.
![Moodle](../../translated_images/moodle.94eb93d714a50cb2c97435b408017dee224348b61bc86203ffd43a4f4e57b95f.sr.png)
![Moodle](../../translated_images/moodle.94eb93d714a50cb2.sr.png)
> Наставни план у Moodle учионици
![Canvas](../../translated_images/canvas.fbd605ff8e5b8aff567d398528ce113db304446b90b9cad55c654de3fdfcda34.sr.png)
![Canvas](../../translated_images/canvas.fbd605ff8e5b8aff.sr.png)
> Наставни план у Canvas-у
### Коришћење репозиторијума директно (без Classroom-а)

Loading…
Cancel
Save