Bladeren bron

Added Polish translations for manuals regarding input handling and script writing. (#364)

Pawel 1 jaar geleden
bovenliggende
commit
fd48b3d921

+ 2 - 1
docs/pl/manuals/debugging-game-logic.md

@@ -35,7 +35,7 @@ Wizualne komunikaty debugowania dodają dane do potoku (pipeline) renderowania i
 * `"draw_debug_text"` jest to to samo co `"draw_text"`, ale jest renderowany w kolorze niestandardowym.
 Zauważ, że prawdopodobnie chcesz aktualizować te dane co klatkę, więc przesyłanie wiadomości do skryptu renderowania w funkcji `update()` jest dobrym pomysłem.
 
-## Uruchamianie debugger
+## Uruchamianie debuggera
 
 Aby uruchomić wbudowany debugger wraz z grą klkinij menu <kbd>Debug ▸ Run with Debugger</kbd> lub wybierz <kbd>Debug ▸ Attach Debugger</kbd>, aby dołączyć debugger do aktualnie uruchomionej gry.
 
@@ -79,6 +79,7 @@ Step Out
 : ![step out](images/debugging/step_out.svg){width=60px .left}
   Kontynuuj działanie do momentu zakończenia bieżącej funkcji. Jeśli wykonanie jest w funkcji, naciśnięcie przycisku "Step Out" spowoduje kontynuowanie działania do momentu zakończenia funkcji.
 
+
 Ustawianie i usuwanie punktów przerwania (breakpoints)
 : Możesz ustawić dowolną liczbę punktów przerwania w kodzie Lua. Gdy gra działa z podłączonym debugerem, zatrzyma się na następnym punkcie przerwania i poczeka na dalsze interakcje z tobą.
 

+ 247 - 0
docs/pl/manuals/input-gamepads.md

@@ -0,0 +1,247 @@
+---
+title: Wejścia z gamepadów i innych kontrolerów w Defoldzie.
+brief: Ta instrukcja wyjaśnia jak obsługiwać gamepady.
+---
+
+::: sidenote
+Zalecamy zapoznanie się z ogólnym sposobem działania wejścia w Defoldzie, jak przechwytuje się wejście, jak wiążę z akcjami oraz w jakiej kolejności skrypty odbierają dane wejściowe. Dowiedz się więcej na temat systemu wejść w [ogólnej instrukcji na temat Wejść](/manuals/input).
+:::
+
+# Gamepady
+
+Gamepady w Defoldzie pozwalają na przypisanie standardowego wejścia z gamepada do funkcji gry. Wejście z gamepadów obejmuje przypisanie akcji do:
+
+- Lewej i prawej analogowej gałki (kierunek i kliknięcia)
+- Przycisków. Przyciski po prawej stronie zazwyczaj odpowiadają przyciskom "A", "B", "X" i "Y" na kontrolerze Xbox i Nintendo Switch oraz przyciskom "kwadrat", "okrąg", "trójkąt" i "krzyżyk" na kontrolerze PlayStation.
+- Lewego i prawego spustu (triggers)
+- Lewego i prawego przycisku na ramieniu (shoulder buttons)
+- Przycisków Start, Wstecz (Back) i Przewodnika (Guide)
+
+![](images/input/gamepad_bindings.png)
+
+::: important
+Poniższe przykłady używają akcji pokazanych na obrazie powyżej. Podobnie jak w przypadku wszystkich innych akcji, możesz dowolnie nazywać akcje wejściowe.
+:::
+
+## Przyciski
+
+Przyciski cyfrowe generują zdarzenia naciśnięcia, zwolnienia i powtórzenia. Oto przykład wykrywania wejścia z przycisku cyfrowego (czy naciśnięto lub zwolniono):
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("gamepad_lpad_left") then
+        if action.pressed then
+            -- start ruchu w lewo
+        elseif action.released then
+            -- stop ruchu w lewo
+        end
+    end
+end
+```
+
+## Analogowe gałki
+
+Analogowe gałki generują ciągłe zdarzenia wejścia, gdy drążek jest przesuwany poza martwą strefę (ang. dead zone) zdefiniowaną w pliku ustawień gamepada (patrz poniżej). Oto przykład wykrywania wejścia z analogowej gałki:
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("gamepad_lstick_down") then
+        -- lewa gałka ruszona w dół
+        print(action.value) -- wartość między 0.0 a -1.0
+    end
+end
+```
+
+Analogowe drążki generują również zdarzenia naciśnięcia i zwolnienia, gdy są przesuwane w kierunku kardynalnym (ang. cardinal directions) powyżej pewnej wartości progowej. Dzięki temu można również używać analogowego drążka jako cyfrowego wejścia kierunkowego:
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("gamepad_lstick_down") and action.pressed then
+        -- lewa gałka ruszona na sam dół
+    end
+end
+```
+
+## Wiele gamepadów
+
+Defold obsługuje wiele gamepadów poprzez system operacyjny urządzenia, akcje ustawiają pole `gamepad` w tabeli akcji, aby wskazać numer gamepada, z którego pochodzi dane wejście:
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("gamepad_start") then
+        if action.gamepad == 0 then
+          -- gamepad 0 chce dolaczyc do gry
+        end
+    end
+end
+```
+
+## Podłączenie i rozłączenie
+
+Przypisania wejścia od gamepada (ang. gamepad input bindings) dostarczają również dwa osobne przypisania o nazwach `Connected` i `Disconnected`, aby wykrywać, kiedy gamepad jest podłączony (nawet te, które były podłączone od początku) lub odłączony.
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("gamepad_connected") then
+        if action.gamepad == 0 then
+          -- gamepad 0 został podłączony
+        end
+    elseif action_id == hash("gamepad_dicconnected") then
+        if action.gamepad == 0 then
+          -- gamepad 0 został odłączony
+        end
+    end
+end
+```
+
+## Raw gamepady
+
+(Od wersji Defold 1.2.183)
+
+Przypisania wejścia od gamepada dostarczają również osobne przypisanie o nazwie `Raw`, które umożliwia pobranie surowych (bez zastosowanej martwej strefy) danych przycisków, osi i przycisków "hat" dowolnie podłączonego gamepada.
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("raw") then
+        pprint(action.gamepad_buttons)
+        pprint(action.gamepad_axis)
+        pprint(action.gamepad_hats)
+    end
+end
+```
+
+## Plik ustawień gamepadów
+
+Konfiguracja wejścia od gamepadów wykorzystuje osobny plik mapujący dla każdego rodzaju sprzętowego gamepada. Mapowania gamepadów dla konkretnych typów gamepadów sprzętowych są ustawiane w pliku *gamepads*. Wraz z Defold dostarczany jest wbudowany plik gamepadów z ustawieniami dla popularnych gamepadów:
+
+![Gamepad settings](images/input/gamepads.png){srcset="images/input/[email protected] 2x"}
+
+Jeśli musisz utworzyć nowy plik z ustawieniami gamepadów, udostępniamy proste narzędzie do pomocy:
+
+[Kliknij aby pobrać paczkę gdc.zip](https://forum.defold.com/t/big-thread-of-gamepad-testing/56032).
+
+Narzędzie to zawiera pliki binarne dla systemów Windows, Linux i macOS. Uruchom je z wiersza poleceń:
+
+```sh
+./gdc
+```
+
+Narzędzie poprosi cię o naciśnięcie różnych przycisków na podłączonym kontrolerze. Następnie wygeneruje nowy plik z ustawieniami gamepadów z prawidłowymi mapowaniami dla twojego kontrolera. Zapisz nowy plik lub połącz go z istniejącym plikiem ustawień gamepadów, a następnie zaktualizuj ustawienie w *game.project*:
+
+![Gamepad settings](images/input/gamepad_setting.png){srcset="images/input/[email protected] 2x"}
+
+### Niezidentyfikowane gamepady
+
+(Od wersji Defold 1.2.186)
+
+Kiedy podłączony jest gamepad i nie ma mapowania dla tego gamepada, gamepad będzie generował tylko akcje "connected", "disconnected" i "raw". W takim przypadku musisz ręcznie zmapować dane surowe gamepada na akcje w twojej grze.
+
+(Od wersji Defold 1.4.8)
+
+Możesz sprawdzić, czy akcja wejścia dla gamepada jest od nieznanego gamepada, czy nie, odczytując wartość `gamepad_unknown` z akcji:
+
+```lua
+function on_input(self, action_id, action)
+    if action_is == hash("connected") then
+        if action.gamepad_unknown then
+            print("The connected gamepad is unidentified and will only generate raw input")
+        else
+            print("The connected gamepad is known and will generate input actions for buttons and sticks")
+        end
+    end
+end
+``` 
+
+## Gamepady w HTML5
+
+Gamepady są obsługiwane w projektach HTML5 i generują takie same zdarzenia wejścia jak na innych platformach. Obsługa gamepadów opiera się na [API Gamepad](https://www.w3.org/TR/gamepad/), które jest obsługiwane przez większość przeglądarek ([zobacz wykres obsługi](https://caniuse.com/?search=gamepad)). Jeśli przeglądarka nie obsługuje API Gamepad, Defold będzie ignorować dowolne wywołania związanego z Gamepadem w twoim projekcie. Możesz sprawdzić, czy przeglądarka obsługuje API Gamepad, sprawdzając, czy funkcja `getGamepads` istnieje w obiekcie `navigator`:
+
+```lua
+local function supports_gamepads()
+    return not html5 or (html5.run('typeof navigator.getGamepads === "function"') == "true")
+end
+
+if supports_gamepads() then
+    print("Platform supports gamepads")
+end
+```
+
+Jeśli twoja gra przeglądarkowa działa wewnątrz ramki `iframe`, upewnij się, że `iframe` ma dodane uprawnienie `gamepad`:
+
+```html
+<iframe allow="gamepad"></iframe>
+```
+
+### Standardowe gamepady
+
+(Od wersji Defold 1.4.1)
+
+Jeśli podłączony gamepad jest zidentyfikowany przez przeglądarkę jako standardowy, używać on będzie mapowania "Standard Gamepad" w [pliku konfiguracji gamepads](/manuals/input-gamepads/#gamepads-settings-file) (mapowanie standardowego gamepada jest dołączone do pliku `default.gamepads` w folderze `/builtins`). Standardowy gamepad ma zdefiniowane 16 przycisków i 2 analogowe gałki z układem podobnym do kontrolerów PlayStation lub Xbox. (zobacz [definicję W3C i układ przycisków](https://w3c.github.io/gamepad/#dfn-standard-gamepad)). Jeśli podłączony gamepad nie jest zidentyfikowany jako standardowy, Defold będzie próbował znaleźć mapowanie odpowiadające typowi kontrolwera w pliku konfiguracji gamepadów.
+
+## Gamepady na systemie Windows
+
+Na systemie Windows obecnie obsługiwane są tylko kontrolery XBox 360. Aby podłączyć kontroler Xbox 360 do komputera z systemem Windows, upewnij się, że jest on skonfigurowany poprawnie, zgodnie z [tym poradnikiem](http://www.wikihow.com/Use-Your-Xbox-360-Controller-for-Windows).
+
+## Gamepady na systemie Android
+
+(Od wersji Defold 1.2.183)
+
+Gamepady są obsługiwane w projektach na platformę Android i generują te same zdarzenia wejścia co na innych platformach. Obsługa gamepadów opiera się na [systemie wejść Androida dla zdarzeń klawiszy i ruchu]https://developer.android.com/training/game-controllers/controller-input).. Zdarzenia wejścia Androida zostaną przetłumaczone na zdarzenia gamepadów Defold, używając tego samego pliku gamepadów, jak opisano powyżej.
+
+Podczas dodawania dodatkowych przypisań gamepadów na platformie Android, możesz skorzystać z poniższych tabel przekształceń zdarzeń Androida na wartości pliku *gamepad*:
+
+| Klawisz - indeks przycisku  | Indeks | Wersja  |
+|-----------------------------|--------|---------|
+| AKEYCODE_BUTTON_A           | 0      | 1.2.183 |
+| AKEYCODE_BUTTON_B           | 1      | 1.2.183 |
+| AKEYCODE_BUTTON_C           | 2      | 1.2.183 |
+| AKEYCODE_BUTTON_X           | 3      | 1.2.183 |
+| AKEYCODE_BUTTON_L1          | 4      | 1.2.183 |
+| AKEYCODE_BUTTON_R1          | 5      | 1.2.183 |
+| AKEYCODE_BUTTON_Y           | 6      | 1.2.183 |
+| AKEYCODE_BUTTON_Z           | 7      | 1.2.183 |
+| AKEYCODE_BUTTON_L2          | 8      | 1.2.183 |
+| AKEYCODE_BUTTON_R2          | 9      | 1.2.183 |
+| AKEYCODE_DPAD_CENTER        | 10     | 1.2.183 |
+| AKEYCODE_DPAD_DOWN          | 11     | 1.2.183 |
+| AKEYCODE_DPAD_LEFT          | 12     | 1.2.183 |
+| AKEYCODE_DPAD_RIGHT         | 13     | 1.2.183 |
+| AKEYCODE_DPAD_UP            | 14     | 1.2.183 |
+| AKEYCODE_BUTTON_START       | 15     | 1.2.183 |
+| AKEYCODE_BUTTON_SELECT      | 16     | 1.2.183 |
+| AKEYCODE_BUTTON_THUMBL      | 17     | 1.2.183 |
+| AKEYCODE_BUTTON_THUMBR      | 18     | 1.2.183 |
+| AKEYCODE_BUTTON_MODE        | 19     | 1.2.183 |
+| AKEYCODE_BUTTON_1           | 20     | 1.2.186 |
+| AKEYCODE_BUTTON_2           | 21     | 1.2.186 |
+| AKEYCODE_BUTTON_3           | 22     | 1.2.186 |
+| AKEYCODE_BUTTON_4           | 23     | 1.2.186 |
+| AKEYCODE_BUTTON_5           | 24     | 1.2.186 |
+| AKEYCODE_BUTTON_6           | 25     | 1.2.186 |
+| AKEYCODE_BUTTON_7           | 26     | 1.2.186 |
+| AKEYCODE_BUTTON_8           | 27     | 1.2.186 |
+| AKEYCODE_BUTTON_9           | 28     | 1.2.186 |
+| AKEYCODE_BUTTON_10          | 29     | 1.2.186 |
+| AKEYCODE_BUTTON_11          | 30     | 1.2.186 |
+| AKEYCODE_BUTTON_12          | 31     | 1.2.186 |
+| AKEYCODE_BUTTON_13          | 32     | 1.2.186 |
+| AKEYCODE_BUTTON_14          | 33     | 1.2.186 |
+| AKEYCODE_BUTTON_15          | 34     | 1.2.186 |
+| AKEYCODE_BUTTON_16          | 35     | 1.2.186 |
+
+([Definicje zdarzeń Android KeyEvent](https://developer.android.com/ndk/reference/group/input#group___input_1gafccd240f973cf154952fb917c9209719))
+
+| Ruch - indeks przycisku     | Indeks |
+|-----------------------------|--------|
+| AMOTION_EVENT_AXIS_X        | 0      |
+| AMOTION_EVENT_AXIS_Y        | 1      |
+| AMOTION_EVENT_AXIS_Z        | 2      |
+| AMOTION_EVENT_AXIS_RZ       | 3      |
+| AMOTION_EVENT_AXIS_LTRIGGER | 4      |
+| AMOTION_EVENT_AXIS_RTRIGGER | 5      |
+| AMOTION_EVENT_AXIS_HAT_X    | 6      |
+| AMOTION_EVENT_AXIS_HAT_Y    | 7      |
+
+([Definicje Android MotionEvent](https://developer.android.com/ndk/reference/group/input#group___input_1ga157d5577a5b2f5986037d0d09c7dc77d))
+
+Użyj tej tabelu w kombinacji z aplikacją testową dla gamepadów z Google Play Store, żeby zobaczyć jakie przyciski wywołują jakie wydarzenia na Twoim gamepadzie.

+ 57 - 0
docs/pl/manuals/input-key-and-text.md

@@ -0,0 +1,57 @@
+---
+title: Wejścia klawiszy i tekstowe w silniku Defold
+brief: Ta instrukcja wyjaśnia, jak działa wejście za pomocą klawiszy i wejścia tekstowe w silniku Defold.
+---
+
+::: sidenote
+Zalecamy zapoznanie się z ogólnym sposobem działania wejścia w Defoldzie, jak przechwytuje się wejście, jak wiążę z akcjami oraz w jakiej kolejności skrypty odbierają dane wejściowe. Dowiedz się więcej na temat systemu wejść w [ogólnej instrukcji na temat Wejść](/manuals/input).
+:::
+
+# Obsługa klawiatury
+
+Wyzwalacze klawiszy (ang. key triggers) pozwalają przypisywać pojedyncze klawisze klawiatury do akcji w grze. Każdy klawisz jest mapowany osobno na odpowiadającą mu akcję. Wyzwalacze klawiszy są używane do przypisywania konkretnych przycisków do określonych funkcji, na przykład ruchu postaci przy użyciu klawiszy strzałek lub WASD. Jeśli potrzebujesz odczytać dowolne dane wejściowe z klawiatury, użyj wyzwalaczy tekstowych (zobacz poniżej).
+
+![](images/input/key_bindings.png)
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("left") then
+        if action.pressed then
+            -- rozpocznij ruch w lewo
+        elseif action.released then
+            -- zakończ ruch w lewo
+        end
+    end
+end
+```
+
+# Obsługa tekstu
+
+Wyzwalacze tekstowe (ang. text triggers) służą do odczytywania dowolnego tekstu wprowadzanego za pomocą klawiatury. Istnieją dwa rodzaje wyzwalaczy tekstowych: tekstowy (text) i oznaczony tekst (marked text).
+
+![](images/input/text_bindings.png)
+
+## Tekst
+
+Wyzwalacz `text` służy do przechwytywania standardowego tekstu wprowadzanego za pomocą klawiatury. Ustawia pole `text` w tabeli akcji na ciąg znaków zawierający wprowadzoną literę. Akcja zostaje uruchomiona tylko w momencie naciśnięcia klawisza, nie wysyła akcji `released` lub `repeated`.
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("text") then
+        -- Concatenate the typed character to the "user" node...
+        local node = gui.get_node("user")
+        local name = gui.get_text(node)
+        name = name .. action.text
+        gui.set_text(node, name)
+    end
+end
+```
+
+## Zaznaczony tekst
+
+Wyzwalacz marked-text jest używany głównie w klawiaturach azjatyckich, gdzie wiele naciśnięć klawiszy może mapować się na pojedyncze wprowadzone znaki. Na przykład w klawiaturze iOS "Japanese-Kana" użytkownik może wprowadzać kombinacje, a górna część klawiatury wyświetla dostępne symbole lub sekwencje symboli, które można wprowadzić.
+
+![Input marked text](images/input/marked_text.png){srcset="images/input/[email protected] 2x"}
+
+- Każde naciśnięcie klawisza generuje osobną akcję i ustawia pole text akcji na obecnie wprowadzoną sekwencję symboli (tzw. "oznaczony tekst").
+- Gdy użytkownik wybierze symbol lub kombinację symboli, wysłana zostanie osobna akcja typu `text` (jeśli jest ona skonfigurowana na liście przypisań wejścia). Oddzielna akcja ustawia pole text akcji na ostateczną sekwencję symboli.

+ 131 - 0
docs/pl/manuals/input-mouse-and-touch.md

@@ -0,0 +1,131 @@
+---
+title: Wejścia myszki i dotykowe w silniku Defold
+brief: Ta instrukcja wyjaśnia, jak działa wejście za pomocą myszki i dotyku na urządzeniach dotykowych w silniku Defold.
+---
+
+::: sidenote
+Zalecamy zapoznanie się z ogólnym sposobem działania wejścia w Defoldzie, jak przechwytuje się wejście, jak wiążę z akcjami oraz w jakiej kolejności skrypty odbierają dane wejściowe. Dowiedz się więcej na temat systemu wejść w [ogólnej instrukcji na temat Wejść](/manuals/input).
+:::
+
+# Obsługa myszki
+
+Wyzwalacze myszy pozwalają na przypisanie akcji gry do klawiszy myszy i kółka przewijania.
+
+![](images/input/mouse_bindings.png)
+
+::: sidenote
+Przyciski myszy `MOUSE_BUTTON_LEFT`, `MOUSE_BUTTON_RIGHT` i `MOUSE_BUTTON_MIDDLE` są równoznaczne z `MOUSE_BUTTON_1`, `MOUSE_BUTTON_2` i `MOUSE_BUTTON_3`.
+:::
+
+::: important
+Poniższe przykłady korzystają z akcji pokazanych na powyższym obrazku. Możesz dowolnie nazywać akcje wejściowe - użyj takich, jakie są dla Ciebie najlepsze.
+:::
+
+## Przyciski myszki
+
+Klawisze myszy generują zdarzenia wciśnięcia, zwolnienia i powtarzania. Przykład pokazuje, jak wykrywać wejście z lewego klawisza myszy (czy wciśnięty lub zwolniony):
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("mouse_button_left") then
+        if action.pressed then
+            -- wciśnięto lewy przycisk myszy
+        elseif action.released then
+            -- wciśnięto prawy przycisk myszy
+        end
+    end
+end
+```
+
+::: important
+Akcje wejścia `MOUSE_BUTTON_LEFT` (lub `MOUSE_BUTTON_1`) są również wysyłane dla pojedynczego dotyku na urządzeniach dotykowych.
+:::
+
+## Kółko myszki
+
+Wejścia kółka myszy wykrywają akcje przewijania. Pole `action.value` wynosi `1`, jeśli kółko zostało przewinięte, a w przeciwnym przypadku `0` (akcje przewijania traktowane są tak, jak gdyby były to naciśnięcia klawiszy). Aktualnie Defold nie obsługuje dokładnego przewijania palcem na urządzeniach dotykowych.
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("mouse_wheel_up") then
+        if action.value == 1 then
+            -- przewinięcie kółka myszy w górę
+        end
+    end
+end
+```
+
+## Ruch myszki
+
+Ruch myszy jest obsługiwany osobno. Zdarzenia ruchu myszy nie są normalnie odbierane, chyba że w twoich przypisaniach wejścia jest ustawiony przynajmniej jeden wyzwalacz myszy.
+
+Ruch myszy nie jest opisywany w ustawieniach *input bindings*, dlatego `action_id` jest ustawiane na `nil`, a tabela `action` jest wypełniana pozycją i zmianą pozycji myszy, kiedy mysz jest poruszona.
+
+```lua
+function on_input(self, action_id, action)
+    if action.x and action.y then
+        -- pozwól obiektowi gry śledzić ruch myszy/dotyku
+        local pos = vmath.vector3(action.x, action.y, 0)
+        go.set_position(pos)
+    end
+end
+```
+
+# Obsługa urządzeń dotykowych
+
+Wyzwalacze dotyku (pojedynczego i wielodotykowego (ang. multitouch)) są dostępne na urządzeniach iOS i Android w aplikacjach natywnych oraz w grach przeglądarkowych HTML5.
+
+![](images/input/touch_bindings.png)
+
+## Pojedyncze dotknięcie
+
+Wyzwalacze pojedynczego dotyku nie są konfigurowane z poziomu sekcji *Touch Triggers* w przypisaniach wejścia (input bindings). Zamiast tego, wyzwalacze pojedynczego dotyku są **automatycznie konfigurowane**, gdy masz skonfigurowane wejście z klawiszem myszy `MOUSE_BUTTON_LEFT` lub `MOUSE_BUTTON_1`.
+
+## Multi-touch
+
+Wyzwalacze dotyku wielokrotnego wypełniają tabelę w tabeli akcji o nazwie `touch`. Elementy w tabeli są indeksowane liczbami całkowitymi od `1` do `N`, gdzie `N` to liczba punktów dotyku. Każdy element tabeli zawiera pola z danymi wejściowymi:
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("touch_multi") then
+        -- Twórz w każdym punkcie dotyku
+        for i, touchdata in ipairs(action.touch) do
+            local pos = vmath.vector3(touchdata.x, touchdata.y, 0)
+            factory.create("#factory", pos)
+        end
+    end
+end
+```
+
+::: important
+Multi-touch nie może być przypisany do tej samej akcji co wejście klawisza myszy `MOUSE_BUTTON_LEFT` lub `MOUSE_BUTTON_1`. Przypisanie tej samej akcji efektywnie nadpisze wyzwalacze pojedynczego dotyku i uniemożliwi otrzymanie jakichkolwiek zdarzeń pojedyncze dotknięcie.
+:::
+
+::: sidenote
+Gotowe rozwiązania do używania elementów sterowania na ekranie dotykowym (on-screen controls) czy ogólnie do obsługi przycisków i gałek analgowych z obsługą przeciągania i kliknięcia można znaleźć w bibliotece [Defold-Input](https://defold.com/assets/defoldinput/).
+:::
+
+
+## Detekcja kliknięć i dotknięć na obiekcie
+
+Wykrywanie kliknięć lub dotknięć na komponentach wizualnych to bardzo częsta operacja, którą można znaleźć w wielu grach. Może to być interakcja użytkownika z przyciskiem lub innym elementem interfejsu użytkownika, a także interakcja z obiektem gry, takim jak jednostka kontrolowana przez gracza w grze strategicznej, skarb na poziomie w grze typu dungeon crawler czy postać oferująca zadanie w grze RPG. Sposób użycia różni się w zależności od rodzaju komponentu wizualnego.
+
+### Wykrywanie interakcji z węzłami GUI
+
+Dla elementów interfejsu użytkownika istnieje funkcja `gui.pick_node(node, x, y)`, która zwraca wartość `true` lub `false`, w zależności od tego, czy określona współrzędna mieści się w granicach węzła GUI. Aby dowiedzieć się więcej, zajrzyj do [dokumentacji API](/ref/gui/#gui.pick_node:node-x-y), [przykładu nawigacji wskaźnikiem myszy](/examples/gui/pointer_over/) lub [przykładu z przyciskiem](/examples/gui/button/.
+
+### Wykrywanie interakcji z obiektami gry
+
+W przypadku obiektów gry (game objects) jest bardziej skomplikowane wykrywanie interakcji, ponieważ takie rzeczy jak przekształcenia kamery i projekcje renderowania mogą wpłynąć na wymagane obliczenia. Istnieją dwa ogólne podejścia do wykrywania interakcji z obiektami gry:
+
+  1. Śledzenie pozycji i rozmiaru obiektów gry, z którymi użytkownik może współdziałać, i sprawdzanie, czy współrzędne myszy lub dotyku mieszczą się w granicach któregoś z tych obiektów.
+  2. Dołączanie obiektów kolizji do obiektów gry, z którymi użytkownik może współdziałać, oraz jednego obiektu kolizji, który podąża za myszą lub palcem i sprawdzanie kolizji między nimi.
+
+::: sidenote
+Gotowe rozwiązanie do używania obiektów kolizji do wykrywania wejścia użytkownika z obsługą przeciągania i kliknięcia można znaleźć w elemencie [Defold-Input](https://defold.com/assets/defoldinput/).
+:::
+
+W obu przypadkach konieczne jest przeliczenie współrzędnych przestrzeni ekranu myszy lub dotyku na współrzędne przestrzeni gry. Można to zrobić na kilka różnych sposobów:
+
+  * Ręczne śledzenie, który widok i projekcja są używane przez skrypt renderujący i wykorzystaj to do przeliczenia współrzędnych na współrzędne przestrzeni gry. Zobacz [instrukcję kamery](/manuals/camera/#converting-mouse-to-world-coordinates).
+  * Użyj [bibliotek dla kamery](/manuals/camera/#third-party-camera-solutions) i skorzystaj z dostarczonych funkcji konwersji z ekranu na świat.

+ 222 - 0
docs/pl/manuals/input.md

@@ -0,0 +1,222 @@
+---
+title: Urządzenia wejścia w Defoldzie
+brief: Ta instrukcja wyjaśnia jak obsługiwać wejścia i przechwytywać i reagować na akcje użytkownika.
+---
+
+# Urządzenia wejścia
+
+Wszystkie dane wejściowe użytkownika (z klawiatury, myszki, ekranu dotykowego lub innego kontrolera) są przechwytywane przez silnik i wysyłane jako akcje do komponentów skryptów oraz komponentów skryptów GUI w obiektach gry, które zdobyły aktywne skupienie na wejścia (ang. input focus) i implementują funkcję cyklu życia `on_input()`. Niniejsza instrukcja wyjaśnia, jak skonfigurować wiązania wejścia (ang. input bindings) do przechwytywania danych wejściowych oraz jak tworzyć kod, który na nie reaguje.
+
+System wejściowy wykorzystuje zestaw prostych i potężnych koncepcji, pozwalających na zarządzanie danymi wejściowymi w sposób dostosowany do potrzeb Twojej gry.
+
+![Input bindings](images/input/overview.png){srcset="images/input/[email protected] 2x"}
+
+Devices
+: Urządzenia wejściowe, które są częścią lub podłączone do twojego komputera lub urządzenia mobilnego, dostarczają dane wejściowe na poziomie systemu operacyjnego, które przesyłane są do środowiska uruchomieniowego Defold. Obsługiwane są następujące typy urządzeń:
+
+  1. Keyboard - Klawiatura (pojedynczy klawisz oraz wprowadzanie tekstu)
+  2. Mouse - Mysz (pozycja, naciśnięcia przycisków i akcje kółka myszy)
+  3. Single and multi-touch - jedno- i wielopunktowy ekran dotykowy (na urządzeniach z systemem iOS i Android oraz na przeglądarkach HTML5)
+  4. Gamepads - Gamepady (obsługiwane przez system operacyjny i zmapowane w pliku [gamepads](#gamepads-settings-file))
+
+Input bindings
+: Wiązania wejścia - przed przekazaniem danych wejściowych do skryptu dane wejściowe z urządzenia są tłumaczone na konkretne *akcje* za pomocą tabeli wiązań wejścia (ang. input bindings table).
+
+Actions
+: Akcje są identyfikowane przez (zahaszowane) nazwy określone w pliku wiązań wejścia. Każda akcja zawiera także istotne dane na temat danych wejściowych: czy przycisk jest naciśnięty lub zwolniony, współrzędne myszy i dotyku itp.
+
+Input listeners
+: Każdy komponent skryptu lub skrypt GUI może odbierać akcje wejścia przez zdobycie skupienia wejścia (ang. *acquiring input focus*). Kilku słuchaczy (ang. listener) może być aktywnych jednocześnie.
+
+Input stack
+: Lista (stos) słuchaczy wejścia, z pierwszym zdobywającym skupienie na dole stosu i ostatnim zdobywającym na górze.
+
+Consuming input
+: Skrypt może wybrać, aby skonsumować dane wejściowe, uniemożliwiając ich odbieranie przez słuchaczy niżej w stosie.
+
+## Konfigurowanie wiązań wejścia
+
+Wiązania wejścia (input bindings) to tabela o zasięgu projektu, która pozwala określić, jak dane wejściowe z urządzenia powinny być tłumaczone na konkretne *akcje* przed ich przesłaniem do komponentów skryptów i skryptów GUI. Aby utworzyć nowy plik wiązań wejścia, <kbd>kliknij prawym przyciskiem myszy</kbd> w lokalizacji w panelu *Assets* i wybierz <kbd>New... ▸ Input Binding</kbd>. Aby użyć nowego pliku, zmień ustawienie *Game Binding* w pliku *game.project*.
+
+![Input binding setting](images/input/setting.png){srcset="images/input/[email protected] 2x"}
+
+Domyślny plik wiązań wejścia jest automatycznie tworzony w każdym nowym projekcie, więc zazwyczaj nie ma potrzeby tworzenia nowego pliku wiązań. Domyślny plik nazywa się "game.input_binding" i znajduje się w folderze "input" w głównym katalogu projektu. <kbd>Kliknij dwukrotnie</kbd> na plik, aby otworzyć go w edytorze:
+
+![Input set bindings](images/input/input_binding.png){srcset="images/input/[email protected] 2x"}
+
+Aby utworzyć nowe wiązanie, kliknij przycisk <kbd>+</kbd> u dołu odpowiedniego typu wyzwalacza (ang. trigger). Każde wprowadzenie ma dwie pola:
+
+*Input*
+: Surowe dane wejściowe do nasłuchiwania, wybierane z przewijanej listy dostępnych wejść.
+
+*Action*
+: Nazwa akcji nadawana akcjom wejściowym podczas ich tworzenia i przesyłania do skryptów. Tę samą nazwę akcji można przypisać wielu wejściom. Na przykład, można przypisać klawisz <kbd>Spacja</kbd> i przycisk "A" pada do akcji `skok`. Należy pamiętać, że wejścia dotykowe (touch inputs) niestety nie mogą mieć tych samych nazw akcji co inne wejścia.
+
+## Rodzaje wyzwalaczy
+
+Istnieje pięć różnych rodzajów wyzwalaczy (ang. triggers) specyficznych dla urządzenia, które można utworzyć:
+There are five device specific types of triggers that you can create:
+
+Key Triggers
+: Wyzwalacze uruchamiane przez klawisze klawiatury. Każdy klawisz jest mapowany osobno na odpowiadającą akcję. Więcej informacji można znaleźć w osobnej [instrukcji do wejść klawiszy i tekstowego](/manuals/input-key-and-text).
+
+Text Triggers
+: Wyzwalacze tekstu służą do odczytywania dowolnych danych wejściowych. Więcej informacji można znaleźć w osobnej [instrukcji do wejść klawiszy i tekstowego](/manuals/input-key-and-text)
+
+Mouse Triggers
+: Wejście z przycisków myszy i kółek przewijania myszy (scroll wheel). Więcej informacji można znaleźć w [instrukcji do wejść myszy i dotykowych](/manuals/input-mouse-and-touch).
+
+Touch Triggers
+: Dostępne są wyzwalacze typu jednopunktowego i wielopunktowego na urządzeniach z systemem iOS i Android w aplikacjach natywnych oraz w grach HTML5. Więcej informacji można znaleźć w [instrukcji do wejść myszy i dotykowych](/manuals/input-mouse-and-touch).
+
+Gamepad Triggers
+: Wyzwalacze gamepadów pozwalają na przypisanie standardowego wejścia z gamepada do funkcji gry. Więcej informacji można znaleźć w [instrukcji do gamepadów](/manuals/input-gamepads).
+
+### Wejście akcelerometru
+
+Oprócz pięciu różnych rodzajów wyzwalaczy wymienionych powyżej, Defold obsługuje również wejście akcelerometru w aplikacjach natywnych na systemy Android i iOS. Sprawdź pole "Use Accelerometer" w sekcji "Input" w pliku *game.project*.
+
+In addition to the five different trigger types listed above Defold also supports accelerometer input in native Android and iOS applications. Check the Use Accelerometer box in the Input section of your *game.project* file.
+
+```lua
+function on_input(self, action_id, action)
+    if action.acc_x and action.acc_y and action.acc_z then
+        -- react to accelerometer data
+    end
+end
+```
+
+## Input focus
+
+Aby nasłuchiwać akcji wejścia w komponencie skryptu lub skrypcie GUI, należy wysłać wiadomość `acquire_input_focus` do obiektu gry zawierającego ten komponent:
+
+```lua
+-- tell the current game object (".") to acquire input focus
+msg.post(".", "acquire_input_focus")
+```
+
+Ta wiadomość nakazuje silnikowi dodać komponenty zdolne do obsługi wejścia (skrypty, komponenty GUI i pełnomocnicy kolekcji) w obiektach gry do stosu wejścia: *input stack*. Komponenty obiektu gry są umieszczane na szczycie stosu wejścia; komponent, który został dodany ostatni, będzie na górze stosu. Należy zauważyć, że jeśli obiekt gry zawiera więcej niż jeden składnik zdolny do obsługi wejścia, wszystkie składniki zostaną dodane do stosu:
+
+![Input stack](images/input/input_stack.png){srcset="images/input/[email protected] 2x"}
+
+Jeśli obiekt gry, który już zdobył skupienie wejścia, robi to ponownie, jego komponenty zostaną przeniesione na górę stosu.
+
+## Przekazywanie akcji wejścia i on_input()
+
+Akcje wejściowe są rozpakowywane ze stosu wejścia od góry do dołu.
+
+![Action dispatch](images/input/actions.png){srcset="images/input/[email protected] 2x"}
+
+Dowolny komponent znajdujący się na stosie zawierający funkcję [on_input()](/ref/go#on_input) będzie miał tę funkcję wywoływaną dla każdej akcji wejściowej w trakcie klatki, z następującymi argumentami:
+
+`self`
+: Bieżąca instancja skryptu.
+
+`action_id`
+: Zahaszowana nazwa akcji, zgodnie z konfiguracją w plikach wiązań wejścia.
+
+`action`
+: Tabela zawierająca przydatne dane na temat akcji, takie jak wartość wejścia, jego położenie (pozycje absolutne i różnice), czy przycisk został *wciśnięty* itp. Zobacz więcej szczegółów w opisie funkcji [on_input()](/ref/go#on_input).
+
+```lua
+function on_input(self, action_id, action)
+  if action_id == hash("left") and action.pressed then
+    -- ruch w lew
+    local pos = go.get_position()
+    pos.x = pos.x - 100
+    go.set_position(pos)
+  elseif action_id == hash("right") and action.pressed then
+    -- ruch w prawo
+    local pos = go.get_position()
+    pos.x = pos.x + 100
+    go.set_position(pos)
+  end
+end
+```
+
+
+### Skupienie wejścia i składniki kolekcji proxy
+
+Każdy świat gry, który jest dynamicznie ładowany za pomocą komponentu pełnomocnika kolekcji (collection proxy), posiada własny stos wejścia. Aby akcje trafiły na stos wejścia załadowanego świata, komponent proxy musi znajdować się na stosie wejścia głównego świata. Wszystkie składniki na stosie załadowanego świata obsługiwane są przed kontynuacją przekazywania akcji w dół stosu głównego:
+
+![Action dispatch to proxies](images/input/proxy.png){srcset="images/input/[email protected] 2x"}
+
+::: important
+To powszechny błąd, że zapomina się wysłać wiadomość `acquire_input_focus` do obiektu gry zawierającego komponent kolekcji proxy. Pominięcie tego kroku uniemożliwia odbieranie akcji wejścia przez składniki na stosie załadowanego świata.
+:::
+
+
+### Zwalnianie wejścia
+
+Aby przestać nasłuchiwać akcji wejścia, wyślij wiadomość `release_input_focus` do obiektu gry. Ta wiadomość usunie komponenty obiektu gry ze stosu wejścia:
+
+```lua
+-- informuj bieżący obiekt gry (".") o zwolnieniu skupienia wejścia
+msg.post(".", "release_input_focus")
+```
+
+## Konsumowanie danych wejściowych
+
+Funkcja `on_input()` komponentu może aktywnie kontrolować, czy akcje powinny być przekazywane dalej na stosie, czy też nie:
+
+- Jeśli `on_input()` zwraca `false`, lub nic nie jest zwracane (również zwracania wartości `nil` jest tak traktowane w Lua), akcje wejściowe zostaną przekazane do następnego komponentu na stosie wejścia.
+- Jeśli `on_input()` zwraca `true`, dane wejściowe zostaną skonsumowane, co oznacza, że żaden komponent na stosie wejścia nie otrzyma danych wejściowych. Należy zauważyć, że dotyczy to wszystkich stosów wejścia. Komponent na stosie załadowanego świata może zużyć dane wejściowe, uniemożliwiając komponentom na stosie głównym ich odbieranie:
+
+![consuming input](images/input/consuming.png){srcset="images/input/[email protected] 2x"}
+
+Istnieje wiele dobrych przypadków użycia, w których konsumowanie danych wejściowych zapewnia prosty i potężny sposób na przesuwanie danych wejściowych między różnymi częściami gry. Na przykład, jeśli potrzebujesz menu wysuwane, które tymczasowo jest jedyną częścią gry nasłuchującą na wejście:
+
+![consuming input](images/input/game.png){srcset="images/input/[email protected] 2x"}
+
+Menu pauzy jest początkowo ukryte i wyłączone (disabled), a gdy gracz dotknie elementu HUD "PAUSE", jest włączane:
+
+```lua
+function on_input(self, action_id, action)
+    if action_id == hash("mouse_press") and action.pressed then
+        -- Czy gracz nacisnął PAUSE?
+        local pausenode = gui.get_node("pause")
+        if gui.pick_node(pausenode, action.x, action.y) then
+            -- Poinformuj menu pauzy o przejęciu kontroli..
+            msg.post("pause_menu", "show")
+        end
+    end
+end
+```
+
+![pause menu](images/input/game_paused.png){srcset="images/input/[email protected] 2x"}
+
+Menu pauzy GUI zdobywa skupienie wejścia i konsumuje dane wejściowe, uniemożliwiając odbieranie danych wejściowych innych niż te istotne dla menu wysuwanego:
+
+```lua
+function on_message(self, message_id, message, sender)
+  if message_id == hash("show") then
+    -- Pokaż menu pauzy.
+    local node = gui.get_node("pause_menu")
+    gui.set_enabled(node, true)
+
+    -- Zdobądź skupienie wejścia.
+    msg.post(".", "acquire_input_focus")
+  end
+end
+
+function on_input(self, action_id, action)
+  if action_id == hash("mouse_press") and action.pressed then
+
+    -- zrób coś...
+
+    local resumenode = gui.get_node("resume")
+    if gui.pick_node(resumenode, action.x, action.y) then
+        -- Ukryj menu pauzy
+        local node = gui.get_node("pause_menu")
+        gui.set_enabled(node, false)
+
+        -- Zwolnij wejście.
+        msg.post(".", "release_input_focus")
+    end
+  end
+
+  -- Skonsumuj wszystkie dane wejściowe. Cokolwiek poniżej nas na stosie wejścia
+  -- nigdy nie zobaczy danych wejściowych, dopóki nie zwolnimy skupienia wejścia.
+  return true
+end
+```

+ 675 - 0
docs/pl/manuals/lua.md

@@ -0,0 +1,675 @@
+---
+title: Programowanie Lua w Defoldzie
+brief: Ta instrukcja przedstawi krótkie wprowadzenie do podstaw programowania w języku Lua ogólnie oraz to, na co należy zwrócić uwagę podczas pracy z Lua w Defoldzie.
+---
+
+# Lua w Defoldzie
+
+Silnik Defold ma wbudowany język Lua do skryptowania. Lua to lekki język dynamiczny, który jest potężny, szybki i łatwy do osadzenia. Jest powszechnie używany jako język skryptowy w grach wideo. Programy w Lua są napisane w prostym składni proceduralnym. Język jest dynamicznie typowany i uruchamiany przez interpreter kodu bajtowego. Posiada automatyczne zarządzanie pamięcią z inkrementalnym zbieraniem śmieci.
+
+Ta instrukcja przedstawi krótkie wprowadzenie do podstaw programowania w Lua ogólnie oraz to, na co należy zwrócić uwagę podczas pracy z Lua w Defoldzie. Jeśli masz pewne doświadczenie z Pythonem, Perlem, Rubym, Javascriptem lub podobnym językiem dynamicznym, szybko się dostosujesz. Jeśli jesteś zupełnie nowy w programowaniu, możesz rozpocząć od książki o Lua skierowanej dla początkujących. Jest ich wiele do wyboru.
+
+## Wersje Lua
+
+Staramy się, aby Defold był taki sam na wszystkich platformach, ale obecnie mamy kilka drobnych rozbieżności w wersji języka Lua między platformami:
+
+| Platforma        | Wersja Lua          | JIT Włączony |
+|------------------|---------------------|--------------|
+| Windows          | LuaJIT 2.1.0-beta3  | Tak          |
+| macOS            | LuaJIT 2.1.0-beta3  | Tak          |
+| Linux            | LuaJIT 2.1.0-beta3  | Tak          |
+| Android          | LuaJIT 2.1.0-beta3  | Tak          |
+| iOS              | LuaJIT 2.1.0-beta3  | Nie*         |
+| Nintendo Switch  | LuaJIT 2.1.0-beta3  | Nie*         |
+| HTML5            | Lua 5.1.4           | N/A          |
+
+*=Kod kompilowany JIT nie jest dozwolony
+
+[LuaJIT](https://luajit.org/) to bardzo zoptymalizowana wersja Lua, odpowiednia do użycia w grach i innych krytycznych pod względem wydajności oprogramowaniu. LuaJIT jest w pełni kompatybilny w górę z Lua 5.1. Obsługuje wszystkie standardowe funkcje biblioteki Lua oraz pełen zestaw funkcji Lua/C API.
+
+LuaJIT dodaje również kilka [rozszerzeń języka](https://luajit.org/extensions.html) i niektóre funkcje z Lua 5.2.
+
+::: important
+Aby zagwarantować, że Twoja gra działa na wszystkich obsługiwanych platformach, gorąco zalecamy korzystanie TYLKO z funkcji języka z wersji Lua 5.1.
+:::
+
+### Biblioteki standardowe i rozszerzenia
+Defold zawiera wszystkie [standardowe biblioteki Lua 5.1](http://www.lua.org/manual/5.1/manual.html#5), a także bibliotekę do operacji na gniazdach i operacji bitowych:
+
+  - base (`assert()`, `error()`, `print()`, `ipairs()`, `require()`, itp.)
+  - coroutine
+  - package
+  - string
+  - table
+  - math
+  - io
+  - os
+  - debug
+  - socket (z [LuaSocket](https://github.com/diegonehab/luasocket))
+  - bitop (z [BitOp](http://bitop.luajit.org/api.html))
+
+Wszystkie biblioteki są udokumentowane w [dokumentacji API](/ref/go).
+
+## Książki i zasoby Lua
+
+### Zasoby online
+* [Programowanie w Lua (pierwsza edycja)](http://www.lua.org/pil/contents.html) Dostępne są późniejsze edycje w wersji drukowanej.
+* [Podręcznik referencyjny Lua 5.1](http://www.lua.org/manual/5.1/)
+* [Naucz się Lua w 15 minut](http://tylerneylon.com/a/learn-lua/)
+* [Niesamowita Lua - sekcja z tutorialami](https://github.com/LewisJEllis/awesome-lua#tutorials)
+
+### Książki
+* [Programowanie w Lua](https://www.amazon.com/gp/product/8590379868/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0) - Programowanie w Lua to oficjalna książka o języku, stanowiąca solidną podstawę dla każdego programisty, który chce używać Lua. Autorstwa Roberto Ierusalimschy, głównego architekta języka.
+* [Lua programming gems](https://www.amazon.com/gp/product/8590379868/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0) - Lua Programming Gems to zbiór krótkich i zrozumiałych przepisów, stworzonych przez różnych doświadczonych programistów Lua. Książka ta oferuje wiele przydatnych porad i trików dotyczących programowania w Lua.
+* [Beginning Lua Programming](https://www.amazon.com/gp/product/1484219602/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0) - Ta książka zawiera wiele praktycznych przykładów i projektów, które pomogą Ci opanować język Lua. Jest odpowiednia dla początkujących programistów, ale oferuje także bardziej zaawansowane tematy dla tych, którzy chcą pogłębić swoją wiedzę.
+* [Programming in Lua](https://www.amazon.com/gp/product/8590379868/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0) - Kolejna dobra książka na temat Lua, napisana przez Roberto Ierusalimschy, jednego z autorów języka Lua. Obejmuje wiele aspektów języka Lua i dostarcza praktyczne wskazówki oraz porady dotyczące programowania w nim.
+
+Oczywiście, istnieje wiele innych dostępnych materiałów i samouczków do nauki Lua, więc możesz wybrać te, które najlepiej odpowiadają Twoim potrzebom i poziomowi umiejętności.
+
+## Składnia języka Lua
+
+Programy w Lua mają prostą, czytelną składnię. Instrukcje zapisywane są jedna na każdej linii, i nie ma potrzeby oznaczania końca instrukcji. Opcjonalnie można używać średników `;` do oddzielania instrukcji. Bloki kodu są ograniczane słowem kluczowym `end`. Komentarze mogą być blokowe lub do końca linii:
+
+```lua
+--[[
+Oto blok komentarzy, który może zajmować
+wiele linii w pliku źródłowym.
+--]]
+
+a = 10
+b = 20 ; c = 30 -- dwie instrukcje w jednej linii
+
+if my_variable == 3 then
+    call_some_function(true) -- To jest komentarz w jednej linii
+else
+    call_another_function(false)
+end
+```
+
+## Zmienne i typy danych
+
+Lua jest językiem dynamicznym, co oznacza, że zmienne nie mają określonych typów, ale wartości już mają. W odróżnieniu od języków o typach statycznych, możesz przypisać dowolną wartość do dowolnej zmiennej. W Lua istnieje osiem podstawowych typów wartości:
+
+`nil`
+: Ten typ ma tylko jedna wartość, `nil`. Zazwyczaj reprezentuje brak przydatnej wartości, na przykład nieprzypisane zmienne.
+
+  ```lua
+  print(my_var) -- wyświetli 'nil', ponieważ 'moja_zmienna' nie ma jeszcze przypisanej wartości
+  ```
+
+`boolean`
+: Ma wartość `true` (prawda) lub `false` (fałsz). Warunki, które są `false` lub `nil`, uznawane są za fałsz. Każda inna wartość jest uważana za prawdę.
+
+  ```lua
+  flag = true
+  if flag then
+      print("flag is true")
+  else
+      print("flag is false")
+  end
+
+  if my_var then
+      print("my_var is not nil nor false!")
+  end
+
+  if not my_var then
+      print("my_var is either nil or false!")
+  end
+  ```
+
+`number`
+: Liczby są reprezentowane wewnętrznie jako 64-bitowe liczby całkowite (_integers_) lub 64-bitowe liczby zmiennoprzecinkowe (_floating point_). Lua automatycznie przelicza te reprezentacje, więc zazwyczaj nie musisz się tym martwić.
+
+  ```lua
+  print(10) --> prints '10'
+  print(10.0) --> '10'
+  print(10.000000000001) --> '10.000000000001'
+
+  a = 5 -- integer
+  b = 7/3 -- float
+  print(a - b) --> '2.6666666666667'
+  ```
+
+`string`
+: Stringi to ciągi znaków; są niemutowalnymi sekwencjami bajtów, które mogą zawierać dowolną wartość 8-bitową, włączając w to znaki zerowe (`\0`). Lua nie zakłada żadnych założeń co do zawartości ciągu, więc można w nich przechowywać dowolne dane. Ciągi znaków zapisuje się w pojedynczych lub podwójnych cudzysłowach. Lua przelicza liczby na ciągi znaków w trakcie wykonywania programu. Ciągi znaków można łączyć za pomocą operatora `..`.
+
+  Ciągi znaków mogą zawierać następujące sekwencje unikodowe w stylu C:
+
+  | Sekwencja | Znak      |
+  | --------- | --------- |
+  | `\a`      | dzwonek/alert |
+  | `\b`      | backspace |
+  | `\f`      | form feed (przewiń stronę) |
+  | `\n`      | newline (nowa linia) |
+  | `\r`      | carriage return (powrót karetki) |
+  | `\t`      | tabulacja pozioma |
+  | `\v`      | tabulacja pionowa |
+  | `\\`      | ukośnik wsteczny |
+  | `\"`      | podwójny cudzysłów |
+  | `\'`      | pojedynczy cudzysłów |
+  | `\[`      | lewy nawias kwadratowy |
+  | `\]`      | prawy nawias kwadratowy |
+  | `\ddd`    | znak określony wartością liczbową, gdzie ddd to sekwencja od jednej do trzech dziesiętnych cyfr |
+
+  ```lua
+  my_string = "hello"
+  another_string = 'world'
+  print(my_string .. another_string) --> "helloworld"
+
+  print("10.2" + 1) --> 11.2
+  print(my_string + 1) -- błąd, nie można przekonwertować "hello"
+  print(my_string .. 1) --> "hello1"
+
+  print("one\nstring") --> one
+                       --> string
+
+  print("\097bc") --> "abc"
+
+  multi_line_string = [[
+  Oto kawałek tekstu, który rozciąga się na wiele linii. To jest wszystko
+  umieszczone w ciągu znaków i czasami jest to bardzo przydatne.
+  ]]
+  ```
+
+function
+: Funkcje w Lua są wartościami pierwszej klasy, co oznacza, że można je przekazywać jako parametry do funkcji i zwracać jako wartości. Zmienne przypisane do funkcji zawierają referencję do funkcji. Możesz przypisywać zmienne do anonimowych funkcji, ale Lua dostarcza składni ułatwiającej pracę (`function nazwa(param1, param2) ... end`).
+
+  ```lua
+  -- Przypisz 'my_plus' do funkcji
+  my_plus = function(p, q)
+      return p + q
+  end
+
+  print(my_plus(4, 5)) --> 9
+
+  -- Wygodna składnia do przypisania funkcji do zmiennej 'my_mult'
+  function my_mult(p, q)
+      return p * q
+  end
+
+  print(my_mult(4, 5)) --> 20
+
+  -- Przyjmuje funkcję jako parametr 'func'
+  function operate(func, p, q)
+      return func(p, q) -- Wywołuje podaną funkcję z parametrami 'p' i 'q'
+  end
+
+  print(operate(my_plus, 4, 5)) --> 9
+  print(operate(my_mult, 4, 5)) --> 20
+
+  -- Stwórz funkcję dodawania i zwróć ją
+  function create_adder(n)
+      return function(a)
+          return a + n
+      end
+  end
+
+  adder = create_adder(2)
+  print(adder(3)) --> 5
+  print(adder(10)) --> 12
+  ```
+
+`table`
+: Tabele są jedynym typem danych strukturalnych w Lua. Są to _obiekty_ tablic asocjacyjnych, które służą do reprezentowania list, tablic, sekwencji, tabel symboli, zbiorów, rekordów, grafów, drzew itp. Tabele są zawsze anonimowe, a zmienne, do których przypisuje się tabelę, nie zawierają samej tabeli, lecz odniesienie do niej. Podczas inicjalizacji tabeli jako sekwencji pierwszy indeks to `1`, a nie `0`.
+
+  ```lua
+  -- Zainicjuj tabelę jako sekwencję
+  weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday",
+              "Thursday", "Friday", "Saturday"}
+  print(weekdays[1]) --> "Sunday"
+  print(weekdays[5]) --> "Thursday"
+
+  -- Zainicjuj tabelę jako rekord z wartościami sekwencyjnymi
+  moons = { Earth = { "Moon" },
+            Uranus = { "Puck", "Miranda", "Ariel", "Umbriel", "Titania", "Oberon" } }
+  print(moons.Uranus[3]) --> "Ariel"
+
+  -- Zbuduj tabelę za pomocą pustego konstruktora {}
+  a = 1
+  t = {}
+  t[1] = "first"
+  t[a + 1] = "second"
+  t.x = 1 -- to samo co t["x"] = 1
+
+  -- Przechodzenie przez pary klucz-wartość w tabeli
+  for key, value in pairs(t) do
+      print(key, value)
+  end
+  --> 1   first
+  --> 2   second
+  --> x   1
+
+  u = t -- u teraz odnosi się do tej samej tabeli co t
+  u[1] = "changed"
+
+  for key, value in pairs(t) do -- nadal iteracja po t!
+      print(key, value)
+  end
+  --> 1   changed
+  --> 2   second
+  --> x   1
+  ```
+
+`userdata`
+: Userdata (dane użytkownika) pozwala na przechowywanie dowolnych danych C w zmiennych Lua. W Defoldzie, userdata Lua służy do przechowywania wartości Hash (`hash`), obiektów URL (`url`), obiektów Math (`vector3`, `vector4`, `matrix4`, `quaternion`), obiektów gry, węzłów GUI (`GUI node`), predykatów renderowania (`predicate`), celów renderowania (`render_target`) oraz buforów stałych renderowania (`constant_buffer`).
+
+`thread`
+: Wątki reprezentują niezależne wątki wykonywania i są używane do implementacji korygujących. Zobacz poniżej dla szczegółów.
+
+## Operatory
+
+Operatory arytmetyczne
+: Operatory matematyczne `+`, `-`, `*`, `/`, unarny `-` (negacja) i eksponenta `^`.
+
+  ```lua
+  a = -1
+  print(a * 2 + 3 / 4^5) --> -1.9970703125
+  ```
+
+  Lua zapewnia automatyczną konwersję między liczbami i ciągami znaków (strings) w trakcie działania programu. Każda operacja numeryczna stosowana do ciągu znaków próbuje przekształcić ciąg w liczbę:
+
+  ```lua
+  print("10" + 1) --> 11
+  ```
+
+Operatory relacyjne/porównania
+: `<` (mniejsze niż), `>` (większe niż), `<=` (mniejsze lub równe), `>=` (większe lub równe), `==` (równe), `~=` (nierówne). Operatory te zawsze zwracają `true` lub `false`. Wartości różnych typów są uważane za różne. Jeśli typy są takie same, są porównywane na podstawie ich wartości. Lua porównuje tabele, userdata i funkcje na podstawie odniesienia. Dwie takie same wartości są uważane za równe tylko wtedy, gdy odnoszą się do tego samego obiektu.
+
+  ```lua
+  a = 5
+  b = 6
+
+  if a <= b then
+      print("a is less than or equal to b")
+  end
+
+  print("A" < "a") --> true
+  print("aa" < "ab") --> true
+  print(10 == "10") --> false
+  print(tostring(10) == "10") --> true
+  ```
+
+Operatory logiczne
+: `and`, `or`, oraz `not`. Operator `and` zwraca swój pierwszy argument, jeśli jest on `false`, w przeciwnym razie zwraca swój drugi argument. Operator `or` zwraca swój pierwszy argument, jeśli nie jest on `false`, w przeciwnym razie zwraca swój drugi argument.
+
+  ```lua
+  print(true or false) --> true
+  print(true and false) --> false
+  print(not false) --> true
+
+  if a == 5 and b == 6 then
+      print("a is 5 and b is 6")
+  end
+  ```
+
+Konkatenacja
+: Ciągi znaków (string) można konkatenować za pomocą operatora `...` Liczby są przeliczane na ciągi znaków podczas konkatenacji.
+
+  ```lua
+  print("donkey" .. "kong") --> "donkeykong"
+  print(1 .. 2) --> "12"
+  ```
+
+Długość
+: Jednoargumentowy operator długości (length) `#`. Długość ciągu znaków to liczba jego bajtów. Długość tabeli to jej długość sekwencji, czyli liczba indeksów o numerze od `1` wzwyż, gdzie wartość nie jest `nil`. Uwaga: Jeśli w sekwencji są "dziury" z wartością `nil`, długość może być indeksem poprzedzającym wartość `nil`.
+
+  ```lua
+  s = "donkey"
+  print(#s) --> 6
+
+  t = { "a", "b", "c", "d" }
+  print(#t) --> 4
+
+  u = { a = 1, b = 2, c = 3 }
+  print(#u) --> 0
+
+  v = { "a", "b", nil }
+  print(#v) --> 2
+  ```
+
+## Kontrola przepływu danych
+
+ua dostarcza standardowy zestaw konstrukcji sterowania przepływem (flow control).
+
+if---then---else
+: Testuje warunek, wykonuje część `then`, jeśli warunek jest prawdziwy, w przeciwnym razie wykonuje (opcjonalną) część `else`. Zamiast zagnieżdżać instrukcje `if`, można używać `elseif`. To zastępuje instrukcję `switch`, której Lua nie ma.
+
+  ```lua
+  a = 5
+  b = 4
+
+  if a < b then
+      print("a is smaller than b")
+  end
+
+  if a == '1' then
+      print("a is 1")
+  elseif a == '2' then
+      print("a is 2")
+  elseif a == '3' then
+      print("a is 3")
+  else
+      print("I have no idea what a is...")
+  end
+  ```
+
+while
+: Testuje warunek i wykonuje blok tak długo, jak warunek jest prawdziwy (`true`).
+
+  ```lua
+  weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday",
+              "Thursday", "Friday", "Saturday"}
+
+  -- Print each weekday
+  i = 1
+  while weekdays[i] do
+      print(weekdays[i])
+      i = i + 1
+  end
+  ```
+
+repeat---until
+: Powtarza blok aż warunek stanie się prawdziwy (`true`). Warunek jest testowany po bloku kodu, więc blok zostanie wykonany co najmniej raz.
+
+  ```lua
+  weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday",
+              "Thursday", "Friday", "Saturday"}
+
+  -- Print each weekday
+  i = 0
+  repeat
+      i = i + 1
+      print(weekdays[i])
+  until weekdays[i] == "Saturday"
+  ```
+
+for
+: Lua posiada dwa rodzaje pętli `for`: numeryczną i ogólną. Numeryczna pętla `for` przyjmuje 2 lub 3 wartości liczbowe, natomiast ogólna pętla `for` iteruje po wszystkich wartościach zwracanych przez funkcję _iteratora_.
+
+  ```lua
+  -- Wyświetla liczby do 1 do 10
+  for i = 1, 10 do
+      print(i)
+  end
+
+  -- Wyświetla liczby od 1 do 10 z krokiem 2
+  for i = 1, 10, 2 do
+      print(i)
+  end
+
+  -- Wyświetla liczby od 10 do 1
+  for i=10, 1, -1 do
+      print(i)
+  end
+
+  t = { "a", "b", "c", "d" }
+  -- Iteruje po sekwencji i wyświetla wartości
+  for i, v in ipairs(t) do
+      print(v)
+  end
+  ```
+
+break and return
+: Użyj instrukcji `break`, aby przerwać blok pętli `for`, `while` lub `repeat`. Użyj `return`, aby zwrócić wartość z funkcji lub zakończyć jej wykonywanie i wrócić do wywołującego. `break` lub `return` mogą występować tylko jako ostatnia instrukcja bloku.
+
+  ```lua
+  a = 1
+  while true do
+      a = a + 1
+      if a >= 100 then
+          break
+      end
+  end
+
+  function my_add(a, b)
+      return a + b
+  end
+
+  print(my_add(10, 12)) --> 22
+  ```
+
+## Lokalne zmienne, zmienne globalne i zasięg leksykalny
+
+Wszystkie zmienne, które deklarujesz, są domyślnie globalne, co oznacza, że są dostępne we wszystkich częściach kontekstu uruchomienia Lua. Możesz wyraźnie zadeklarować zmienne jako `local`, co oznacza, że zmienna istnieje tylko w bieżącym zakresie (ang. scope).
+
+Każdy plik źródłowy Lua definiuje osobny zakres. Lokalne deklaracje na najwyższym poziomie w pliku oznaczają, że zmienna jest lokalna w skrypcie Lua. Każda funkcja tworzy inny zagnieżdżony zakres, a każdy blok struktury sterującej tworzy dodatkowe zakresy. Możesz wyraźnie tworzyć zakresy za pomocą słów kluczowych `do` i `end`. Lua działa w zakresie leksykalnym, co oznacza, że zakres ma pełny dostęp do _lokalnych_ zmiennych z otaczającego zakresu. Należy zauważyć, że zmienne lokalne muszą być zadeklarowane przed ich użyciem.
+
+```lua
+function my_func(a, b)
+    -- 'a' i 'b' są lokalne w tej funkcji i dostępne w jej zakresie
+
+    do
+        local x = 1
+    end
+
+    print(x) --> nil. 'x' nie jest dostępne poza zakresem do-end
+    print(foo) --> nil. 'foo' jest zadeklarowane poza 'moja_funkcja'
+    print(foo_global) --> "value 2", ponieważ jest globalna
+end
+
+local foo = "value 1"
+foo_global = "value 2"
+
+print(foo) --> "value 1". 'foo' jest dostępne w najwyższym zakresie po deklaracji.
+```
+
+Należy zauważyć, że jeśli deklarujesz funkcje jako `local` w pliku skryptu (co jest ogólnie dobrym pomysłem), musisz uważać na kolejność kodu. Możesz użyć deklaracji przód, jeśli masz funkcje, które nawzajem się wywołują.
+
+```lua
+local func2 -- Forward declaration: 'func2'
+
+local function func1(a)
+    print("func1")
+    func2(a)
+end
+
+function func2(a) -- lub func2 = function(a)
+    print("func2")
+    if a < 10 then
+        func1(a + 1)
+    end
+end
+
+function init(self)
+    func1(1)
+end
+```
+
+Jeśli napiszesz funkcję zamkniętą w innej funkcji, ma ona także pełen dostęp do lokalnych zmiennych z otaczającej funkcji. To jest bardzo potężna konstrukcja.
+
+```lua
+function create_counter(x)
+    -- 'x' to zmienna lokalna w 'create_counter'
+    return function()
+        x = x + 1
+        return x
+    end
+end
+
+count1 = create_counter(10)
+count2 = create_counter(20)
+print(count1()) --> 11
+print(count2()) --> 21
+print(count1()) --> 12
+```
+
+## Zasłanianie zmiennych
+
+Lokalne zmienne zadeklarowane w bloku zasłonią zmienne o tej samej nazwie w otaczającym bloku.
+
+```lua
+my_global = "global"
+print(my_global) -->"global"
+
+local v = "local"
+print(v) --> "local"
+
+local function test(v)
+    print(v)
+end
+
+function init(self)
+    v = "apple"
+    print(v) --> "apple"
+    test("banana") --> "banana"
+end
+```
+
+## Korutyny
+
+Funkcje wykonują się od początku do końca, i nie ma sposobu, aby zatrzymać je w połowie. Korutyny (ang. coroutines) umożliwiają to, co może być bardzo wygodne w niektórych przypadkach. Załóżmy, że chcemy stworzyć bardzo konkretną animację klatka po klatce, w której przesuwamy obiekt gry z pozycji Y `0` do niektórych konkretnych pozycji Y od klatki 1 do klatki 5. Moglibyśmy rozwiązać to za pomocą licznika w funkcji `update()` (patrz poniżej) i listy pozycji. Jednak z użyciem korutyny uzyskujemy bardzo czystą implementację, która jest łatwa do rozbudowy i pracy. Cały stan jest zawarty w samej korutynie.
+
+Gdy korutyna jest zawieszona, zwraca kontrolę do wywołującego, ale pamięta swój punkt wykonania, więc może kontynuować od tego momentu później.
+
+```lua
+-- To nasza korutyna
+local function sequence(self)
+    coroutine.yield(120)
+    coroutine.yield(320)
+    coroutine.yield(510)
+    coroutine.yield(240)
+    return 440 -- zwraca wartość końcową
+end
+
+function init(self)
+    self.co = coroutine.create(sequence) -- Tworzy korutynę. 'self.co' to obiekt wątku
+    go.set_position(vmath.vector3(100, 0, 0)) -- Ustawia pozycję początkową
+end
+
+function update(self, dt)
+    local status, y_pos = coroutine.resume(self.co, self) -- Kontynuuje wykonywanie koriutyny.
+    if status then
+        -- Jeśli korutyna nie jest jeszcze zakończona, używa wartości zwróconej przez nią jako nowej pozycji
+        go.set_position(vmath.vector3(100, y_pos, 0))
+    end
+end
+```
+
+
+## Konteksty Lua w Defoldzie
+
+Wszystkie zmienne, które deklarujesz, są domyślnie globalne, co oznacza, że są dostępne we wszystkich częściach kontekstu uruchomienia Lua (ang. Lua runtime context). W Defoldzie istnieje opcja *shared_state* w pliku *game.project*, która kontroluje ten kontekst. Jeśli opcja jest ustawiona, wszystkie skrypty, skrypty GUI i skrypt renderowania są oceniane w tym samym kontekście Lua, a zmienne globalne są widoczne wszędzie. Jeśli opcja nie jest ustawiona, silnik wykonuje skrypty, skrypty GUI i skrypt renderowania w osobnych kontekstach.
+
+![Contexts](images/lua/lua_contexts.png)
+
+Defold pozwala na użycie tego samego pliku skryptu w kilku osobnych komponentach obiektu gry. Wszystkie zmienne zadeklarowane lokalnie są udostępniane między komponentami, które używają tego samego pliku skryptu.
+
+```lua
+-- 'my_global_value' będzie dostępna we wszystkich skryptach, skryptach GUI, skrypcie renderowania i modułach (plikach Lua)
+my_global_value = "global scope"
+
+-- ta wartość będzie współdzielona między wszystkimi instancjami komponentu, które używają tego konkretnego pliku skryptu
+local script_value = "script scope"
+
+function init(self, dt)
+    -- Ta wartość będzie dostępna w bieżącej instancji komponentu skryptu
+    self.foo = "self scope"
+
+    -- ta wartość będzie dostępna wewnątrz funkcji init() i po jej deklaracji
+    local local_foo = "local scope"
+    print(local_foo)
+end
+
+function update(self, dt)
+    print(self.foo)
+    print(my_global_value)
+    print(script_value)
+    print(local_foo) -- wypisze nil, ponieważ local_foo jest widoczne tylko w init()
+end
+```
+
+## Rozważania dotyczące wydajności
+
+W grach o wysokiej wydajności, które mają działać płynnie w 60 FPS, niewielkie błędy wydajności mogą mieć duży wpływ na doświadczenie. Istnieją pewne ogólne rzeczy do rozważenia, a także niektóre, które na pierwszy rzut oka mogą się nie wydawać problematyczne.
+
+Zacznijmy od prostych rzeczy. Zawsze warto jest pisać prosty kod, który nie zawiera zbędnych pętli. Czasami konieczne jest iterowanie przez listy rzeczy, ale należy być ostrożnym, jeśli lista jest dosyć duża. Poniższy przykład działa w nieco ponad 1 milisekundę na dość dobrym laptopie, co może mieć ogromne znaczenie, jeśli każda klatka trwa tylko 16 milisekund (przy 60 FPS), a silnik, skrypt renderowania, symulacja fizyki i inne czynniki już pochłaniają część tego czasu.
+
+```lua
+local t = socket.gettime()
+local table = {}
+for i=1,2000 do
+    table[i] = vmath.vector3(i, i, i)
+end
+print((socket.gettime() - t) * 1000)
+
+-- DEBUG:SCRIPT: 0.40388
+```
+
+Aby sprawdzić wydajność wątpliwego kodu, można użyć wartości zwracanej przez `socket.gettime()` (liczba sekund od tzw. epoki systemowej).
+
+## Pamięć i gromadzenie śmieci
+
+Gromadzenie śmieci (ang. garbage collection) w Lua działa domyślnie w tle i zwalnia pamięć, którą alokował runtime Lua. Gromadzenie dużej ilości śmieci może być czasochłonnym zadaniem, dlatego warto ograniczać liczbę obiektów, które trzeba będzie zniszczyć:
+
+* Zmienne lokalne same w sobie nie generują śmieci (np. `local v = 42`).
+* Każdy nowy unikalny ciąg (string) tworzy nowy obiekt. Zapisywanie `local s = "some_string"` stworzy nowy obiekt i przypisze go do `s`. Zmienna lokalna `s` sama w sobie nie generuje śmieci, ale obiekt ciągu tak.
+* Za każdym razem, gdy jest wykonywany konstruktor tabeli (`{ ... }`), tworzona jest nowa tabela.
+* Wykonanie deklaracji funkcji tworzy obiekt zamknięcia (ang. closure object). (np. wykonanie deklaracji `function () ... end`, a nie wywołanie zdefiniowanej funkcji)
+* Funkcje o zmiennej liczbie argumentów, tzw. vararg (`function(v, ...) end`) tworzą tabelę dla wielokropka za każdym razem, gdy funkcja jest wywoływana (w Lua przed wersją 5.2 lub jeśli nie używasz LuaJIT).
+* `dofile()` i `dostring()`
+* Obiekty użytkownika (Userdata)
+
+Istnieją sytuacje, w których można uniknąć tworzenia nowych obiektów i zamiast tego ponownie używać tych już istniejących. Na przykład, na końcu każdej funkcji `update()` można znaleźć:
+
+```lua
+-- Resetuj prędkość
+self.velocity = vmath.vector3()
+```
+
+Łatwo jest zapomnieć, że każde wywołanie `vmath.vector3()` tworzy nowy obiekt. Sprawdźmy, ile pamięci zajmuje jeden obiekt `vector3`:
+
+```lua
+print(collectgarbage("count") * 1024)       -- 88634
+local v = vmath.vector3()
+print(collectgarbage("count") * 1024)       -- 88704. Razem przypisano 70 bajtów
+```
+
+Między wywołaniami `collectgarbage()` przydzielono 70 bajtów, ale obejmuje to alokacje większe niż obiekt `vector3`. Każde wyświetlenie wyniku z `collectgarbage()` generuje ciąg, co samo w sobie dodaje 22 bajty śmieci:
+
+```lua
+print(collectgarbage("count") * 1024)       -- 88611
+print(collectgarbage("count") * 1024)       -- 88633. Przydzielono 22 bajty
+```
+
+Dlatego `vector3` zajmuje 70-22 = 48 bajtów. To nie jest wiele, ale jeśli tworzysz jeden obiekt w każdej klatce w grze o 60 FPS, nagle masz 2,8 kB śmieci na sekundę. Z 360 komponentami skryptowymi, które każdy tworzą jeden `vector3` co klatka, otrzymujemy 1 MB śmieci generowanych na sekundę. Te liczby mogą bardzo szybko się zwiększać. Gdy runtime Lua automatycznie zbiera śmieci, może to zabrać wiele cennych milisekund, zwłaszcza na platformach mobilnych.
+
+Jednym ze sposobów unikania alokacji jest stworzenie `vector3` i pracowanie dalej na tym samym obiekcie. Na przykład, aby zresetować `vector3`, można użyć następującej konstrukcji:
+
+```lua
+-- Zamiast robić self.velocity = vmath.vector3(), co tworzy nowy obiekt
+-- zerujemy składowe istniejącego obiektu wektora prędkości
+self.velocity.x = 0
+self.velocity.y = 0
+self.velocity.z = 0
+```
+
+Domyślna konfiguracja gromadzenia śmieci może nie być optymalna w przypadku aplikacji o dużym nacisku na czas. Jeśli widzisz szarpanie w grze lub aplikacji, warto dostosować sposób gromadzenia śmieci w Lua za pomocą funkcji [`collectgarbage()`](/ref/base/#collectgarbage). Możesz na przykład uruchamiać zbieracz przez krótki czas w każdej klatce z niską wartością `step`. Aby dowiedzieć się, ile pamięci zużywa twoja gra lub aplikacja, możesz wydrukować aktualną liczbę bajtów śmieci za pomocą:
+
+```lua
+print(collectgarbage("count") * 1024)
+```
+
+## Najlepsze praktyki
+
+Jednym z podstawowych aspektów projektowania jest sposób strukturyzowania kodu dla współdzielonych zachowań. Istnieje kilka możliwych podejść.
+
+Zachowania w module
+: Umieszczenie zachowania w module pozwala na łatwe dzielenie kodu między różnymi komponentami obiektów gry (i skryptami GUI). Podczas pisania funkcji modułu zazwyczaj warto pisać kod ściśle funkcyjny. Są przypadki, w których przechowywanie stanu lub skutki uboczne są koniecznością (lub prowadzą do czystszej struktury). Jeśli trzeba przechowywać stan w module, trzeba pamiętać, że komponenty współdzielą konteksty Lua. Zobacz szczegóły w [instrukcji do modułów](/manuals/modules).
+
+  ![Module](images/lua/lua_module.png)
+  
+  Ponadto, nawet jeśli modułowi jest możliwe bezpośrednie modyfikowanie wewnętrznych danych obiektu gry (przesyłanie `self` do funkcji modułu), zdecydowanie odradzamy to, ponieważ prowadzi to do bardzo silnego sprzężenia.
+
+Pomocniczy obiekt gry z zamkniętym zachowaniem
+: Tak samo, jak można umieścić kod skryptu w module Lua, można go umieścić w obiekcie gry z komponentem skryptowym. Różnica polega na tym, że umieszczenie go w obiekcie gry pozwala na komunikację z nim tylko poprzez przekazywanie wiadomości.
+
+  ![Helper](images/lua/lua_helper.png)
+  
+Grupowanie obiektu gry z pomocniczym obiektem zachowania wewnątrz kolekcji
+: W tym projekcie można stworzyć obiekt gry, który automatycznie działa na innym docelowym obiekcie gry, albo przez zdefiniowaną nazwę (użytkownik musi zmienić nazwę docelowego obiektu gry, aby pasowała), albo poprzez adres URL `go.property()`, który wskazuje na docelowy obiekt gry.
+
+  ![Collection](images/lua/lua_collection.png)
+
+  Zaletą tego rozwiązania jest to, że można umieścić obiekt gry zachowania w kolekcji zawierającej docelowy obiekt. Nie jest wymagany żaden dodatkowy kod.
+
+  W przypadkach, gdy musisz zarządzać dużą ilością obiektów gry, to rozwiązanie nie jest zalecane, ponieważ obiekt zachowania jest duplikowany dla każdej instancji, a każdy obiekt będzie kosztować pamięć.

+ 239 - 0
docs/pl/manuals/modules.md

@@ -0,0 +1,239 @@
+---
+title: Moduły Lua w Defoldzie
+brief: Ta instrukcja wyjaśnia czym są i jak działają moduły Lua w Defoldzie.
+---
+
+# Moduły Lua
+
+Moduły Lua pozwalają na strukturyzację projektu i tworzenie wielokrotnie używanego kodu bibliotecznego. Ogólnie warto unikać duplikacji w projektach. Defold pozwala korzystać z funkcjonalności modułu Lua, aby dołączać pliki skryptowe do innych plików skryptowych. Dzięki temu można zawierać funkcje (i dane) w zewnętrznym pliku skryptowym, aby ponownie używać ich w plikach skryptów obiektów gry i plikach skryptów GUI.
+
+## Wymaganie/załączanie plików Lua
+
+Kod Lua przechowywany w plikach z rozszerzeniem ".lua" w dowolnym miejscu w strukturze projektu gry może być wymagany (dołączony) w plikach skryptowych i plikach skryptów GUI. Aby utworzyć nowy plik modułu Lua, kliknij prawym przyciskiem myszy folder, w którym chcesz go utworzyć w widoku *Assets*, a następnie wybierz <kbd>New... ▸ Lua Module</kbd>. Nadaj plikowi unikalną nazwę i naciśnij <kbd>Ok</kbd>:
+
+![new file](images/modules/new_name.png){srcset="images/modules/[email protected] 2x"}
+
+Załóżmy, że poniższy kod jest dodany do pliku "main/anim.lua":
+
+```lua
+function direction_animation(direction, char)
+    local d = ""
+    if direction.x > 0 then
+        d = "right"
+    elseif direction.x < 0 then
+        d = "left"
+    elseif direction.y > 0 then
+        d = "up"
+    elseif direction.y < 0 then
+        d = "down"
+    end
+    return hash(char .. "-" .. d)
+end
+```
+
+Następnie dowolny skrypt może zażądać (ang. require) tego pliku i używać funkcji:
+
+```lua
+require "main.anim"
+
+function update(self, dt)
+    -- zaktualizuj pozycję, ustaw kierunek itp.
+    ...
+
+    -- ustaw animację
+    local anim = direction_animation(self.dir, "player")
+    if anim ~= self.current_anim then
+        msg.post("#sprite", "play_animation", { id = anim })
+        self.current_anim = anim
+    end
+end
+```
+
+Funkcja `require` wczytuje podany moduł. Na początek przegląda tabelę [`package.loaded`](/ref/package/#package.loaded), aby sprawdzić, czy moduł jest już załadowany. Jeśli tak, funkcja `require` zwraca wartość przechowywaną w `package.loaded[module_name]`. W przeciwnym przypadku wczytuje i ewaluuje plik za pomocą ładowacza (ang. loader).
+
+Składnia łańcucha nazwy pliku (filename string) przekazywanej do require jest nieco specjalna. Lua zamienia znaki `"."` w łańcuchu nazwy pliku na znaki separatora ścieżki: `'/'` na macOS i Linux oraz `'\'` na systemie Windows.
+
+Należy zauważyć, że zazwyczaj nie jest dobrym pomysłem używanie zakresu globalnego do przechowywania stanu i definiowania funkcji, tak jak w przykładzie powyżej. Istnieje ryzyko kolizji nazw, ujawnienia stanu modułu lub wprowadzenia zależności między użytkownikami modułu.
+
+## Modułu
+
+Aby inkapsulować dane i funkcje, Lua używa _modułów_. Moduł Lua to zwykła tabela Lua służąca do zawierania funkcji i danych. Tabela jest deklarowana jako lokalna, aby nie zanieczyszczać zakresu globalnego:
+
+```lua
+local M = {}
+
+-- private
+local message = "Hello world!"
+
+function M.hello()
+    print(message)
+end
+
+return M
+```
+
+Moduł można następnie używać. Ponownie, preferuje się przypisanie go do zmiennej lokalnej:
+
+```lua
+local m = require "mymodule"
+m.hello() --> "Hello world!"
+```
+
+## Ładowanie modułów w trakcie działania (hot reloading)
+
+Rozważmy prosty moduł:
+
+```lua
+-- module.lua
+local M = {} -- tworzy nową tabelę w zakresie lokalnym
+M.value = 4711
+return M
+```
+
+I użytkownika modułu:
+
+```lua
+local m = require "module"
+print(m.value) --> "4711" (nawet jeśli plik "module.lua" zostanie zmieniony i na nowo załadowany)
+```
+
+Jeśli ponownie załadujesz plik modułu, kod zostanie uruchomiony ponownie, ale nic się nie dzieje z `m.value`. Dlaczego?
+
+Po pierwsze, tabela utworzona w pliku "module.lua" jest tworzona w zakresie lokalnym, a odniesienie do tej tabeli jest zwracane użytkownikowi. Ponowne wczytanie pliku "module.lua" ocenia kod modułu ponownie, ale tworzy nową tabelę w zakresie lokalnym zamiast aktualizować tabelę `m`.
+
+Po drugie, Lua przechowuje w pamięci podręcznej załadowane pliki. Pierwszym razem, gdy plik jest wymagany, jest on dodawany do tabeli [`package.loaded`](/ref/package/#package.loaded), aby można go było szybciej odczytywać podczas kolejnych wymagań. Aby wymusić ponowne odczytanie pliku z dysku, można ustawić wpis pliku na `nil`: `package.loaded["my_module"] = nil`.
+
+Aby prawidłowo ponownie załadować moduł, musisz ponownie załadować moduł, zresetować pamięć podręczną i następnie ponownie załadować wszystkie pliki, które używają modułu. Jest to jednak dalekie od optymalnego.
+
+Zamiast tego możesz rozważyć obejście do użycia w _trakcie rozwoju programu_: umieścić tabelę modułu w zakresie globalnym i spowodować, aby `M` odnosiło się do globalnej tabeli, zamiast tworzyć nową tabelę za każdym razem, gdy plik jest używany ponownie. Ponowne wczytanie modułu zmienia zawartość globalnej tabeli:
+
+```lua
+--- module.lua
+
+-- Zamiast tego użyj "local M = {}" w ostatecznej wersji
+uniquevariable12345 = uniquevariable12345 or {}
+local M = uniquevariable12345
+
+M.value = 4711
+return M
+```
+
+## Moduły a stan
+
+Moduły z zachowaniem stanu przechowują stan wewnętrzny, który jest współdzielony między wszystkimi użytkownikami modułu i można go porównać do singletonów:
+
+```lua
+local M = {}
+
+-- wszyscy użytkownicy modułu będą współdzielić tę tabelę
+local state = {}
+
+function M.do_something(foobar)
+    table.insert(state, foobar)
+end
+
+return M
+```
+
+Z kolei moduł bezstanowy nie przechowuje wewnętrznego stanu. Zamiast tego dostarcza mechanizm do wyeksternalizowania stanu do osobnej tabeli lokalnej dla użytkownika modułu. Oto kilka różnych sposobów, aby to zaimplementować:
+
+Korzystanie z tabeli stanu
+: Być może najprostszym podejściem jest użycie funkcji konstruktora, która zwraca nową tabelę zawierającą tylko stan. Stan jest jawnie przekazywany do modułu jako pierwszy parametr każdej funkcji manipulującej tabelą stanu.
+
+  ```lua
+  local M = {}
+  
+  function M.alter_state(the_state, v)
+      the_state.value = the_state.value + v
+  end
+  
+  function M.get_state(the_state)
+      return the_state.value
+  end
+  
+  function M.new(v)
+      local state = {
+          value = v
+      }
+      return state
+  end
+  
+  return M
+  ```
+  
+  Użyj modułu w ten sposób:
+  
+  ```lua
+  local m = require "main.mymodule"
+  local my_state = m.new(42)
+  m.alter_state(my_state, 1)
+  print(m.get_state(my_state)) --> 43
+  ```
+
+Korzystanie z metatablic
+: Innym podejściem jest użycie funkcji konstruktora, która zwraca nową tabelę ze stanem oraz publiczne funkcje modułu za każdym razem, gdy jest wywoływana:
+
+  ```lua
+  local M = {}
+  
+  function M:alter_state(v)
+      -- self jest dodawane jako pierwszy argument, gdy używa się notacji ":"
+      self.value = self.value + v
+  end
+  
+  function M:get_state()
+      return self.value
+  end
+  
+  function M.new(v)
+      local state = {
+          value = v
+      }
+      return setmetatable(state, { __index = M })
+  end
+  
+  return M
+  ```
+
+  Use the module like this:
+
+  ```lua
+  local m = require "main.mymodule"
+  local my_state = m.new(42)
+  my_state:alter_state(1) -- "my_state" jest dodawane jako pierwszy argument przy użyciu notacji ":"
+  print(my_state:get_state()) --> 43
+  ```
+
+Korzystanie z domknięć
+: Trzeci sposób to zwrócenie domknięcia (ang. closure) zawierającego cały stan i funkcje. Nie trzeba przekazywać instancji jako argumentu (ani jawnie, ani niejawnie, używając operatora dwukropka), jak w przypadku użycia metatablic. Metoda ta jest również nieco szybsza niż korzystanie z metatablic (ang. metatables), ponieważ wywołania funkcji nie muszą przechodzić przez metametodę `__index`, ale każde domknięcie zawiera własną kopię funkcji, co zwiększa zużycie pamięci.
+
+  ```lua
+  local M = {}
+  
+  function M.new(v)
+      local state = {
+          value = v
+      }
+  
+      state.alter_state = function(v)
+          state.value = state.value + v
+      end
+  
+      state.get_state = function()
+          return state.value
+      end
+  
+      return state
+  end
+  
+  return M
+  ```
+
+  Użyj modułu w ten sposób:
+
+  ```lua
+  local m = require "main.mymodule"
+  local my_state = m.new(42)
+  my_state.alter_state(1)
+  print(my_state.get_state()) 
+  ```

+ 18 - 0
docs/pl/manuals/physics-groups.md

@@ -0,0 +1,18 @@
+---
+title: Grupy kolizji w Defoldzie
+brief: Ta instrukcja jak działają grupy i maski silnika fizyki.
+---
+
+# Grupy i maski kolizji
+
+Silnik fizyczny pozwala na grupowanie obiektów fizycznych i określanie, jak powinny ze sobą kolidować. Jest to możliwe dzięki zdefiniowanym grupom kolizji. Dla każdego obiektu kolizji (ang. collision object) tworzysz dwie właściwości (ang. properties), które kontrolują, jak obiekt koliduje z innymi obiektami, a mianowicie *Group* i *Mask*.
+
+Aby kolizja między dwoma obiektami została zarejestrowana, oba obiekty muszą wzajemnie określić grupy, do których należą (określone w *Group*), w swoim polu *Mask*.
+
+![Physics collision group](images/physics/collision_group.png){srcset="images/physics/[email protected] 2x"}
+
+Pole *Mask* może zawierać wiele nazw grup, co pozwala na różne scenariusze interakcji.
+
+## Wykrywanie kolizji
+
+Gdy dwa obiekty kolizji o takich samych grupach i maskach kolidują, silnik fizyczny generuje [wiadomości o kolizji](/manuals/physics-messages), które można wykorzystać w grach do odpowiedniej reakcji na kolizje.

+ 151 - 0
docs/pl/manuals/properties.md

@@ -0,0 +1,151 @@
+---
+title: Właściwości w Defoldzie
+brief: Ta instrukcja opisuje typy właściwości, jak je używać i animować.
+---
+
+# Właściwości
+
+Defold udostępnia właściwości (ang. properties) dla obiektów gry, komponentów oraz węzłów GUI, które można odczytywać, ustawiać i animować. Istnieje kilka rodzajów właściwości:
+
+* Systemowo zdefiniowane transformacje obiektów gry (pozycja, rotacja i skala) oraz specyficzne dla komponentów właściwości (na przykład rozmiar pikseli sprite'a lub masa obiektu kolizyjnego).
+* Właściwości zdefiniowane przez użytkownika w komponentach skryptów Lua (zobacz [dokumentację właściwości skryptów](/manuals/script-properties)).
+* Właściwości węzłów GUI.
+* Stałe shaderów zdefiniowane w shaderach i plikach materiałów (zobacz [dokumentację materiałów](/manuals/material)).
+
+W zależności od miejsca, w którym znajduje się właściwość, dostęp do niej uzyskuje się za pomocą funkcji ogólnej lub funkcji przeznaczonej do właściwości. Wiele z tych właściwości można automatycznie animować. Zaleca się animowanie właściwości za pomocą wbudowanego systemu, zarówno z powodów wydajnościowych, jak i wygody, zamiast manipulować nimi samodzielnie (wewnątrz funkcji `update()`).
+
+Złożone właściwości typu `vector3`, `vector4` lub `quaternion` eksponują również swoje składowe (`x`, `y`, `z` i `w`). Możesz adresować składowe indywidualnie, dodając do nazwy właściwości kropkę (`.`) i nazwę składowej. Na przykład, aby ustawić składową x pozycji obiektu gry:
+
+```lua
+-- Ustaw x pozycji "game_object" na 10.
+go.set("game_object", "position.x", 10)
+```
+
+Funkcje `go.get()`, `go.set()` i `go.animate()` przyjmują jako pierwszy parametr odniesienie oraz identyfikator właściwości jako drugi. Odniesienie identyfikuje obiekt gry (ang. game object) lub komponent (ang. component) i może być ciągiem znaków, haszem lub adresem URL. Adresy URL są szczegółowo omówione w [instrukcji dotyczącej adresowania](/manuals/addressing). Identyfikator właściwości to ciąg znaków lub hash, który określa właściwość.
+
+```lua
+-- Ustaw skalę x komponentu sprite
+local url = msg.url("#sprite")
+local prop = hash("scale.x")
+go.set(url, prop, 2.0)
+```
+
+Dla węzłów GUI, identyfikator węzła jest podawany jako pierwszy parametr do funkcji przeznaczonej do właściwości:
+
+```lua
+-- Pobierz kolor przycisku
+local node = gui.get_node("button")
+local color = gui.get_color(node)
+```
+
+## Właściwości obiektów gry i komponentów
+
+Wszystkie obiekty gry i niektóre typy komponentów mają właściwości, które można odczytywać i modyfikować w czasie rzeczywistym. Wartości te można odczytać za pomocą [`go.get()`](/ref/go#go.get) i zaktualizować za pomocą [`go.set()`](/ref/go#go.set). W zależności od typu wartości właściwości, można animować je za pomocą [`go.animate()`](/ref/go#go.animate). Kilka wybranych właściwości jest przeznaczonych tylko do odczytu.
+
+`get`{.mark}
+: Można je odczytywać za pomocą [`go.get()`](/ref/go#go.get).
+
+`get+set`{.mark}
+: Można je odczytywać za pomocą [`go.get()`](/ref/go#go.get) i aktualizować za pomocą [`go.set()`](/ref/go#go.set). Wartości numeryczne można animować za pomocą [`go.animate()`](/ref/go#go.animate).
+
+*WŁAŚCIWOŚCI OBIEKTÓW GRY*
+
+| Właściwość | Opis                                   | Typ             |                  |
+| ---------- | -------------------------------------- | --------------- | ---------------- |
+| *position* | Lokalna pozycja obiektu gry.           | `vector3`       | `get+set`{.mark} |
+| *rotation* | Lokalna rotacja obiektu gry wyrażona jako kwaternion.    | `quaternion` | `get+set`{.mark} |
+| *euler*    | Lokalna rotacja obiektu gry wyrażona jako kąty Eulera.   | `vector3`    | `get+set`{.mark} |
+| *scale*    | Lokalna nieliniowa skala obiektu gry, wyrażona jako wektor, w którym każdy składnik zawiera mnożnik wzdłuż każdej osi. Przykładowo, aby podwoić rozmiar w osiach x i y, użyj vmath.vector3(2.0, 2.0, 0). | `vector3` | `get+set`{.mark} |
+
+::: sidenote
+Istnieją także konkretne funkcje do pracy z transformacją obiektu gry, takie jak `go.get_position()`, `go.set_position()`, `go.get_rotation()`, `go.set_rotation()`, `go.get_scale()` i `go.set_scale()`.
+:::
+
+*WŁAŚCIWOŚCI KOMPONENTÓW SPRITE*
+
+| Właściwość | Opis                                   | Typ             |                  |
+| ---------- | -------------------------------------- | --------------- | ---------------- |
+| *size*     | Rozmiar sprite'a nieprzeskalowany - jego rozmiar pobierany z atlasu źródłowego. | `vector3` | `get`{.mark} |
+| *image*    | Skrót hasza ścieżki tekstury sprite'a. | `hash`    | `get`{.mark}|
+| *scale*    | Nieliniowa skala sprite'a.             | `vector3` | `get+set`{.mark}|
+| *material* | Materiał używany przez sprite'a.       | `hash`    | `get+set`{.mark}|
+| *cursor*   | Pozycja (między 0 a 1) wskaźnika odtwarzania.   | `number`  | `get+set`{.mark}|
+| *playback_rate* | Ilość klatek na sekundę animacji flipbook. | `number`  | `get+set`{.mark}|
+
+*WŁAŚCIWOŚCI KOMPONENTÓW OBIEKTÓW KOLIZJI*
+
+| Właściwość | Opis                                   | Typ             |                  |
+| ---------- | -------------------------------------- | --------------- | ---------------- |
+| *mass*     | Masa obiektu kolizyji.                 | `number`        | `get`{.mark} |
+| *linear_velocity* | Aktualna prędkość liniowa obiektu kolizyji. | `vector3` | `get`{.mark} |
+| *angular_velocity* | Aktualna prędkość kątowa obiektu kolizyji. | `vector3` | `get`{.mark} |
+| *linear_damping* | Dławienie liniowe obiektu kolizyji. | `vector3`    | `get+set`{.mark} |
+| *angular_damping* | Dławienie kątowe obiektu kolizyji. | `vector3`    | `get+set`{.mark} |
+
+*WŁAŚCIWOŚCI KOMPONENTÓW MODELU 3D*
+
+| Właściwość | Opis                                   | Typ             |                  |
+| ---------- | -------------------------------------- | --------------- | ---------------- |
+| *animation* | Aktualna animacja.                    | `hash`          | `get`{.mark}     |
+| *texture0*  | Skrót hasza ścieżki tekstury modelu.  | `hash` | `get`{.mark}|
+| *cursor*    | Pozycja (między 0 a 1) wskaźnika odtwarzania. | `number`   | `get+set`{.mark} |
+| *playback_rate* | Prędkość odtwarzania animacji. Mnożnik prędkości odtwarzania animacji. | `number` | `get+set`{.mark} |
+| *material* | Materiał używany przez model. | `hash` | `get+set`{.mark}|
+
+*WŁAŚCIWOŚCI KOMPONENTÓW ETYKIETY*
+
+| Właściwość | Opis                                   | Typ             |                  |
+| ---------- | -------------------------------------- | --------------- | ---------------- |
+| *scale*    | Skala etykiety.                        | `vector3`       | `get+set`{.mark} |
+| *color*    | Kolor etykiety.                        | `vector4`       | `get+set`{.mark} |
+| *outline*  | Kolor konturu etykiety.                | `vector4`       | `get+set`{.mark} |
+| *shadow*   | Kolor cienia etykiety.                 | `vector4`       | `get+set`{.mark} |
+| *size*     | Rozmiar etykiety. Rozmiar ogranicza tekst, jeśli jest włączona linia przerwy. | `vector3` | `get+set`{.mark} |
+| *material* | Materiał używany przez etykietę.       | `hash`          | `get+set`{.mark}|
+| *font*     | Czcionka używana przez etykietę.       | `hash`          | `get+set`{.mark}|
+
+## Właściwości węzłów GUI
+
+Węzły GUI również posiadają właściwości, ale są odczytywane i zapisywane za pomocą specjalnych funkcji getterów i setterów z API `gui`. Dla każdej właściwości istnieje funkcja gettera i settera. Istnieje także zestaw stałych zdefiniowanych do użycia jako odniesienie do właściwości podczas animacji. Jeśli potrzebujesz odnosić się do oddzielnych składowych właściwości, musisz używać nazwy ciągu znaków właściwości lub hasza nazwy ciągu znaków.
+
+GUI nodes also contain properties, but they are read and written through special getter and setter functions. For each property there exists one get- and one set- function. There is also a set of constants defined to use as reference to the properties when animating them. If you need to refer to separate property components you have to use the string name of the property, or a hash of the string name.
+
+* `position` (lub `gui.PROP_POSITION`)
+* `rotation` (lub `gui.PROP_ROTATION`)
+* `scale` (lub `gui.PROP_SCALE`)
+* `color` (lub `gui.PROP_COLOR`)
+* `outline` (lub `gui.PROP_OUTLINE`)
+* `shadow` (lub `gui.PROP_SHADOW`)
+* `size` (lub `gui.PROP_SIZE`)
+* `fill_angle` (lub `gui.PROP_FILL_ANGLE`)
+* `inner_radius` (lub `gui.PROP_INNER_RADIUS`)
+* `slice9` (lub `gui.PROP_SLICE9`)
+
+Zauważ, że wszystkie wartości koloru są zakodowane w vector4, gdzie składniki odpowiadają wartościom RGBA:
+
+`x`
+: Składnik koloru czerwonego
+
+`y`
+: Składnik koloru zielonego
+
+`z`
+: Składnik koloru niebieskiego
+
+`w`
+: Składnik alfa
+
+*GUI NODE PROPERTIES*
+
+| Właściwość | Opis                                   | Typ             |                  |
+| ---------- | -------------------------------------- | --------------- | ---------------- |
+| *color*    | Kolor przedniej strony węzła.          | `vector4`       | `gui.get_color()` `gui.set_color()` |
+| *outline*  | Kolor konturu węzła.                   | `vector4`       | `gui.get_outline()` `gui.set_outline()` |
+| *position* | Pozycja węzła.                         | `vector3`       | `gui.get_position()` `gui.set_position()` |
+| *rotation* | Obrót węzła wyrażony w kątach Eulera - stopnie obrócone wokół każdej osi. | `vector3` | `gui.get_rotation()` `gui.set_rotation()` |
+| *scale*    | Skala węzła wyrażona jako mnożnik wzdłuż każdej osi.     | `vector3` |`gui.get_scale()` `gui.set_scale()` |
+| *shadow*   | Kolor cienia węzła.                    | `vector4`       | `gui.get_shadow()` `gui.set_shadow()` |
+| *size*     | Rozmiar węzła niezeskalowany.          | `vector3`       | `gui.get_size()` `gui.set_size()` |
+| *fill_angle*   | Kąt wypełnienia węzła typu pie wyrażony w stopniach przeciwnie do ruchu wskazówek zegara. | `number` | `gui.get_fill_angle()` `gui.set_fill_angle()` |
+| *inner_radius* | Wewnętrzny promień węzła typu pie. | `number`        | `gui.get_inner_radius()` `gui.set_inner_radius()` |
+| *slice9*   | Odległości brzegowe węzła typu slice9. | `vector4`       | `gui.get_slice9()` `gui.set_slice9()` |

+ 137 - 0
docs/pl/manuals/script-properties.md

@@ -0,0 +1,137 @@
+---
+title: Właściwości komponentu skryptu
+brief: Ta instrukcja wyjaśnia, jak dodawać niestandardowe właściwości do komponentów skryptu i jak uzyskiwać do nich dostęp z edytora oraz skryptów uruchamianych podczas działania gry.
+---
+
+# Właściwości skryptów
+
+Właściwości skryptów dostarczają prosty i potężny sposób definiowania i eksponowania niestandardowych właściwości dla określonej instancji obiektu gry. Właściwości skryptów można edytować bezpośrednio w edytorze na określonych instancjach, a ich ustawienia można używać w kodzie do zmiany zachowania obiektu gry. Istnieje wiele przypadków, w których właściwości skryptów są bardzo przydatne:
+
+* Kiedy chcesz zastąpić wartości dla określonych instancji w edytorze, zwiększając tym samym ponowne wykorzystanie skryptu.
+* Kiedy chcesz utworzyć obiekt gry z wartościami początkowymi.
+* Kiedy chcesz animować wartości właściwości.
+* Kiedy chcesz uzyskać dostęp do danych stanu w jednym skrypcie z innego. (Należy pamiętać, że jeśli często uzyskujesz dostęp do właściwości między obiektami, lepiej jest przenieść dane do wspólnej pamięci.)
+
+Powszechnymi przypadkami użycia są ustawianie zdrowia lub prędkości określonego przeciwnika AI, koloru odbierania przedmiotu, atlasu sprite'a lub wiadomości, którą obiekt przycisku ma wysłać po naciśnięciu - i/lub dokąd ma ją wysłać.
+
+## Definicja właściwości skryptu
+
+Właściwości skryptu są dodawane do komponentu skryptu poprzez ich zdefiniowanie za pomocą specjalnej funkcji `go.property()`. Funkcję tę należy używać na najwyższym poziomie - poza jakimikolwiek funkcjami wywoływanymi, takimi jak `init()` i `update()`. Domyślna wartość podana dla właściwości decyduje o rodzaju właściwości: `number`, `boolean`, `hash`, `msg.url`, `vmath.vector3`, `vmath.vector4`, `vmath.quaternion` oraz `resource` (patrz niżej).
+
+```lua
+-- can.script
+-- Definiowanie właściwości skryptu dla zdrowia i celu ataku
+go.property("health", 100)
+go.property("target", msg.url())
+
+function init(self)
+  -- przechowaj początkową pozycję celu.
+  -- self.target to url odnoszący się do innego obiektu.
+  self.target_pos = go.get_position(self.target)
+  ...
+end
+
+function on_message(self, message_id, message, sender)
+  if message_id == hash("take_damage") then
+    -- zmniejsz wartość właściwości health
+    self.health = self.health - message.damage
+    if self.health <= 0 then
+      go.delete()
+    end
+  end
+end
+```
+Dowolna instancja komponentu skryptu utworzona z tego skryptu może następnie ustawiać wartości właściwości.
+
+![Component with properties](images/script-properties/component.png){srcset="images/script-properties/[email protected] 2x"}
+
+Wybierz komponent skryptu w widoku *Outline* w Edytorze, a właściwości pojawią się w widoku *Properties*, pozwalając na ich edycję:
+
+![Properties](images/script-properties/properties.png){srcset="images/script-properties/[email protected] 2x"}
+
+Każda właściwość, która zostanie zastąpiona nową wartością określoną dla danej instancji, jest oznaczana kolorem niebieskim. Kliknij przycisk resetowania obok nazwy właściwości, aby przywrócić wartość domyślną (ustawioną w skrypcie).
+
+## Dostęp do właściwości skryptu
+
+Każda zdefiniowana właściwość skryptu jest dostępna jako przechowywana zmienna w `self`, odniesieniu do instancji skryptu:
+
+```lua
+-- my_script.script
+go.property("my_property", 1)
+
+function update(self, dt)
+  -- Odczyt i zapis właściwości
+  if self.my_property == 1 then
+      self.my_property = 3
+  end
+end
+```
+
+Niestandardowe właściwości skryptu można również uzyskać poprzez funkcje pozyskiwania, ustawiania i animowania, w ten sam sposób, co dowolna inna właściwość:
+
+```lua
+-- another.script
+
+-- zwiększenie "my_property" w "myobject#script" o 1
+local val = go.get("myobject#my_script", "my_property")
+go.set("myobject#my_script", "my_property", val + 1)
+
+-- animowanie "my_property" w "myobject#my_script"
+go.animate("myobject#my_script", "my_property", go.PLAYBACK_LOOP_PINGPONG, 100, go.EASING_LINEAR, 2.0)
+```
+
+## Obiekty utworzone przez fabryki
+
+Jeśli używasz fabryki do tworzenia obiektu gry, możesz ustawić właściwości skryptu podczas tworzenia:
+
+```lua
+local props = { health = 50, target = msg.url("player") }
+local id = factory.create("#can_factory", nil, nil, props)
+
+-- Dostęp do właściwości skryptu utworzonych przez fabrykę
+local url = msg.url(nil, id, "can")
+local can_health = go.get(url, "health")
+```
+
+Podczas tworzenia hierarchii obiektów gry przez `collectionfactory.create()` musisz zestawić identyfikatory obiektów z tabelami właściwości. Są one zbierane w jednej tabeli i przekazywane do funkcji `create()`:
+
+```lua
+local props = {}
+props[hash("/can1")] = { health = 150 }
+props[hash("/can2")] = { health = 250, target = msg.url("player") }
+props[hash("/can3")] = { health = 200 }
+
+local ids = collectionfactory.create("#cangang_factory", nil, nil, props)
+```
+
+Wartości właściwości dostarczane za pomocą `factory.create()` i `collectionfactory.create()` zastępują wartość ustawioną w pliku prototypu, a także wartości domyślne w skrypcie.
+
+Jeśli kilka komponentów skryptu przyczepionych do obiektu gry definiuje tę samą właściwość, każdy komponent zostanie zainicjowany wartością dostarczoną za pomocą `factory.create()` lub `collectionfactory.create()`.
+
+## Właściwości zasobów
+
+Właściwości zasobów definiuje się dokładnie tak samo jak właściwości skryptu dla podstawowych typów danych:
+
+```lua
+go.property("my_atlas", resource.atlas("/atlas.atlas"))
+go.property("my_font", resource.font("/font.font"))
+go.property("my_material", resource.material("/material.material"))
+go.property("my_texture", resource.texture("/texture.png"))
+go.property("my_tile_source", resource.tile_source("/tilesource.tilesource"))
+```
+
+Gdy właściwość zasobu jest zdefiniowana, pojawia się w widoku *Properties* tak samo jak każda inna właściwość skryptu, ale jako pole przeglądarki plików/zasobów:
+
+![Resource Properties](images/script-properties/resource-properties.png)
+
+Dostęp i użycie właściwości zasobu odbywa się za pomocą funkcji `go.get()` lub poprzez odniesienie do instancji skryptu `self` i używając `go.set()`:
+
+```lua
+function init(self)
+  go.set("#sprite", "image", self.my_atlas)
+  go.set("#label", "font", self.my_font)
+  go.set("#sprite", "material", self.my_material)
+  go.set("#model", "texture0", self.my_texture)
+  go.set("#tilemap", "tile_source", self.my_tile_source)
+end
+```

+ 186 - 0
docs/pl/manuals/script.md

@@ -0,0 +1,186 @@
+---
+title: Pisanie logiki gry w skryptach
+brief: Ta instrukcja opisuje szczegóły pisania logiki gry w komponentach typu skrypt.
+---
+
+# Skrypty
+
+Komponent typu skrypt (ang. script) pozwala na tworzenie logiki gry przy użyciu języka programowania Lua. Skrypty dodawane są do obiektów gry dokładnie tak samo jak każdy inny [komponent](/manuals/components), a Defold wykona kod Lua w ramach funkcji cyklu życia silnika.
+
+## Typy skryptów
+
+W Defoldzie występują trzy rodzaje skryptów Lua, z dostępem do różnych bibliotek Defolda.
+
+Skrypty logiczne (.script)
+: Uruchamiane przez komponenty skryptu w obiektach gry. Skrypty logiczne są zazwyczaj używane do kontrolowania obiektów gry i logiki łączącej grę z ładowaniem poziomów, zasadami gry itp. Skrypty logiczne mają dostęp do wszystkich funkcji bibliotek Defold, z wyjątkiem funkcji [GUI](/ref/gui) i [Render](/ref/render).
+
+Skrypty GUI (.gui_script)
+: Uruchamiane przez komponenty GUI i zazwyczaj zawierają logikę wymaganą do wyświetlania elementów interfejsu użytkownika, takich jak wyświetlacze informacji, menu itp. Skrypty GUI mają dostęp do funkcji biblioteki [GUI](/ref/gui).
+
+Skrypty renderowania (.render_script)
+: Uruchamiane przez potok renderowania (rendering pipeline) i zawierają logikę wymaganą do renderowania grafiki aplikacji/gry w każdej klatce. Skrypty renderowania mają dostęp do funkcji biblioteki [Render](/ref/render).
+
+## Wykonywanie skryptów, wywołania zwrotne i "self"
+
+Defold wykonuje skrypty Lua jako część cyklu życia silnika i ujawnia cykl życia przez zestaw predefiniowanych funkcji wywołania zwrotnego. Gdy dodasz komponent skryptu do obiektu gry, skrypt staje się częścią cyklu życia obiektu gry i jego komponentu (lub komponentów). Skrypt jest oceniany w kontekście Lua, gdy jest wczytywany, a następnie silnik wykonuje następujące funkcje i przekazuje odniesienie do bieżącej instancji komponentu skryptu. Możesz użyć tego odniesienia "self" do przechowywania stanu w instancji komponentu.
+
+::: ważne
+"Self" to obiekt typu userdata, który działa jak tabela Lua, ale nie można go przeglądać za pomocą pairs() ani ipairs(), ani drukować za pomocą pprint().
+:::
+
+init(self)
+: Wywoływane, gdy komponent jest inicjowany.
+
+  ```lua
+  function init(self)
+      -- These variables are available through the lifetime of the component instance
+      self.my_var = "something"
+      self.age = 0
+  end
+  ```
+
+final(self)
+: Wywoływane, gdy komponent jest usuwany. Przydatne do celów sprzątania, na przykład, jeśli utworzyłeś obiekty gry, które powinny być usunięte, gdy komponent jest usuwany.
+
+  ```lua
+  function final(self)
+      if self.my_var == "something" then
+          -- wykonaj jakiś kod
+      end
+  end
+
+update(self, dt)
+: Wywoływane raz w każdej klatce. dt zawiera czas delta od ostatniej klatki.
+
+  ```lua
+  function update(self, dt)
+      self.age = self.age + dt -- increase age with the timestep
+  end
+  ```
+
+fixed_update(self, dt)
+: Aktualizacja niezależna od liczby klatek. dt zawiera czas delta od ostatniej aktualizacji. Ta funkcja jest wywoływana, gdy engine.fixed_update_frequency jest włączony (!= 0) i jest przydatna, gdy chcesz manipulować obiektami fizycznymi w regularnych odstępach czasu, aby uzyskać stabilną symulację fizyki, gdy physics.use_fixed_timestep jest włączone w game.project.
+
+  ```lua
+  function fixed_update(self, dt)
+      msg.post("#co", "apply_force", {force = vmath.vector3(1, 0, 0), position = go.get_world_position()})
+  end
+  ```
+
+on_message(self, message_id, message, sender)
+: Gdy wiadomości są wysyłane do komponentu skryptu za pomocą msg.post(), silnik wywołuje tę funkcję komponentu odbiorczego. Dowiedz się więcej na temat przekazywania wiadomości.
+
+  ```lua
+  function on_message(self, message_id, message, sender)
+      if message_id == hash("increase_score") then
+          self.total_score = self.total_score + message.score
+      end
+  end
+```
+
+on_input(self, action_id, action)
+: Jeśli ten komponent uzyskał fokus wejścia (zobacz acquire_input_focus), silnik wywołuje tę funkcję, gdy zostanie zarejestrowane wejście. Dowiedz się więcej na temat obsługi wejścia.'
+
+  ```lua
+  function on_input(self, action_id, action)
+      if action_id == hash("touch") and action.pressed then
+          print("Touch", action.x, action.y)
+      end
+  end
+  ```
+
+on_reload(self)
+: Ta funkcja jest wywoływana, gdy skrypt jest ponownie wczytywany za pomocą funkcji edytora "hot reload" (<kbd>Edytuj ▸ Ponownie załaduj zasób</kbd>). Jest bardzo przydatna do celów debugowania, testowania i dostrojenia. Dowiedz się więcej na temat ponownego ładowania na gorąco.
+
+  ```lua
+  function on_reload(self)
+      print(self.age) -- wyświetl wartość zmiennej self.age
+  end
+  ```
+
+## Logika reaktywna
+
+Obiekt gry z komponentem skryptu implementuje pewną logikę. Często zależy ona od pewnego czynnika zewnętrznego. Przykładowo sztuczna inteligencja przeciwnika może reagować na gracza znajdującego się w określonym promieniu od przeciwnika, drzwi mogą odblokować się i otworzyć w wyniku interakcji gracza itp.
+
+Funkcja `update()` pozwala na implementację złożonych zachowań zdefiniowanych jako automat stanów, który działa w każdej klatce - czasami jest to odpowiednie podejście. Jednak z każdym wywołaniem `update()` wiąże się pewien koszt. Jeśli naprawdę nie potrzebujesz tej funkcji, powinieneś ją usunąć i spróbować budować swoją logikę w sposób reaktywny. Oczekiwanie biernie na jakąś wiadomość, która wyzwoli reakcję, jest "tańsze" niż aktywne przeszukiwanie świata gry w poszukiwaniu danych do analizy. Ponadto rozwiązanie danego problemu w sposób reaktywny zazwyczaj prowadzi do czystszego i bardziej stabilnego projektu i jego implementacji.
+
+Przyjrzyjmy się konkretnemu przykładowi. Załóżmy, że chcesz, aby komponent skryptu wysłał wiadomość 2 sekundy po inicjalizacji. Następnie powinien oczekiwać na określoną wiadomość odpowiedzi i po jej otrzymaniu, wysłać inną wiadomość 5 sekund później. Niereaktywny kod dla tego wyglądałby mniej więcej tak:
+
+```lua
+function init(self)
+    -- Licznik czasu.
+    self.counter = 0
+    -- Potrzebujemy tego do śledzenia naszego stanu.
+    self.state = "first"
+end
+
+function update(self, dt)
+    self.counter = self.counter + dt
+    if self.counter >= 2.0 and self.state == "first" then
+        -- wysłanie wiadomości po 2 sekundach
+        msg.post("some_object", "some_message")
+        self.state = "waiting"
+    end
+    if self.counter >= 5.0 and self.state == "second" then
+        -- wysłanie wiadomości 5 sekund po otrzymaniu "response"
+        msg.post("another_object", "another_message")
+        -- Wyczyszczenie stanu, aby nie wykonać tego bloku stanu ponownie.
+        self.state = nil
+    end
+end
+
+function on_message(self, message_id, message, sender)
+    if message_id == hash("response") then
+        -- Stan "pierwszy" zakończony, wchodzi kolejny
+        self.state = "second"
+        -- Wyzerowanie licznika
+        self.counter = 0
+    end
+end
+```
+
+Even in this quite simple case we get fairly tangled up logic. It's possible to make this look better with the help of coroutines in a module (see below), but let's instead try to make this reactive and use a built-in timing mechanism.
+
+```lua
+local function send_first()
+	msg.post("some_object", "some_message")
+end
+
+function init(self)
+	-- Poczekaj 2 s, a następnie wywołaj send_first()
+	timer.delay(2, false, send_first)
+end
+
+local function send_second()
+	msg.post("another_object", "another_message")
+end
+
+function on_message(self, message_id, message, sender)
+	if message_id == hash("response") then
+		-- Poczekaj 5 s, a następnie wywołaj send_second()
+		timer.delay(5, false, send_second)
+	end
+end
+```
+
+To jest bardziej przejrzyste i łatwiejsze do śledzenia. Pozbywamy się wewnętrznych zmiennych stanu, które często są trudne do śledzenia przez logikę - i które mogą prowadzić do subtelnych błędów. Dodatkowo całkowicie rezygnujemy z funkcji `update()`. Zwalnia to silnik z wywoływania naszego skryptu 60 razy na sekundę.
+
+## Preprocessing
+Przetwarzanie wstępne, czyli preprocessing wykrozystuje preprocesor Lua i specjalne znaczniki, aby warunkowo dołączać kod w zależności od wariantu budowy. Przykład:
+
+```lua
+-- Użyj jednego z tych słów kluczowych: RELEASE, DEBUG lub HEADLESS
+--#IF DEBUG
+local lives_num = 999
+--#ELSE 
+local lives_num = 3
+--#ENDIF
+```
+
+Preprocesor jest dostępny jako rozszerzenie budowania. Dowiedz się więcej na temat sposobu instalacji i użycia na [stronie rozszerzenia na GitHubie](https://github.com/defold/extension-lua-preprocessor).
+
+## Wsparcie Edytora
+
+Edytor Defold obsługuje edycję skryptów Lua z kolorowaniem składni i autouzupełnianiem. Aby wyświetlić nazwy funkcji Defold, naciśnij <kbd>Ctrl</kbd>+<kbd>Spacja</kbd>, aby wyświetlić listę funkcji pasujących do tego, co wpisujesz.
+
+![Automatyczne uzupełnianie](images/script/completion.png){srcset="images/script/[email protected] 2x"}