diff --git a/translated_images/1.b6da8c1394b07491.bg.png b/translated_images/1.b6da8c1394b07491.bg.png new file mode 100644 index 000000000..68f6077ea Binary files /dev/null and b/translated_images/1.b6da8c1394b07491.bg.png differ diff --git a/translated_images/1.b6da8c1394b07491.cs.png b/translated_images/1.b6da8c1394b07491.cs.png new file mode 100644 index 000000000..ae00c493c Binary files /dev/null and b/translated_images/1.b6da8c1394b07491.cs.png differ diff --git a/translated_images/1.b6da8c1394b07491.hu.png b/translated_images/1.b6da8c1394b07491.hu.png new file mode 100644 index 000000000..ae5b7f7fc Binary files /dev/null and b/translated_images/1.b6da8c1394b07491.hu.png differ diff --git a/translated_images/1.b6da8c1394b07491.ro.png b/translated_images/1.b6da8c1394b07491.ro.png new file mode 100644 index 000000000..879a982fd Binary files /dev/null and b/translated_images/1.b6da8c1394b07491.ro.png differ diff --git a/translated_images/1.b6da8c1394b07491.sk.png b/translated_images/1.b6da8c1394b07491.sk.png new file mode 100644 index 000000000..64a178067 Binary files /dev/null and b/translated_images/1.b6da8c1394b07491.sk.png differ diff --git a/translated_images/1.b6da8c1394b07491.sr.png b/translated_images/1.b6da8c1394b07491.sr.png new file mode 100644 index 000000000..8003016cd Binary files /dev/null and b/translated_images/1.b6da8c1394b07491.sr.png differ diff --git a/translated_images/1.cc07a5cbe114ad1d.bg.png b/translated_images/1.cc07a5cbe114ad1d.bg.png new file mode 100644 index 000000000..d32e28f20 Binary files /dev/null and b/translated_images/1.cc07a5cbe114ad1d.bg.png differ diff --git a/translated_images/1.cc07a5cbe114ad1d.cs.png b/translated_images/1.cc07a5cbe114ad1d.cs.png new file mode 100644 index 000000000..2302da2d0 Binary files /dev/null and b/translated_images/1.cc07a5cbe114ad1d.cs.png differ diff --git a/translated_images/1.cc07a5cbe114ad1d.hu.png b/translated_images/1.cc07a5cbe114ad1d.hu.png new file mode 100644 index 000000000..35c218b87 Binary files /dev/null and b/translated_images/1.cc07a5cbe114ad1d.hu.png differ diff --git a/translated_images/1.cc07a5cbe114ad1d.ro.png b/translated_images/1.cc07a5cbe114ad1d.ro.png new file mode 100644 index 000000000..fe829eaf4 Binary files /dev/null and b/translated_images/1.cc07a5cbe114ad1d.ro.png differ diff --git a/translated_images/1.cc07a5cbe114ad1d.sk.png b/translated_images/1.cc07a5cbe114ad1d.sk.png new file mode 100644 index 000000000..b310f3790 Binary files /dev/null and b/translated_images/1.cc07a5cbe114ad1d.sk.png differ diff --git a/translated_images/1.cc07a5cbe114ad1d.sr.png b/translated_images/1.cc07a5cbe114ad1d.sr.png new file mode 100644 index 000000000..bccf5da50 Binary files /dev/null and b/translated_images/1.cc07a5cbe114ad1d.sr.png differ diff --git a/translated_images/2.1dae52ff08042246.bg.png b/translated_images/2.1dae52ff08042246.bg.png new file mode 100644 index 000000000..1fcfb3f37 Binary files /dev/null and b/translated_images/2.1dae52ff08042246.bg.png differ diff --git a/translated_images/2.1dae52ff08042246.cs.png b/translated_images/2.1dae52ff08042246.cs.png new file mode 100644 index 000000000..a5c13c161 Binary files /dev/null and b/translated_images/2.1dae52ff08042246.cs.png differ diff --git a/translated_images/2.1dae52ff08042246.hu.png b/translated_images/2.1dae52ff08042246.hu.png new file mode 100644 index 000000000..5dda60186 Binary files /dev/null and b/translated_images/2.1dae52ff08042246.hu.png differ diff --git a/translated_images/2.1dae52ff08042246.ro.png b/translated_images/2.1dae52ff08042246.ro.png new file mode 100644 index 000000000..b3f2bb68c Binary files /dev/null and b/translated_images/2.1dae52ff08042246.ro.png differ diff --git a/translated_images/2.1dae52ff08042246.sk.png b/translated_images/2.1dae52ff08042246.sk.png new file mode 100644 index 000000000..a23529fb2 Binary files /dev/null and b/translated_images/2.1dae52ff08042246.sk.png differ diff --git a/translated_images/2.1dae52ff08042246.sr.png b/translated_images/2.1dae52ff08042246.sr.png new file mode 100644 index 000000000..2fe7ee3c4 Binary files /dev/null and b/translated_images/2.1dae52ff08042246.sr.png differ diff --git a/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.bg.png b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.bg.png new file mode 100644 index 000000000..c902d7808 Binary files /dev/null and b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.bg.png differ diff --git a/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.cs.png b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.cs.png new file mode 100644 index 000000000..3e2599c73 Binary files /dev/null and b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.cs.png differ diff --git a/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.hu.png b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.hu.png new file mode 100644 index 000000000..f8919d653 Binary files /dev/null and b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.hu.png differ diff --git a/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.ro.png b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.ro.png new file mode 100644 index 000000000..72fe8c70c Binary files /dev/null and b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.ro.png differ diff --git a/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.sk.png b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.sk.png new file mode 100644 index 000000000..052d76399 Binary files /dev/null and b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.sk.png differ diff --git a/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.sr.png b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.sr.png new file mode 100644 index 000000000..564e3baf5 Binary files /dev/null and b/translated_images/after-codeswing-extension-pb.0ebddddcf73b5509.sr.png differ diff --git a/translated_images/background.148a8d43afde5730.bg.png b/translated_images/background.148a8d43afde5730.bg.png new file mode 100644 index 000000000..bc956aea5 Binary files /dev/null and b/translated_images/background.148a8d43afde5730.bg.png differ diff --git a/translated_images/background.148a8d43afde5730.cs.png b/translated_images/background.148a8d43afde5730.cs.png new file mode 100644 index 000000000..de0364f5f Binary files /dev/null and b/translated_images/background.148a8d43afde5730.cs.png differ diff --git a/translated_images/background.148a8d43afde5730.hu.png b/translated_images/background.148a8d43afde5730.hu.png new file mode 100644 index 000000000..8608f23ad Binary files /dev/null and b/translated_images/background.148a8d43afde5730.hu.png differ diff --git a/translated_images/background.148a8d43afde5730.ro.png b/translated_images/background.148a8d43afde5730.ro.png new file mode 100644 index 000000000..737b07a5d Binary files /dev/null and b/translated_images/background.148a8d43afde5730.ro.png differ diff --git a/translated_images/background.148a8d43afde5730.sk.png b/translated_images/background.148a8d43afde5730.sk.png new file mode 100644 index 000000000..5d3bc5dfd Binary files /dev/null and b/translated_images/background.148a8d43afde5730.sk.png differ diff --git a/translated_images/background.148a8d43afde5730.sr.png b/translated_images/background.148a8d43afde5730.sr.png new file mode 100644 index 000000000..efc1894a0 Binary files /dev/null and b/translated_images/background.148a8d43afde5730.sr.png differ diff --git a/translated_images/backgroundColor.e19c3c60768150c8.bg.png b/translated_images/backgroundColor.e19c3c60768150c8.bg.png new file mode 100644 index 000000000..3bd93a532 Binary files /dev/null and b/translated_images/backgroundColor.e19c3c60768150c8.bg.png differ diff --git a/translated_images/backgroundColor.e19c3c60768150c8.cs.png b/translated_images/backgroundColor.e19c3c60768150c8.cs.png new file mode 100644 index 000000000..3bd93a532 Binary files /dev/null and b/translated_images/backgroundColor.e19c3c60768150c8.cs.png differ diff --git a/translated_images/backgroundColor.e19c3c60768150c8.hu.png b/translated_images/backgroundColor.e19c3c60768150c8.hu.png new file mode 100644 index 000000000..3bd93a532 Binary files /dev/null and b/translated_images/backgroundColor.e19c3c60768150c8.hu.png differ diff --git a/translated_images/backgroundColor.e19c3c60768150c8.ro.png b/translated_images/backgroundColor.e19c3c60768150c8.ro.png new file mode 100644 index 000000000..3bd93a532 Binary files /dev/null and b/translated_images/backgroundColor.e19c3c60768150c8.ro.png differ diff --git a/translated_images/backgroundColor.e19c3c60768150c8.sk.png b/translated_images/backgroundColor.e19c3c60768150c8.sk.png new file mode 100644 index 000000000..3bd93a532 Binary files /dev/null and b/translated_images/backgroundColor.e19c3c60768150c8.sk.png differ diff --git a/translated_images/backgroundColor.e19c3c60768150c8.sr.png b/translated_images/backgroundColor.e19c3c60768150c8.sr.png new file mode 100644 index 000000000..3bd93a532 Binary files /dev/null and b/translated_images/backgroundColor.e19c3c60768150c8.sr.png differ diff --git a/translated_images/browser-console.efaf0b51aaaf6778.bg.png b/translated_images/browser-console.efaf0b51aaaf6778.bg.png new file mode 100644 index 000000000..14141e512 Binary files /dev/null and b/translated_images/browser-console.efaf0b51aaaf6778.bg.png differ diff --git a/translated_images/browser-console.efaf0b51aaaf6778.cs.png b/translated_images/browser-console.efaf0b51aaaf6778.cs.png new file mode 100644 index 000000000..9f418f95d Binary files /dev/null and b/translated_images/browser-console.efaf0b51aaaf6778.cs.png differ diff --git a/translated_images/browser-console.efaf0b51aaaf6778.hu.png b/translated_images/browser-console.efaf0b51aaaf6778.hu.png new file mode 100644 index 000000000..be28686f1 Binary files /dev/null and b/translated_images/browser-console.efaf0b51aaaf6778.hu.png differ diff --git a/translated_images/browser-console.efaf0b51aaaf6778.ro.png b/translated_images/browser-console.efaf0b51aaaf6778.ro.png new file mode 100644 index 000000000..667519a9e Binary files /dev/null and b/translated_images/browser-console.efaf0b51aaaf6778.ro.png differ diff --git a/translated_images/browser-console.efaf0b51aaaf6778.sk.png b/translated_images/browser-console.efaf0b51aaaf6778.sk.png new file mode 100644 index 000000000..8d8414343 Binary files /dev/null and b/translated_images/browser-console.efaf0b51aaaf6778.sk.png differ diff --git a/translated_images/browser-console.efaf0b51aaaf6778.sr.png b/translated_images/browser-console.efaf0b51aaaf6778.sr.png new file mode 100644 index 000000000..ab012c4d8 Binary files /dev/null and b/translated_images/browser-console.efaf0b51aaaf6778.sr.png differ diff --git a/translated_images/browser.60317c9be8b7f84a.bg.jpg b/translated_images/browser.60317c9be8b7f84a.bg.jpg new file mode 100644 index 000000000..29aef5c35 Binary files /dev/null and b/translated_images/browser.60317c9be8b7f84a.bg.jpg differ diff --git a/translated_images/browser.60317c9be8b7f84a.cs.jpg b/translated_images/browser.60317c9be8b7f84a.cs.jpg new file mode 100644 index 000000000..74bccd331 Binary files /dev/null and b/translated_images/browser.60317c9be8b7f84a.cs.jpg differ diff --git a/translated_images/browser.60317c9be8b7f84a.hu.jpg b/translated_images/browser.60317c9be8b7f84a.hu.jpg new file mode 100644 index 000000000..984cf9bd3 Binary files /dev/null and b/translated_images/browser.60317c9be8b7f84a.hu.jpg differ diff --git a/translated_images/browser.60317c9be8b7f84a.ro.jpg b/translated_images/browser.60317c9be8b7f84a.ro.jpg new file mode 100644 index 000000000..613eb2ab5 Binary files /dev/null and b/translated_images/browser.60317c9be8b7f84a.ro.jpg differ diff --git a/translated_images/browser.60317c9be8b7f84a.sk.jpg b/translated_images/browser.60317c9be8b7f84a.sk.jpg new file mode 100644 index 000000000..9368e3f93 Binary files /dev/null and b/translated_images/browser.60317c9be8b7f84a.sk.jpg differ diff --git a/translated_images/browser.60317c9be8b7f84a.sr.jpg b/translated_images/browser.60317c9be8b7f84a.sr.jpg new file mode 100644 index 000000000..342b05dd0 Binary files /dev/null and b/translated_images/browser.60317c9be8b7f84a.sr.jpg differ diff --git a/translated_images/canvas.fbd605ff8e5b8aff.bg.png b/translated_images/canvas.fbd605ff8e5b8aff.bg.png new file mode 100644 index 000000000..267273d0f Binary files /dev/null and b/translated_images/canvas.fbd605ff8e5b8aff.bg.png differ diff --git a/translated_images/canvas.fbd605ff8e5b8aff.cs.png b/translated_images/canvas.fbd605ff8e5b8aff.cs.png new file mode 100644 index 000000000..9de65f573 Binary files /dev/null and b/translated_images/canvas.fbd605ff8e5b8aff.cs.png differ diff --git a/translated_images/canvas.fbd605ff8e5b8aff.hu.png b/translated_images/canvas.fbd605ff8e5b8aff.hu.png new file mode 100644 index 000000000..dd0fab048 Binary files /dev/null and b/translated_images/canvas.fbd605ff8e5b8aff.hu.png differ diff --git a/translated_images/canvas.fbd605ff8e5b8aff.ro.png b/translated_images/canvas.fbd605ff8e5b8aff.ro.png new file mode 100644 index 000000000..0f38e9345 Binary files /dev/null and b/translated_images/canvas.fbd605ff8e5b8aff.ro.png differ diff --git a/translated_images/canvas.fbd605ff8e5b8aff.sk.png b/translated_images/canvas.fbd605ff8e5b8aff.sk.png new file mode 100644 index 000000000..f9992b79b Binary files /dev/null and b/translated_images/canvas.fbd605ff8e5b8aff.sk.png differ diff --git a/translated_images/canvas.fbd605ff8e5b8aff.sr.png b/translated_images/canvas.fbd605ff8e5b8aff.sr.png new file mode 100644 index 000000000..48a4b52eb Binary files /dev/null and b/translated_images/canvas.fbd605ff8e5b8aff.sr.png differ diff --git a/translated_images/canvas_grid.5f209da785ded492.bg.png b/translated_images/canvas_grid.5f209da785ded492.bg.png new file mode 100644 index 000000000..ad358fbbd Binary files /dev/null and b/translated_images/canvas_grid.5f209da785ded492.bg.png differ diff --git a/translated_images/canvas_grid.5f209da785ded492.cs.png b/translated_images/canvas_grid.5f209da785ded492.cs.png new file mode 100644 index 000000000..c0e65c344 Binary files /dev/null and b/translated_images/canvas_grid.5f209da785ded492.cs.png differ diff --git a/translated_images/canvas_grid.5f209da785ded492.hu.png b/translated_images/canvas_grid.5f209da785ded492.hu.png new file mode 100644 index 000000000..b60045992 Binary files /dev/null and b/translated_images/canvas_grid.5f209da785ded492.hu.png differ diff --git a/translated_images/canvas_grid.5f209da785ded492.ro.png b/translated_images/canvas_grid.5f209da785ded492.ro.png new file mode 100644 index 000000000..b9c03829c Binary files /dev/null and b/translated_images/canvas_grid.5f209da785ded492.ro.png differ diff --git a/translated_images/canvas_grid.5f209da785ded492.sk.png b/translated_images/canvas_grid.5f209da785ded492.sk.png new file mode 100644 index 000000000..4ffb2f81c Binary files /dev/null and b/translated_images/canvas_grid.5f209da785ded492.sk.png differ diff --git a/translated_images/canvas_grid.5f209da785ded492.sr.png b/translated_images/canvas_grid.5f209da785ded492.sr.png new file mode 100644 index 000000000..a0a0d0225 Binary files /dev/null and b/translated_images/canvas_grid.5f209da785ded492.sr.png differ diff --git a/translated_images/character.5c0dd8e067ffd693.bg.png b/translated_images/character.5c0dd8e067ffd693.bg.png new file mode 100644 index 000000000..52c4260fb Binary files /dev/null and b/translated_images/character.5c0dd8e067ffd693.bg.png differ diff --git a/translated_images/character.5c0dd8e067ffd693.cs.png b/translated_images/character.5c0dd8e067ffd693.cs.png new file mode 100644 index 000000000..0701afb05 Binary files /dev/null and b/translated_images/character.5c0dd8e067ffd693.cs.png differ diff --git a/translated_images/character.5c0dd8e067ffd693.hu.png b/translated_images/character.5c0dd8e067ffd693.hu.png new file mode 100644 index 000000000..f81251e68 Binary files /dev/null and b/translated_images/character.5c0dd8e067ffd693.hu.png differ diff --git a/translated_images/character.5c0dd8e067ffd693.ro.png b/translated_images/character.5c0dd8e067ffd693.ro.png new file mode 100644 index 000000000..f2aa19001 Binary files /dev/null and b/translated_images/character.5c0dd8e067ffd693.ro.png differ diff --git a/translated_images/character.5c0dd8e067ffd693.sk.png b/translated_images/character.5c0dd8e067ffd693.sk.png new file mode 100644 index 000000000..285a189d2 Binary files /dev/null and b/translated_images/character.5c0dd8e067ffd693.sk.png differ diff --git a/translated_images/character.5c0dd8e067ffd693.sr.png b/translated_images/character.5c0dd8e067ffd693.sr.png new file mode 100644 index 000000000..1161aba25 Binary files /dev/null and b/translated_images/character.5c0dd8e067ffd693.sr.png differ diff --git a/translated_images/click-register.e89a30bf0d4bc9ca.bg.png b/translated_images/click-register.e89a30bf0d4bc9ca.bg.png new file mode 100644 index 000000000..ccc65305d Binary files /dev/null and b/translated_images/click-register.e89a30bf0d4bc9ca.bg.png differ diff --git a/translated_images/click-register.e89a30bf0d4bc9ca.cs.png b/translated_images/click-register.e89a30bf0d4bc9ca.cs.png new file mode 100644 index 000000000..ccc65305d Binary files /dev/null and b/translated_images/click-register.e89a30bf0d4bc9ca.cs.png differ diff --git a/translated_images/click-register.e89a30bf0d4bc9ca.hu.png b/translated_images/click-register.e89a30bf0d4bc9ca.hu.png new file mode 100644 index 000000000..ccc65305d Binary files /dev/null and b/translated_images/click-register.e89a30bf0d4bc9ca.hu.png differ diff --git a/translated_images/click-register.e89a30bf0d4bc9ca.ro.png b/translated_images/click-register.e89a30bf0d4bc9ca.ro.png new file mode 100644 index 000000000..ccc65305d Binary files /dev/null and b/translated_images/click-register.e89a30bf0d4bc9ca.ro.png differ diff --git a/translated_images/click-register.e89a30bf0d4bc9ca.sk.png b/translated_images/click-register.e89a30bf0d4bc9ca.sk.png new file mode 100644 index 000000000..ccc65305d Binary files /dev/null and b/translated_images/click-register.e89a30bf0d4bc9ca.sk.png differ diff --git a/translated_images/click-register.e89a30bf0d4bc9ca.sr.png b/translated_images/click-register.e89a30bf0d4bc9ca.sr.png new file mode 100644 index 000000000..ccc65305d Binary files /dev/null and b/translated_images/click-register.e89a30bf0d4bc9ca.sr.png differ diff --git a/translated_images/clone_repo.5085c48d666ead57.bg.png b/translated_images/clone_repo.5085c48d666ead57.bg.png new file mode 100644 index 000000000..d3fe7cffe Binary files /dev/null and b/translated_images/clone_repo.5085c48d666ead57.bg.png differ diff --git a/translated_images/clone_repo.5085c48d666ead57.cs.png b/translated_images/clone_repo.5085c48d666ead57.cs.png new file mode 100644 index 000000000..8771467f7 Binary files /dev/null and b/translated_images/clone_repo.5085c48d666ead57.cs.png differ diff --git a/translated_images/clone_repo.5085c48d666ead57.hu.png b/translated_images/clone_repo.5085c48d666ead57.hu.png new file mode 100644 index 000000000..2079006bd Binary files /dev/null and b/translated_images/clone_repo.5085c48d666ead57.hu.png differ diff --git a/translated_images/clone_repo.5085c48d666ead57.ro.png b/translated_images/clone_repo.5085c48d666ead57.ro.png new file mode 100644 index 000000000..9f2f67a89 Binary files /dev/null and b/translated_images/clone_repo.5085c48d666ead57.ro.png differ diff --git a/translated_images/clone_repo.5085c48d666ead57.sk.png b/translated_images/clone_repo.5085c48d666ead57.sk.png new file mode 100644 index 000000000..ff78e3ee4 Binary files /dev/null and b/translated_images/clone_repo.5085c48d666ead57.sk.png differ diff --git a/translated_images/clone_repo.5085c48d666ead57.sr.png b/translated_images/clone_repo.5085c48d666ead57.sr.png new file mode 100644 index 000000000..5eac49078 Binary files /dev/null and b/translated_images/clone_repo.5085c48d666ead57.sr.png differ diff --git a/translated_images/clone_repo.6a202fb230ab6bdd.bg.png b/translated_images/clone_repo.6a202fb230ab6bdd.bg.png new file mode 100644 index 000000000..083362766 Binary files /dev/null and b/translated_images/clone_repo.6a202fb230ab6bdd.bg.png differ diff --git a/translated_images/clone_repo.6a202fb230ab6bdd.cs.png b/translated_images/clone_repo.6a202fb230ab6bdd.cs.png new file mode 100644 index 000000000..c2e254cc3 Binary files /dev/null and b/translated_images/clone_repo.6a202fb230ab6bdd.cs.png differ diff --git a/translated_images/clone_repo.6a202fb230ab6bdd.hu.png b/translated_images/clone_repo.6a202fb230ab6bdd.hu.png new file mode 100644 index 000000000..ef6bd19a9 Binary files /dev/null and b/translated_images/clone_repo.6a202fb230ab6bdd.hu.png differ diff --git a/translated_images/clone_repo.6a202fb230ab6bdd.ro.png b/translated_images/clone_repo.6a202fb230ab6bdd.ro.png new file mode 100644 index 000000000..0770b94be Binary files /dev/null and b/translated_images/clone_repo.6a202fb230ab6bdd.ro.png differ diff --git a/translated_images/clone_repo.6a202fb230ab6bdd.sk.png b/translated_images/clone_repo.6a202fb230ab6bdd.sk.png new file mode 100644 index 000000000..61a4bc2e9 Binary files /dev/null and b/translated_images/clone_repo.6a202fb230ab6bdd.sk.png differ diff --git a/translated_images/clone_repo.6a202fb230ab6bdd.sr.png b/translated_images/clone_repo.6a202fb230ab6bdd.sr.png new file mode 100644 index 000000000..315587bc9 Binary files /dev/null and b/translated_images/clone_repo.6a202fb230ab6bdd.sr.png differ diff --git a/translations/sr/6-space-game/2-drawing-to-canvas/README.md b/translations/sr/6-space-game/2-drawing-to-canvas/README.md index e933a6ecf..57e618041 100644 --- a/translations/sr/6-space-game/2-drawing-to-canvas/README.md +++ b/translations/sr/6-space-game/2-drawing-to-canvas/README.md @@ -1,31 +1,76 @@ -# Направите свемирску игру, део 2: Цртање хероја и чудовишта на платну - -Canvas API је једна од најмоћнијих функција веб развоја за креирање динамичке, интерактивне графике директно у вашем претраживачу. У овој лекцији, трансформисаћемо празан HTML `` елемент у свет игре испуњен херојима и чудовиштима. Замислите платно као вашу дигиталну таблу за цртање где код постаје визуелан. - -Надовезујемо се на оно што сте научили у претходној лекцији, а сада ћемо се упустити у визуелне аспекте. Научићете како да учитате и прикажете спрајтове игре, прецизно позиционирате елементе и креирате визуелну основу за вашу свемирску игру. Ово премошћује јаз између статичних веб страница и динамичких, интерактивних искустава. - -На крају ове лекције, имаћете комплетну сцену игре са вашим херојским бродом који је правилно позициониран и формацијама непријатеља спремним за битку. Разумећете како модерне игре рендерују графику у претраживачима и стекнућете вештине за креирање сопствених интерактивних визуелних искустава. Хајде да истражимо графику на платну и оживимо вашу свемирску игру! - -## Квиз пре предавања +# Направи просторну игру део 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 графику и оживимо вашу свемирску игру! + +```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 -Шта је тачно `` елемент? То је HTML5 решење за креирање динамичке графике и анимација у веб претраживачима. За разлику од обичних слика или видео записа који су статични, платно вам даје контролу над пикселима за све што се појављује на екрану. Ово га чини савршеним за игре, визуализацију података и интерактивну уметност. Замислите га као програмску површину за цртање где JavaScript постаје ваша четкица. +Шта је тачно овај `` елемент? То је 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 је једна од најмоћнијих функција веб ``` -**Шта овај код ради:** -- **Поставља** `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). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода. \ No newline at end of file + +**Изјава о одрицању одговорности**: +Овај документ је преведен помоћу АИ сервиса за превођење [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде што прецизнији, имајте у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати званичним и ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било какве неспоразуме или погрешне интерпретације настале употребом овог превода. + \ No newline at end of file diff --git a/translations/sr/6-space-game/3-moving-elements-around/README.md b/translations/sr/6-space-game/3-moving-elements-around/README.md index 0c450669f..0e313b73d 100644 --- a/translations/sr/6-space-game/3-moving-elements-around/README.md +++ b/translations/sr/6-space-game/3-moving-elements-around/README.md @@ -1,103 +1,186 @@ -# Изградња свемирске игре, део 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). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода. \ No newline at end of file + +**Ограничење одговорности**: +Овај документ је преведен уз помоћ АИ сервиса за превођење [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде што прецизнији, молимо имајте у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешна тумачења која могу произаћи из употребе овог превода. + \ No newline at end of file diff --git a/translations/sr/6-space-game/4-collision-detection/README.md b/translations/sr/6-space-game/4-collision-detection/README.md index 880e2a9ae..aec25a678 100644 --- a/translations/sr/6-space-game/4-collision-detection/README.md +++ b/translations/sr/6-space-game/4-collision-detection/README.md @@ -1,36 +1,103 @@ -# Направите свемирску игру, део 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). Иако се трудимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на изворном језику треба сматрати меродавним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода. \ No newline at end of file + +**Ограничење одговорности**: +Овај документ је преведен помоћу АИ преводилачке услуге [Co-op Translator](https://github.com/Azure/co-op-translator). Иако тежимо прецизности, имајте у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на свом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешна тумачења настала коришћењем овог превода. + \ No newline at end of file diff --git a/translations/sr/6-space-game/5-keeping-score/README.md b/translations/sr/6-space-game/5-keeping-score/README.md index 998b6d96d..dcce6c50c 100644 --- a/translations/sr/6-space-game/5-keeping-score/README.md +++ b/translations/sr/6-space-game/5-keeping-score/README.md @@ -1,25 +1,89 @@ -# Направите свемирску игру, део 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 месец) + Професионални развој: Сарадња у тиму + : Документација дизајна + : Истраживање играча + : Оптимизација платформе +``` +### 🛠️ Сажетак вашег сета алата за дизајн игара + +Након завршетка овог часа, овладали сте: +- **Психологија играча**: Разумевање мотивације, ризика/нагaде и петљи ангажовања +- **Визуелна комуникација**: Ефикасан 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](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода. \ No newline at end of file +Овај документ је преведен коришћењем AI преводилачке услуге [Co-op Translator](https://github.com/Azure/co-op-translator). Иако тежимо тачности, молимо имајте у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људског преводиоца. Нисмо одговорни за било каква неспоразума или погрешне тумачења која могу произићи из употребе овог превода. + \ No newline at end of file diff --git a/translations/sr/6-space-game/6-end-condition/README.md b/translations/sr/6-space-game/6-end-condition/README.md index cf277fbee..c715870b7 100644 --- a/translations/sr/6-space-game/6-end-condition/README.md +++ b/translations/sr/6-space-game/6-end-condition/README.md @@ -1,59 +1,163 @@ -# Изградња свемирске игре, део 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() { ``` **Ево шта се дешава у позадини:** -- **Проверава** да ли је наш херој остао без живота (ау!) -- **Броји** колико непријатеља је још увек живо +- **Проверaва** да ли је наш јунак остао без живота (ау!) +- **Броји** колико непријатеља још увек живи и напада - **Враћа** `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](https://github.com/Azure/co-op-translator). Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу произаћи из коришћења овог превода. \ No newline at end of file +Овај документ је преведен помоћу AI сервиса за превођење [Co-op Translator](https://github.com/Azure/co-op-translator). Иако се трудимо да превод буде прецизан, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом матерњем језику треба сматрати званичним извором. За кључне информације препоруучује се професионални превод од стране стручног лојалног преводиоца. Нисмо одговорни за било каква неразумевања или погрешне тумачења која проистекну из употребе овог превода. + \ No newline at end of file diff --git a/translations/sr/7-bank-project/1-template-route/README.md b/translations/sr/7-bank-project/1-template-route/README.md index 305cee63a..017b329a8 100644 --- a/translations/sr/7-bank-project/1-template-route/README.md +++ b/translations/sr/7-bank-project/1-template-route/README.md @@ -1,51 +1,96 @@ -# Изградња апликације за банкарство, део 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 @@ -61,16 +106,16 @@ CO_OP_TRANSLATOR_METADATA: ``` -**Ево шта овај основни шаблон пружа:** -- **Успоставља** структуру HTML5 документа са правилном декларацијом DOCTYPE-а -- **Конфигурише** кодирање карактера као UTF-8 за подршку међународног текста -- **Омогућава** одзивни дизајн са мета тагом за приказ за мобилну компатибилност -- **Поставља** описни наслов који се појављује на картици прегледача -- **Креира** чисту секцију тела где ћемо изградити нашу апликацију +**Ово што овај бојлерплејт обезбеђује:** +- **Успоставља** HTML5 структуру документа са правилном DOCTYPE декларацијом +- **Конфигурише** енкодирање карактера као UTF-8 за међународну подршку текста +- **Омогућава** респонзивни дизајн преко viewport meta тега за мобилне уређаје +- **Поставља** описни наслов који се појављује на табу прегледача +- **Креира** чисто тело странице где ћемо градити нашу апликацију > 📁 **Преглед структуре пројекта** > -> **На крају ове лекције, ваш пројекат ће садржати:** +> **До краја ове лекције, ваш пројекат ће садржати:** > ``` > bank/ > ├── index.html @@ -78,43 +123,60 @@ CO_OP_TRANSLATOR_METADATA: > └── style.css > ``` > -> **Одговорности датотека:** +> **Одговорности фајлова:** > - **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) користећи елемент `