RedziQ

Zasłużony
  • Zawartość

    1654
  • Rejestracja

  • Wygrane w rankingu

    17

Ostatnia wygrana RedziQ w Rankingu w dniu 25 Czerwiec

RedziQ posiada najczęściej lubianą zawartość!

Reputacja

499 Lubiany

O RedziQ

  • Tytuł
    P

Informacje

  • Płeć
    Mężczyzna
  • Nick z minecraft
    RedziQ

Ostatnie wizyty

11289 wyświetleń profilu
  1. = PODSUMOWANIE SERII = Bardzo się cieszę, jeśli dotrwałeś/dotrwałaś do tego wpisu, czyli do końca pierwszej serii z tworzenia gier. Mam nadzieję, że Twoja gra działa i ma się dobrze, a ty sam/sama jesteś z siebie zadowolona, że czegoś się nauczyłaś/nauczyłeś (taką mam nadzieję). Możesz pochwalić się usprawnieniami, jakie dodałeś/dodałaś do swojej gry, jeśli takowe zrobiłaś/zrobiłeś. Jeśli interesują Cię dalsze tego typu tematy – w komentarzu możesz zasugerować, jakie funkcje powinienem dodać do tej gry, bądź o jakiej grze wykonać następną serię. Dzięki za przeczytanie i do usłyszenia!
  2. 1. Nick: Pandera 2. Tematyka budowli: Moje wymarzone wakacje - "Wyspa na oceanie" 3. ID działki (dostępne na tabliczce, na jej rogu po prawej od respu): -133;95
  3. RedziQ

    1.10 - Kolorowanie gry

    = KOLOROWANIE GRY = Dziś trochę luźniejszy wpis, pokolorujemy sobie dziś naszą grę. Dodawanie nowego koloru Zanim zaczniemy rzeczywiście pisać kod, na początek zmieńmy kolor wszystkich obiektów (paletek i piłki) na „inherit”, w wolnym tłumaczeniu „odziedzicz”, czyli dany obiekt będzie podobnego koloru jak tło, na którym się znajduje. Zanim zaczniemy cokolwiek z nim działać, zróbmy sobie nową funkcję – do szybkiego tworzenia nowych prostokątów. Możesz spróbować zrobić ją sama/sam, na podstawie kodu z „renderGame”. Tutaj moja propozycja: Jak widać, po prostu dodaliśmy możliwość tworzenia wypełnionego prostokąta. Jeśli utworzyłeś/utworzyłaś tę funkcję, możesz przetestować jej działanie zamieniając fragment kodu z „renderGame”, tak jak poniżej. Jeśli wszystko na stronie wyświetla się prawidłowo – Twoja nowa funkcja działa bez zarzutu. Teraz, możesz sobie wybrać jakieś dwa ładne kolory, ja postawie na te poniżej. Koncept jest taki, by pokolorować połowy na te dwa kolory. Zatem za pomocą nowo utworzonej funkcji, możemy to zrobić. Możesz spróbować zrobić to najpierw samemu. Oczywiście musimy zrobić to pod wywołaniem „clearRect”, czyli po wyczyszczeniu ekranu, a przed narysowaniem czegokolwiek innego. W przeciwnym razie, moglibyśmy zasłonić tłem jakiś element. Poniżej rozwiązanie Teraz dodajmy przerywaną linię na środku Wyjaśnię pokrótce, co służy czemu. Najpierw ustawiamy kolor pogrubienia („strokeStyle”) Następnie ustawiamy szerokość linii (jak gruba jest linia) Rozpoczynamy nowy kształt (ścieżkę) Zaznaczamy, że linia jest przerywana (każdy fragment ma jest długi na 6 pikseli, ma 12 pikseli marginesu) Rozpoczynamy linię na górze środka ekranu („moveTo”) Rysujemy linię do dołu środka ekranu („lineTo”) Kończymy tworzenie kształtu (ścieżki) Pogrubiamy utworzony kształt W ten sposób otrzymujemy ładną, przerywaną linię na środku ekranu, która symbolizuje siatkę. Założenie jest takie, tak jak już mówiłem, żeby kolor zmieniał się w zależności od tego, gdzie jest dany obiekt. Dlatego stwórz najpierw nową zmienną, która będzie przechowywać zamieniony kolor, a następnie stwórz „ifa”, który sprawdza, czy kolor obiektu jest ustawiony na „inherit”. Jeśli jest, sprawdź w której połowie znajduje się obiekt i ustaw na tej podstawie lekko przyciemniony kolor połowy. Cały kod powinien znaleźć się w pętli „for” funkcji „renderGame”, oczywiście już poniżej definicji zmiennej „object”. (Poniżej znajdują się kody moich przyciemnionych kolorów). Poniżej rozwiązanie, które ja zastosowałem przy realizacji powyższego konceptu. Zanim zaczniesz testować, powinieneś zmienić jeszcze w kodzie odpowiedzialnym za rysowanie odpowiednich kształtów zmienną koloru, z „object.color” na nasz podmieniony kolor „color” W ten sposób stworzyliśmy dość ładną oprawę graficzną dla naszej gry. Jeśli Ci się nie podoba, zawsze możesz usunąć kod odpowiedzialny za nią. Nowo powstały błąd W ostatnich wpisach napisaliśmy kod na odbicia piłki od ścian i paletek. Kod generuje czasem jeden błąd, gdy podczas odbicia nowy kąt lotu piłki będzie bliski 90° lub 270°, piłka blokuje się w paletce. Wynika to z tego, że zanim wykryjemy kolizję, piłka zdąży lekko wbić się w paletkę i jeśli kąt będzie zbyt mały (czyt. Zbyt bliski 90° lub 270°) to zostanie wykryta ponowna kolizja, co spowoduje zapętlenie się tworzenia kolizji. Naprawić możemy to w jeden prosty sposób – wystarczy utworzyć swego rodzaju stoper, który pozwoli na ponowne odbicie dopiero po jakimś czasie. Z racji tego, że może zdarzyć się sytuacja, w której bardzo szybko po sobie nastąpi kolizja z paletką a następnie ze ścianą, trzeba zrobić dwa takie stopery – jeden dla ścian, drugi dla paletek. Ja nazwę je odpowiednio „bDisablePlayers” („ballDisablePlayers” – w wolnym tłumaczeniu: wyłącz kolizję piłki z graczami) i „bDisableWalls” („ballDisableWalls” – w wolnym tłumaczeniu: wyłącz kolizję piłki ze ścianami). Oczywiście, jak zawsze, nazewnictwo dowolne. Powinniśmy je zdefiniować natomiast na samej górze skryptu i przypisać im wartość początkową równą zeru. W funkcji fizyki „updatePhysics” spróbuj zmodyfikować kod detekcji kolizji z obiektami tak, by działał tylko wtedy, gdy odpowiedni stoper jest równy zeru, a przy kolizji z obiektem – odpowiedni stoper powinien być ustawiany na wartość 5. Podczas każdego wywołania „updatePhysics” powinieneś/powinnaś sprawdzić także, czy oba stopery są równe zeru i jeśli nie są – odjąć od nich 1. Poniżej proponowane przeze mnie rozwiązania. Definiowanie „stoperów” Odejmowanie 1 od „stoperów” – kod osadzony oczywiście w „updatePhysics”. Detekcja kolizji z uwzględnieniem „stoperów” (na końcu „ifa” widać „bDisablePlayers” i „bDisableWalls”) i resetowanie ich w przypadku wykrycia „zakwalifikowanej” kolizji. Oczywiście stoperów nie musimy resetować w przypadku kolizji z lewą i prawą ścianą, gdyż wtedy i tak piłka zatrzymuje się wraz z całą grą.
  4. = KOLIZJE Z PALETKAMI = Wykrywanie kolizji z paletkami Podczas sprawdzania kolizji ze ścianami wystarczyło porównać tylko jedną zmienną w odpowiedni sposób, by uzyskać odpowiedź, czy piłka koliduje ze ścianą czy też nie. Problemem w przypadku paletek może być fakt, że rzeczywiście trzeba sprawdzić, czy piłka znajduje się w ich polu, więc jak to zrobić? Więc tak, na powyższym obrazku możemy zobaczyć jedną z paletek. Teraz, by sprawdzić czy koliduje z nią piłka, musimy wykonać 4 kroki. Najpierw sprawdzamy, czy piłka znajduje się po lewej stronie paletki. (Paletka zostawiona, byś mógł/mogła zobaczyć, jak dokładniej to trzeba zrobić. Należy zaznaczyć, że mówiąc „czy piłka znajduje się po lewej stronie paletki”, sprawdzamy teren od jej skrajnie prawego (czyli przeciwnego) boku, a nie skrajnie lewego, jak normalnie interpretujemy to zdanie. Dobrze jest to widoczne na rysunku, gdzie sama paletka też wchodzi w skład sprawdzanego terenu. Następnie sprawdzamy kolejny teren – prawą stronę paletki. Jeśli piłka znajduje się w obu naraz, to znaczy, że znajduje się ona gdzieś w tym ciemnozielonym pasku. Teraz dokładamy sprawdzenie, czy piłka znajduje się powyżej paletki. Jeśli piłka znajdowała się w ciemno-zielonym obszarze (co sprawdziliśmy w poprzednich krokach) i znajduje się w obecnie sprawdzanym obszarze, to musi znajdować się w tym jeszcze bardziej ciemno-zielonym obszarze. Ostatecznie sprawdzamy, czy piłka znajduje się poniżej paletki. Jeśli tak – musi znajdować się w brązowym polu na środku, czyli w naszej paletce. Co za tym idzie – musi z nią kolidować, więc osiągnęliśmy nasz cel. Warto zauważyć, że mamy do wyboru dwie drogi: Sprawdzamy, czy środek piłki jest w paletce Sprawdzamy, czy krawędź piłki jest w paletce O ile mogłoby się wydawać, że odpowiedź jest oczywista – druga opcja jest lepsza, tak musimy mieć na uwadze, że dość ciężko jest sprawdzić czy jakaś część koła znajduje się w podanym terenie, więc będziemy musieli wtedy zrobić kwadrat z koła. Ja osobiście wybrałem tę drugą opcję, gdyż działa ona na korzyść obu graczy. Teraz wystarczy przepisać ten sposób na odpowiedni kod. Możesz spróbować zrobić to samemu. Jeśli nie pamiętasz, jak łączyło się wiele porównań ze sobą w jednym „ifie” (podpowiadam: „&&”), zobacz do wpisu 1.7. Poniżej rozwiązanie zaproponowane przeze mnie. Jak możesz zauważyć, zrobiłem sobie kilka dodatkowych zmiennych, gdyż w sprawdzaniu kolizji z paletkami używałem ich dość często. Dodatkowo sam kod zyskał na czytelności. W przypadku obu paletek możesz zauważyć, że sprawdzane są kolejno następujące tereny: Po lewej od paletki Po prawej od paletki Powyżej paletki Poniżej paletki Oczywiście teren uwzględnia też samą długość i szerokość paletki, o czym mówiłem wcześniej. Możesz spytać, dlaczego teraz odejmujemy od 180, a nie od 360 i dlaczego nie odejmujemy po prostu kierunku? W skrócie odejmujemy od 180, gdyż teraz odbijamy od pionowej powierzchni, a nie od poziomej. (Oba kierunki leżą w tej samej „części” koła przedstawionego wyżej; albo w górnej części, albo w dolnej). Jak widzisz, dodałem dodatkowy kawałek kodu, który manipuluje nowym kierunkiem lotu piłki. Co dokładniej robi? Sprawdza, w którą część paletki uderzyła dokładniej piłka. Jeśli uderzyła powyżej połowy paletki, piłka poleci bardziej w górę, jeśli uderzyła w dolną – bardziej w dół. Dodaje to możliwość zmiany kierunku przez gracza, co daje bardziej ciekawą rozgrywkę i otwiera nowe możliwości. Możesz zmienić tą „2” na końcu na mniejszą, jeśli chcesz uzyskać bardziej widoczny efekt, bądź na większą, jeśli chcesz, żeby efekt był mniejszy. Możesz też całkowicie wywalić ten kod, jeśli uważasz go za zbędny. Po kilku próbach ustaliłem, że z „2” gra się najlepiej, ale przetestuj i sprawdź sam/sama.
  5. = RUCH PIŁKI I ODBICIA OD ŚCIAN = Ruch teoretyczny piłki Zanim zacznę Ci tłumaczyć, jak będziemy przemieszczać piłkę oraz ją odbijać, najpierw spójrzmy na jej dostępne parametry. To co rzeczywiście może nam się przydać w przypadku ruchu piłki, to oczywiście „position” - Obecna pozycja, która zawiera współrzędne X i Y „velocity” - Prędkość (a bardziej „szybkość”, ale mniejsza..) „direction” - Czyli obecny kierunek lotu piłki, zapisany w postaci kąta (w stopniach) Reszta na ten czas jest nam zbędna. Na początku, nasza piłka będzie leciała z prędkością początkową zdefiniowaną w „BALL_VELOCITY_START”, w kierunku 0°, czyli w prawo. Poniżej rozpiska dla innych kątów, wraz z liczbami, które powinniśmy dodać do obu współrzędnych; 0° - prawo (x: 1, y: 0), 90° - dół (x: 0, y: 1), 180° - lewo (x: -1, y: 0), 270° - góra (x: 0, y: -1), I o ile dla tych kątów łatwo jest nam wyliczyć odpowiednie liczby, tak na przykład dla kąta 45° nie będzie nam tak łatwo. Możesz powiedzieć, że to pewnie (x: 0.5, y: 0.5), ale okazuje się, że nie. Co prawda piłka będzie lecieć w dobrą stronę, ale będzie lecieć o ~30% wolniej, niż leciałaby w przypadku kątów podanych powyżej. Prawidłowa odpowiedź to… ~(x: 0.71, y: 0.71). Jak zatem to wyliczyć? Z pomocą przychodzą nam funkcje trygonometryczne, a dokładniej mówiąc – cosinus i sinus. Potrafią one wyliczyć współrzędne X i Y na podstawie kąta. Ściślej mówiąc, Cosinus odpowiada za współrzędną X, a Sinus za współrzędną Y. Pojawia się jednak pewien problem, funkcje te używają radianów jako jednostki miary kąta, dlatego zanim ich użyjemy, musimy przekształcić stopnie na radiany, mnożąc daną ilość stopni przez stałą Pi i dzieląc przez 180. Dzięki temu możemy wyliczyć odpowiednie liczby, które powinniśmy dodać, jeśli piłka porusza się w określonym kierunku. Funkcji „sin” i „cos” oraz stałej „Pi” możemy użyć w kodzie za pomocą wywoływania funkcji „Math.sin” oraz „Math.cos”, a stałą Pi z dokładnym przybliżeniem możemy uzyskać za pomocą zmiennej „Math.PI”. Do parametrów piłki możemy odwoływać się za pomocą zmiennej „objects[ "ball" ]”. Teraz wystarczy przepisać to na kod. Możesz spróbować zrobić to samodzielnie, przypomnę tylko, że takie rzeczy powinniśmy zapisywać w funkcji odpowiedzialnej za fizykę. Poniżej prawidłowe rozwiązanie. Jak widać, znów trzeba tu pomnożyć samą prędkość razy „delta”, zgodnie z wzorem fizycznym. Jeśli zapiszesz swój plik i odświeżysz stronę, powinnaś/powinieneś zobaczyć piłkę lecącą w prawo. Jest jednak jeden zasadniczy problem związany z jej lotem – przenika przez wszystko, co napotka, a tak nie powinno być! Kolizje piłki możemy rozdzielić na dwa rodzaje Kolizje z paletkami Kolizje ze ścianami – te również możemy podzielić na kolejne dwa rodzaje; Ze ścianą górną i ścianą dolną, czyli takie, które normalnie odbijają piłkę Ze ścianą lewą i prawą, czyli takie, które zatrzymują piłkę i powodują koniec rundy Dziś zajmiemy się tylko kolizjami ze ścianami, gdyż kolizje z paletkami są trochę bardziej skomplikowane, niż się wydaje. Odbicia od ścian (niektórych) Zgodnie z tym co napisałem w powyższej liście, napiszemy system odbić od ścian tylko dla dwóch – górnej i dolnej. Kolizja z prawą i lewą ścianą automatycznie powoduje koniec rundy, przez co nie musimy już martwić się o odbijanie piłki od nich. Możesz spróbować napisać detekcję kolizji ze ścianami samodzielnie, jednak pamiętaj o kilku rzeczach; Pozycja piłki „rzeczywiście” jest w jej środku, a nie tak jak ma to miejsce w przypadku prostokątów – w lewym górnym rogu Ściany znajdują się na następujących pozycjach; Lewa: x = 0 Prawa: x = canvas.width Górna: y = 0 Dolna: y = canvas.height „canvas.width” i „canvas.height” to oczywiście szerokość i długość ekranu. Poniżej znajdziesz rozwiązanie. Jak możesz zauważyć, do obecnej pozycji piłki w zależności od ściany odejmuję bądź dodaję jej promień, dlaczego tak? Jeśli będziemy wykrywać kolizję bez dodawania i odejmowania jej promienia, to będzie ona wykrywana dopiero wtedy, gdy już połowa piłki będzie w ścianie, bo porównujemy pozycje X i Y, które w przypadku piłki – są w jej środku. (Obrazek lewy). Dlatego my – sprytne byki – gdy chcemy sprawdzić, czy nastąpiła kolizja, najpierw zmieniamy natychmiastowo jej pozycję, by była w innym miejscu, niż to rzeczywiste (z tego prawego obrazka robimy na chwilę ten lewy), by sprawdzić, czy kolizja nastąpiła, a następnie cofamy ją z powrotem i wysuwamy wnioski. To takie wytłumaczenie, by sobie zobrazować, jak to działa. W rzeczywistości nie przenosimy piłki, a tylko jej pozycję, a przesuwamy ją zgodnie z obrazkiem – o jej promień. Dobrze, ale kiedy odejmujemy ten promień, a kiedy go dodajemy? Odejmujemy dla ścian lewej i górnej, a dodajemy dla prawej i dolnej. Dlaczego akurat tak? Zauważmy, że jeśli poruszamy się w lewo bądź w górę, nasze współrzędne maleją, a jeśli w prawo bądź w dół – rosną. Jest to związane z budową układu współrzędnych (z tym, że lewy górny róg to x: 0, y: 0). Podczas kolizji lewej lub prawej ściany z piłką – kod podczas niej wykonywany wydaje się dość oczywisty – ustawiamy prędkość na zero, czyli piłka nie będzie się poruszać – i dobrze, bo wtedy będziemy chcieli wyświetlić „GameOver” (ale to w przyszłym wpisie). W przypadku górnej i dolnej ściany – nie jest już tak kolorowo – dlaczego odejmujemy od 360 naszego obecnego kierunku? No.. obrazek może na początku przestraszyć, ale zaraz sobie go na spokojnie wytłumaczymy. Po lewej możemy zobaczyć sytuacje kolizji ze ścianą, żółta strzałka to nasz stary kierunek, a zielona to kierunek w jakim powinna odbić się piłka. Na tym po lewej możemy zauważyć jeszcze dwa identyczne kąty Alfa, które oznajmiają mniej więcej tyle, że kąt między kierunkiem początkowym a linią prostopadłą do ściany jest taki sam jak kąt między prostopadłą do ściany a nowym kierunkiem. Rysunek po prawej to przekształcony rysunek po lewej. Znamy wartość kąta Beta, czyli naszego starego kierunku, a chcemy poznać kąt Alfa, czyli nowego kierunku. Na obrazku ładnie jest pokazane, że kąt Beta i kąt Alfa razem tworzą pełne koło, czyli 360°. Możemy więc ułożyć równanie; 360° = β + α A następnie je przekształcić tak, by uzyskać wartość kąta Alfa; 360° - β = α α = 360° - β Stąd wzięło się nasze 360 – kierunek lotu. Teraz należałoby sprawdzić czy wszystko działa. Ustaw więc kierunek początkowy piłki (w funkcji „init”) na 300 i sprawdź, czy piłka się odbija i jeśli tak, to czy robi to w dobry sposób.
  6. = PORUSZANIE OBIEMA PALETKAMI = Zdarzenia (Events) Zdarzenia, bądź może raczej – wydarzenia, są dość proste do zrozumienia. Do „prawdziwych” wydarzeń (np. koncert) możemy się zapisać i zostaniemy poinformowani, gdy wydarzenie za niedługo się rozpocznie. Podobnie jest w JavaScriptcie, z tym, że tym razem nie zapisujemy siebie, a funkcje, które napisaliśmy. Gdy wydarzy się zapisane zdarzenie, funkcja zostanie wywołana wraz z argumentem, który będzie zawierał informacje o tym zdarzeniu. Zdarzeń w JavaScriptcie jest cała masa, jednak my skupimy się tylko na dwóch – „keyup” i „keydown”, które przydadzą nam się do kontrolowania ruchu paletek. „keydown” – zostaje wywołany, gdy klawisz zostaje wciśnięty „keyup” – zostaje wywołany, gdy klawisz powraca na swoją normalną pozycję po wciśnięciu W obu przypadkach dostajemy informację jaki klawisz został naciśnięty, więc wystarczyłoby zrobić nową funkcję, zapisać ją na „keydown” i zaktualizować pozycję paletki, prawda? nie Dlaczego? Zdarzenie „keydown” woła funkcje do niego zapisane tylko raz – gdy klawisz zostaje wciśnięty, więc jeśli naciśniemy i przytrzymamy klawisz, powiedzmy, „w”, to poruszymy się tylko o kilka pikseli w górę. Możesz powiedzieć: „Przecież to nie problem, o to właśnie chodziło!” No właśnie o to raczej nie chodziło, zauważ, że napisałem, że jeśli wciśniemy i przytrzymamy ten klawisz. Jeśli chcielibyśmy poruszyć się z jednego końca ekranu do drugiego, to musielibyśmy cały czas wciskać i puszczać dany klawisz, a przecież nie o to chodzi! Jeśli przytrzymamy klawisz, to powinniśmy poruszać się tak długo, aż go nie puścimy! Dodatkowym argumentem może być fakt, że jeśli mówimy o zmianie pozycji, to jest to zagadnienie bezpośrednio związane z fizyką, a więc przeliczanie pozycji powinno wykonywać się w funkcji odpowiedzialnej za fizykę – „updatePhysics”, gdyż w niej mamy do dyspozycji jedną z ważnych zmiennych – czas. Dlatego podałem tu również zdarzenie „keyup”, które bardzo ułatwi nam sprawę, choć póki co na to nie wygląda. Jak zrealizujemy poruszanie się paletek? Najlepiej będzie utworzyć nowe zmienne, które będą przechowywać informacje o stanie pożądanego klawisza. Jeśli mówimy o stanie, to oczywiście chodzi tu o typ zmiennych Bool (stan), czyli „true” (prawda) albo „false” (fałsz). Stworzymy dwie funkcje, które zapiszemy do zdarzeń „keydown” i „keyup”. Funkcja zapisana do „keydown” będzie odpowiedzialna za zmianę stanu zmiennej klawisza na „true” (prawdę, czyli że jest wciśnięty), natomiast funkcja przypisana do „keyup” będzie zmieniać tę samą zmienną na „false” (fałsz, czyli że niewciśnięty). Następnie, w funkcji odpowiedzialnej za fizykę będziemy sprawdzać które klawisze są wciśnięte i na podstawie tej informacji odpowiednio zmieniać pozycję paletek. Przetwarzanie przemyśleń na kod Zacznij od wybrania klawiszy jakimi będą posługiwać się gracze. Ja postawiłem na „w” i „s” dla gracza pierwszego, a gracz drugi będzie używał strzałki w górę i strzałki w dół. Następnie utwórz zmienne dla każdego klawisza, który wybrałeś/wybrałaś. Najlepiej wsadź je wszystkie w jeden obiekt, by je zgrupować i oswoić się jeszcze bardziej z obiektami. Ich wartość najlepiej ustawić na „false”, gdyż zakładamy, że podczas włączania gry gracz ma wszystkie klawisze w pozycji początkowej. Teraz musimy utworzyć dwie nowe funkcje w kodzie, jedną do przetwarzania zdarzeń „keydown” i drugą do „keyup”. Ja zwykłem nazywać je według zasady „on” + nazwa zdarzenia, by nie zapomnieć po co ich potrzebuje. Czyli; „onKeyUp” i „onKeyDown”. Pamiętaj, że funkcja musi przyjmować jeden argument – informacje o zdarzeniu, więc musisz zadeklarować jej go zadeklarować. Ja zazwyczaj nazywam ten argument „event”. Gdy utworzysz już obie funkcje, możesz przejść teraz do funkcji „init” i zapisać Twoje funkcje do odpowiednich wydarzeń. Możesz to zrobić za pomocą funkcji „document.addEventListener( „nazwa_zdarzenia”, nazwa_funkcji ); ” Poniżej przykład, jak to powinno wyglądać. Teraz, w funkcjach odpowiedzialnych za te zdarzenia spróbuj sam napisać kod, który sprawdzi, jaki klawisz został naciśnięty, a następnie zmieni odpowiednią zmienną. Podpowiem, że za pomocą zmiennej „event.key” możesz sprawdzić znak wciśniętego klawisza. Jeśli nie wiesz, co zawiera „event.key” w przypadku któregoś z wybranych klawiszy, możesz wyświetlić jego zawartość na konsoli za pomocą funkcji „console.log( event.key );”, bądź na stronie https://keycode.info/ , po wciśnięciu wybranego klawisza. Poniżej rozwiązanie dla jednej z funkcji. Druga funkcja będzie wyglądać tak samo, z tym, że będzie zmieniać wartość zmiennych na stan „false”, zamiast „true”. Dodatkowo, możesz zauważyć, że zastosowałem tutaj słówka kluczowe „return” – głównie po to, żeby bardziej zoptymalizować kod – być może pamiętasz ze „wstępu do JavaScriptu”, że komputer po napotkaniu słówka „return” na swojej drodze, po prostu zwróci wartość, która jest za nim podana, a następnie po prostu porzuci resztę kodu – nie wykona go. Jest to dość dobre rozwiązanie, przecież jeśli sprawdziliśmy i wiemy, że „event.key” to w tym momencie na przykład „s”, to nie musimy już potem sprawdzać, czy jest on innym klawiszem, bo nie jest, jeśli jest klawiszem „s”, prawda? Poruszanie paletkami Przejdźmy teraz do samego kodu odpowiedzialnego za zmianę położenia paletek. W Pongu, gracz może poruszać paletkami tylko w górę i w dół, więc powinniśmy aktualizować tylko współrzędną Y. Jak już wcześniej wspomniałem, powinniśmy to zrobić w funkcji „updatePhysics”, gdyż tam mamy dostęp do zmiennej z czasem. Spróbuj utworzyć samemu kod poruszający paletką jednego z graczy w dół i w górę, w zależności od tego, jaki klawisz jest obecnie wciśnięty. Obecna współrzędna Y gracza pierwszego jest przechowywana w zmiennej „objects[ "paddle_1" ].position.y”. Zauważ, że gdy dodasz cokolwiek do tej pozycji, paletka poruszy się w dół, a gdy odejmiesz – poruszy się w górę. Należy zaznaczyć, że nie możesz po prostu napisać „objects[ "paddle_1" ].position.y + 1”, ponieważ to jest po prostu wyrażenie matematyczne, które co prawda zwróci nową pozycję, ale ta pozycja nie zostanie do niczego przypisana. Spróbuj nad tym pomyśleć i znajdź sposób, by poruszyć paletką. Poniżej rozwiązanie dla jednej z paletek. Jak widzisz, znów utworzyłem nową stałą, o nazwie „PADDLE_SPEED”, czyli prędkość poruszania się paletki, u siebie ustawiłem ją na wartość 380. Możesz także zauważyć, że mnożę tę prędkość razy wartość zmiennej „delta”. Dlaczego tak? Ano, żeby pozycja paletki uległa zmianie, musi ona pokonać jakąś drogę, natomiast wzór na drogę wymaga pomnożenia prędkości przez czas i to właśnie robimy. Dodatkowo możesz tu zauważyć dwa nowe operatory; „+=”, który oznacza dodanie wartości po prawej stronie do zmiennej po lewej stronie. „-=”, który oznacza odjęcia wartości po prawej stronie od zmiennej po lewej stronie Te operatory skracają nam ilość napisanego kodu. Poniższe dwie linie kodu, ukazane na obrazku są ze sobą równoznaczne. Jeśli jeszcze tego nie zrobiłaś/zrobiłeś, spróbuj napisać podobny kod do sterowania również drugą paletką. Poniżej rozwiązanie. Sprawdź, czy napisany przez siebie kod działa, jeśli tak, możesz wyczekiwać kolejnego wpisu, jeśli nie, spróbuj znaleźć różnice między swoim kodem, a tym zaproponowanym przeze mnie i wysuń wnioski – postaraj się przerobić swój kod tak, żeby działał. Nowy problem Jeśli pograsz chwilę dłużej w grę, możesz zauważyć, że możesz wyjechać paletkami poza zasięg ekranu. To na pewno nie jest porządany efekt w naszej grze, więc musimy naprawić ten błąd. Jak? Dodamy po prostu sprawdzenie, czy paletka nie wyjeżdża czasem za ekran. Wprowadzę tutaj nowy operator – podwójny ampersand („&&”), który pozwala łączyć wiele warunków. Jeśli użyjesz „&&” w „ifie”, to kod w nim wykona się tylko wtedy, jeśli oba warunki (po lewej i prawej stronie „&&”) będą prawdziwe. Możesz za pomocą tej wiedzy spróbować zrobić odpowiedni „if”. Poniżej moje rozwiązanie problemu.
  7. RedziQ

    1.6 - Obiekty i ich wyświetlanie

    Jak wspomniałem w 1.3, wszystkie następne wpisy (w tym i ten) będą dotyczyły pliku z rozszerzeniem ".js".
  8. = OBIEKTY I ICH WYŚWIETLANIE = Podczas dzisiejszego wpisu utworzymy obiekty, a następnie narysujemy je na ekranie – trochę luźniejszy temat niż kilka ostatnich. Definiowanie wielkości powierzchni gry Jak wiadomo, gdy chcemy coś narysować, musimy mieć na czym, dlatego definiujemy wielkość "płótna" na którym będziemy rysować. Najlepiej zrobić to podczas inicjalizacji gry, czyli wewnątrz funkcji „init”. Ustawiamy szerokość („width”) i wysokość („height”) obiektu „canvas”, czyli naszego płótna, po którym będziemy rysować, na cały dostępny obszar okna („window”). To pozwoli nam rysować na całej stronie. Warto zauważyć, że szerokość i wysokość ustawiamy teraz tylko raz, podczas inicjalizacji, przez co gdy podczas rozgrywki gracz zmniejszy lub zwiększy okno, wielkość gry się nie zmieni. Oczywiście można dodać kod, który na bieżąco dostosowuje rozmiar gry do rozmiaru okna, ale wymaga on dodatkowych przeliczeń w pozycjach, przez co uważam, że nie jest to aż tak potrzebna rzecz w tak prostej grze, więc nie będę pokazywał w tej serii jak to zrobić. Obiekty Także – zacznijmy od utworzenia zmiennej typu „Object” (obiekt), który będzie przechowywał inne obiekty. Jeśli chcemy utworzyć zmienną o takim typie, po prostu przypisujemy jej wartość dwóch nawiasów klamrowych, które symbolizują, można powiedzieć, zbiór różnych rzeczy. Zanim zaczniemy dodawać obiekty do naszej gry, stwórzmy jeszcze „przepis” na nowy typ zmiennej – „Point”. Ułatwi nam on przechowywanie informacji o koordynatach różnych punktów, do których będziemy mogli się odwoływać po prostu dopisując do nazwy zmiennej „.x” lub „.y”. Wystarczy, że przepiszesz kod na tym obrazku na końcu swojego skryptu. (Przed wywołaniem funkcji „init”). Dodawanie obiektów do gry Znów wracamy do funkcji „init”, tym razem, by dodać wszystkie elementy, które będą później wyświetlane podczas gry. Tworzenie zmiennej w obiekcie odbywa się poprzez napisanie nazwy obiektu-rodzica (u nas zmienna „objects”), następnie pary nawiasów kwadratowych, a w nich nazwa zmiennej w podwójnych cudzysłowach. Potem dajemy znak równa się i wartość, którą chcemy przypisać zmiennej w obiekcie. U nas będzie to kolejny obiekt, który będzie miał swoje parametry: Pozycje, czyli punkt Prędkość, czyli zmienną liczbową Kierunek, czyli zmienną liczbową wyrażaną w stopniach (od 0 do 360) Kształt, czyli dwa możliwe napisy - „circle” – kółko lub „rect” – prostokąt Kolor, czyli napis z kolorem zapisanym w formacie heksadecymalnym ("#000000" to czarny, --> tu <-- możesz wybrać dowolny, inny kolor) Promień, czyli promień koła (tylko, jeśli kształt to koło) Zmienne oczywiście możesz nazwać inaczej niż ja. W przypadku zmiennej „Position” (pozycja) pojawiło nam się nowe słówko kluczowe „new” – czyli po angielsku „nowy”, co pozwala nam utworzyć nowy obiekt za pomocą wcześniej utworzonego „przepisu”. Daje nam to ładne zdanie „Nowy Punkt”, a w nawiasach podajemy najpierw współrzędną X, a następnie Y. U mnie piłka będzie zaczynać swój lot na środku, więc współrzędne ustawiłem po prostu na pół szerokości ekranu i pół jego wysokości. Przy przypisywaniu „velocity”, czyli prędkości, utworzyłem nową stałą „BALL_VELOCITY_START” – w wolnym tłumaczeniu: „Prędkość początkowa piłki”. Zrobiłem to po to, by wszystkie zmienne związane z fizyką mieć na samej górze skryptu, dzięki czemu mogę łatwo dostosować wszystkie wartości. Zadanie; spróbuj utworzyć kolejne dwa obiekty, czyli paletki, którym będzie odbijało się piłkę. Paletki powinny być prostokątne. Poniżej rozwiązanie. Jak można zauważyć, zostało tu wprowadzonych kilka zmian. Co do tych mniejszych, kształt tych obiektów to prostokąt, a w związku z tym, zamiast „radius” (promienia koła) mamy „width” i „height” (szerokość i wysokość) ustawione na stałe wartości zapisane wyżej w kodzie („PADDLE_WIDTH” (szerokość), „PADDLE_HEIGHT” (wysokość) ). Tym razem nie ma też prędkości, gdyż w przypadku piłki – prędkość będzie zmieniana przez fizykę, a w przypadku paletek – nie. Dużo większe zmiany widać natomiast w pozycji i już spieszę z wyjaśnieniem czemu tak, a nie inaczej. Tu również wprowadziłem nową stałą „PADDLE_DISTANCE”, czyli dystans paletki od krawędzi ekranu. Możesz zauważyć, że w przypadku pierwszej paletki kod pozycji jest o wiele krótszy niż tej drugiej. Wiąże się to z pewnym założeniem, że współrzędne, które wyznaczają pozycje prostokąta, znajdują się w jego lewym górnym rogu, a nie na jego środku. Dlatego ustawiając pozycję prawej paletki, musimy odjąć od współrzędnej X jej grubość, by skorygować problem, który został przedstawiony poniżej. Gdybyśmy tego nie skorygowali, drugi gracz miałby paletkę oddaloną bardziej od środka niż gracz pierwszy, co może dać mu przewagę. Poza tym, całą współrzędną X drugiej paletki musimy oczywiście odjąć od szerokości ekranu, by paletka znalazła się rzeczywiście po prawej stronie. Podobnie musimy „naprawić” współrzędną Y, odejmując połowę wysokości paletki od połowy wysokości ekranu. W przeciwnym razie, paletka byłaby o połowę niżej. Poniżej zamieszczam również obrazek przypisania nowych stałych, gdyby ktoś nadal nie do końca wiedział, jak to zrobić. Rysowanie obiektów na ekranie Zanim przedstawię potrzebny kod, zastanówmy się, co powinniśmy zrobić, by wyświetlić aktualną klatkę gry. Wyczyścić ekran – żeby obraz poprzedniej klatki nie zlał się z obecną Dla każdego obiektu Sprawdzić czy obiekt jest kołem i jeśli jest, narysować koło o podanym kolorze i promieniu Jeśli nie jest kołem, to sprawdzić czy jest prostokątem i narysować prostokąt o podanym kolorze i wymiarach Brzmi prosto, więc jeśli chcesz – możesz spróbować zrobić to sama/sam. Możesz jeszcze nie wiedzieć jak zrobić niektóre rzeczy, w tej sytuacji możesz poszukać rozwiązania w Google, bądź w innej wyszukiwarce internetowej, na przykład „Jak narysować koło w JavaScript Canvas”, lub „Jak wyczyścić Canvas w JavaScript” Zanim zaczniesz, dodam tylko, że może Ci się tu przydać nieznana wcześniej pętla „for”, która wykonuje kod dla każdej zmiennej zawartej w zmiennej „objects”. Jej konstrukcja została podana na poniższym obrazku. Zmienna „object” wewnątrz pętli będzie zawierać parametry obecnie przetwarzanego obiektu, a zmienna „key” będzie zawierać nazwę obiektu („ball”, „paddle_1”, „paddle_2”). Powyżej został przedstawiony już właściwy kod, który pozwoli wyświetlić oba kształty obiektów, ale rozbijmy sobie znów to na części. Najpierw czyścimy ekran funkcją „clearRect” (w wolnym tłumaczeniu – „wyczyść prostokąt”), która należy do obiektu „draw”. Przyjmuje ona cztery argumenty; współrzędna X, współrzędna Y, szerokość i wysokość prostokąta, który wyczyści wszystko na jego powierzchni. My oczywiście czyścimy cały ekran, więc zaczynamy na współrzędnych x: 0 i y: 0, a szerokość i wysokość prostokąta do wyczyszczenia to szerokość i wysokość przestrzeni do rysowania. Następnie mamy pętlę „for”, która wykona kod w niej zawarty dla każdej zmiennej z obiektu „objects”, w którym umieściliśmy nasze obiekty do narysowania. Następnie mamy… taki dziwny kawałek kodu - porównanie, które w skrócie sprawdza, czy zmienna którą przetwarzamy rzeczywiście jest zmienną. Jak być może pamiętasz – obiekty mogą zawierać zmienne i funkcje w sobie, a tak się składa, że każdy obiekt w JavaScriptcie posiada przypisane "wbudowane" funkcje. Nasz nowy obiekt też je zawiera, natomiast my chcemy wykonać kod tylko dla wszystkich zmiennych w obiekcie, a nie funkcji, dlatego przeskakujemy pętle, jeśli trafimy akurat na funkcję występującą w obiekcie. Dziwne, ale działa. Następnie przypisujemy wartość zmiennej „object” na obecnie przetwarzany obiekt, głównie dla czytelności. Teraz sprawdzamy, czy kształt obiektu to prostokąt. Jeśli nie, pomijamy kod w nawiasach. Jeśli tak, to: Ustawiamy kolor wypełnienia na kolor obiektu Rozpoczynamy nowy kształt (ścieżkę) Rysujemy prostokąt na pozycji, która jest podana w parametrach obiektu i o wymiarach takich, jakie są podane w parametrach obiektu Oznajmiamy, że skończyliśmy rysować kształt (ścieżkę) Wypełniamy kształt wcześniej wybranym kolorem Sprawdzamy, czy kształt obiektu to koło. Jeśli nie, pomijamy kod w nawiasach. Jeśli tak, to: Ustawiamy kolor wypełnienia na kolor obiektu Rozpoczynamy nowy kształt (ścieżkę) Rysujemy koło na pozycji, która jest podana w parametrach obiektu i o promieniu takim, jaki jest podany w parametrach obiektu. Pozostałe dwa parametry to kąt początkowy koła i kąt końcowy, oba podawane w radianach. (Ustawione jest na 360 stopni) Oznajmiamy, że skończyliśmy rysować kształt (ścieżkę) Wypełniamy kształt wcześniej wybranym kolorem I te wszystkie kroki powtarzamy dla każdego przypisanego obiektu w zmiennej „objects”. Jeśli wszystko zrobiłaś/zrobiłeś dobrze, powinieneś/powinnaś ujrzeć trzy obiekty po włączeniu gry w przeglądarce. Dobrze byłoby też sprawdzić konsole, czy nie popełniłeś/popełniłaś żadnych błędów.
  9. = KONSTRUKCJA KAŻDEJ GRY = W dzisiejszym wpisie wreszcie zaczniemy pisać kod, który rzeczywiście będzie potrzebny, żeby Twoja gra zaczęła działać. Mam nadzieje, że nie straciłeś/straciłaś zapału. Ten wpis pokaże i wytłumaczy Ci kod, który powinien znaleźć się w każdej grze przeglądarkowej. Podstawowe zmienne Dwie podstawowe zmienne, które powinieneś/powinnaś utworzyć już na samym początku pliku, to zmienna „canvas” i zmienna „draw”. Zmienną „canvas” ustawiamy na wartość, którą zwróci nam funkcja „getElementById” (w wolnym tłumaczeniu: „zwróć element o podanym Id”). Jak można się domyślić, zwraca ona element języka HTML, o podanym Id. Oczywiście chodzi tu o Id elementu „canvas”, które podałeś/podałaś w pliku „index.html” we wpisie drugim. Następnie, gdy już zdobędziemy element z drugiego pliku, czas na utworzenie zmiennej, który pozwoli nam rysować na stronie, tak że za pomocą poprzednio utworzonej zmiennej pobieramy z elementu „canvas” dwuwymiarowy kontekst (bo nasza gra będzie dwuwymiarowa). Robimy to za pomocą odwołania się do zmiennej canvas, następnie dajemy kropkę i wywołujemy funkcję „getContext” (w wolnym tłumaczeniu: „zwróć kontekst”) z argumentem „2d”. Teraz, w nagrodę możemy narysować sobie na przykład wypełniony kwadrat. Robimy to wywołując funkcję „rect” (skrót od „prostokąt” po angielsku) z nowo utworzonego obiektu w zmiennej „draw”. Jak widać na obrazku, funkcja przyjmuje cztery argumenty i są to odpowiednio; współrzędna X, współrzędna Y, szerokość i wysokość. Ja postanowiłem zrobić kwadrat o boku 20, w lewym górnym rogu strony. Warto zauważyć, że układ współrzędnych ma swój środek właśnie w lewym górnym rogu, a nie tak jakby się mogło wydawać – na środku. Poniżej mniej więcej przedstawiłem o co chodzi. Następnie wywołujemy funkcję „fill” (z ang. „Wypełnij”) znajdującą się w zmiennej „draw”, która powoduje wypełnienie kształtu. Po wejściu na stronę gry, powinieneś/powinnaś zauważyć mały, czarny kwadrat w lewym górnym rogu. Podstawowe funkcje gry Nasza gra będzie podzielona (póki co) na cztery funkcje, każda z nich będzie miała inne zadanie; Funkcja „init” – odpowiada za przygotowanie całej gry do działania Funkcja „tick” – Będzie wywoływana co każdą klatkę animacji przeglądarki, czyli będziesz w niej umieszczać wszystkie rzeczy, które powinny dziać się co każdą klatkę gry Funkcja „updatePhysics” – odpowiada za fizykę gry – czyli aktualizację pozycji wszystkich obiektów podlegających fizyce oraz obsługę kolizji obiektów. Warto zauważyć, że ta funkcja przyjmuje parametr „delta”, czyli różnicę czasu między poszczególnymi jej wywołaniami – przyda Ci się to do późniejszych obliczeń. Funkcja „renderGame” – ta funkcja będzie po prostu rysować całą grę na ekranie Poniżej możesz zobaczyć jak powinny wyglądać napisane przez Ciebie definicje funkcji. Ich nazwy możesz oczywiście zmienić według swojej woli. Na samym końcu skryptu powinniśmy umieścić także wywołanie pierwszej funkcji, która zapoczątkuje całą grę Teraz stopniowo możemy zacząć wypełniać nasze funkcje. Zacznijmy od funkcji „init”. Umieszczamy w niej pierwsze wywołanie do funkcji „tick”, która zapoczątkuje rysowanie gry. Funkcja „tick” ma za zadanie wywoływanie wszystkich innych funkcji, które powinny się w czasie klatki gry. O co chodzi z tymi klatkami? Jak dobrze wiesz, na przykład w Minecraftcie mamy liczbę FPS’ów, czyli tłumacząc na polski: „Klatek na sekundę”. Każda klatka to obraz, który wyświetla Twój monitor, im więcej gra jest w stanie ich wyprodukować w krótkim odstępie czasu, tym wydaję Ci się, że jest ona płynniejsza. W naszej grze za tworzenie klatek będzie odpowiedzialna funkcja renderGame, z tym, że będzie ona produkować tylko jedną klatkę na jedno wywołanie. Jeśli chcemy, żeby gra była płynna, bądź w ogóle cokolwiek się w niej poruszało, musimy tę funkcję wywoływać co chwilę, by odświeżyła obraz na monitorze uwzględniając wszystkie zmiany. requestAnimationFrame By robić coś ciągle – dajemy specjalnej wbudowanej już funkcji nazwę naszej funkcji, którą chcemy powtarzać tak szybko, jak to możliwe. Jej nazwa to „requestAnimationFrame” – w wolnym tłumaczeniu „proś o klatkę animacji” a w nawiasach funkcji dajemy nazwę naszej funkcji, co daje zdanie „proś o klatkę animacji funkcję tick”. Dzięki temu, że funkcja „tick” będzie wywoływana co chwilę, będzie mogła wywołać też funkcję „renderGame”, która wyświetli nam nową klatkę gry. Mam nadzieję, że przyswoiłaś/przyswoiłeś cały fragment tego tekstu i rozumiesz o co w tym chodzi, bo teraz przechodzimy do trochę trudniejszej rzeczy. Główna pętla fizyki gry W poprzednim rozdziale powiedzieliśmy sobie o funkcji „requestAnimationFrame”, która wywołuje funkcję „tick” tak szybko, jak to możliwe. Ta funkcja ma jednak jeden problem – nie działa, gdy karta przeglądarki nie jest otwarta. Czyli; jeśli gramy sobie w grę i nagle na Facebooku w drugiej karcie napisze do nas ulubiona koleżanka czy też kolega, to odpisując mu nasza gra będzie wstrzymana, nic w niej nie będzie się przez ten czas dziać. W jednych grach jest to działanie pożądane, w innych nie. Mimo, że w naszym Pongu mogłoby to zostać tak jak jest, to jednak wolę pokazać, jak rozwiązać ten proble. Tę technikę zaleca się jednak stosować tylko w ramach funkcji fizyki gry, a nie jej wyświetlania, gdyż nadrabianie straconego czasu nic nam nie da w przypadku rysowania nowych klatek, jedynie fizyka powinna nadganiać stracony czas, dlatego rozdzielamy rysowanie i fizykę gry na dwie różne funkcje. Na samym początku musimy zadeklarować sobie trzy kolejne zmienne, którym póki co przypiszmy wartość 0, a następnie trzy stałe, którym musimy już przypisać konkretne wartości, bo inaczej nigdzie indziej im ich nie przypiszemy (bo są stałe). No dobra, ale za co one odpowiadają? Zmienne: lastFrameTime – przechowuje informację, kiedy została narysowana ostatnia klatka gry. Warto zauważyć, że przechowuje ona wartość liczbową – ilość sekund, które upłynęły od włączenia strony. currentTime – przechowuje obecny czas w takim samym formacie, jak „lastFrameTime” PhysicAccumulator – to trochę taki bufor, który będzie przechowywał informację o tym, ile łącznie czasu upłynęło między wszystkimi klatkami gry (w sekundach) Stałe: PhysicFrames – ile razy wykonywać przeliczenie fizyki w ciągu sekundy PhysicDelta – ile sekund powinno upłynąć między poszczególnymi klatkami (tego fragmentu kodu raczej nie edytuj, jeśli nie wiesz co robisz) PhysicAccumulatorMax – Maksymalna wartość, jaką może przechowywać zmienna PhysicAccumulator. Jest ona po to, żeby po długim czasie nieobecności gracza przy grze (to znaczy, przy dłuższym wyjściu do innej karty przeglądarki) zmienna „PhysicAccumulator” nie osiągnęła zbyt dużej wartości. Jeśli by się tak stało, po powrocie do gry, przeglądarka internetowa najprawdopodobniej by się zacięła, gdyż czasu do nadgonienia byłoby zbyt dużo. Wartość „1” oznacza, że możemy wykonać maksymalnie 60 przeliczeń fizyki po powrocie gracza do gry. Ponownie rozbijmy sobie ten obrazek na fragmenty; Najpierw ustawiamy zmienną „currentTime” na wynik funkcji „now()” obiektu „performance”, czyli po prostu obecny czas w milisekundach, a potem dzielimy otrzymany czas przez 1000, zamieniając milisekundy na sekundy. Następnie mamy dość skomplikowanie wyglądające porównanie, ale po kolei; najpierw obliczamy ile czasu upłynęło od ostatniego wywołania funkcji, czyli odejmujemy poprzedni zapisany czas od obecnego czasu („currentTime – lastFrameTime”), co daje nam wynik w sekundach. sprawdzamy, czy „PhysicAccumulator”, po dodaniu sekund, które upłynęły, nie wykracza poza jego maksymalną dozwoloną wartość („PhysicAccumulatorMax”) Jeśli nie wykracza, dodajemy ilość czasu, który upłynął do PhysicAccumulatora, jeśli nie, oznacza to, że osiągnął on swoją maksymalną wartość i nie powinniśmy już nic do niego dodawać, więc zostawiamy go tak jak jest. Następnie ustawiamy ostatni zapisany czas na obecny, tak, by kolejne wywołania funkcji mogły z niego skorzystać Następnie stosujemy pętle, która aktualizuje fizykę tyle razy, by nadgonić ewentualne opóźnienia związane z opuszczeniem karty gry przez gracza Z tym ostatnim punktem wiąże się trochę większa filozofia, gdyż to co robimy to właściwie sprawdzamy, czy upłynęło więcej czasu, niż upłynęłoby pomiędzy kolejnymi klatkami fizyki. Jeśli tak, to aktualizujemy fizykę i odejmujemy od PhysicAccumulator stałą wartość między klatkami fizyki, ponieważ ten czas już nadrobiliśmy. Następnie znów sprawdzamy czy upłynęło więcej czasu… i tak dalej, aż nadrobimy zaległości w fizyce. Ostatecznie, po całym dzisiejszym wpisie, Twój „logic.js” powinien wyglądać mniej więcej tak: To znów ciężki temat, ale jeśli go nie rozumiesz, to chętnie wytłumaczę go w komentarzach, bądź w wiadomości prywatnej.
  10. = KONSOLA – GDZIE SZUKAĆ BŁĘDÓW? = Programowanie jakiegokolwiek programu można właściwie podzielić na trzy etapy i wszystkie trwają mniej więcej tyle samo czasu; Wymyślanie nowych funkcji/programów w głowie Przepisywanie wymyślonych funkcji/programów na kod Testowanie, poprawianie błędów Zazwyczaj wszystkie trzy kroki powtarzają się kilkaset razy, zanim cały program zostanie ukończony, a najbardziej frustrującą czynnością jest szukanie błędów i ich poprawianie. Gdzie komputer pokaże potencjalne błędy? W większości języków programowania błędy, ostrzeżenia bądź inne informacje zazwyczaj będą pojawiać się w konsoli – może to być konsola systemowa, konsola przeglądarki internetowej, czy własna konsola. W przypadku JavaScriptu, będzie to konsola przeglądarki internetowej, gdyż sam JavaScript jest stworzony po to, żeby współgrać z przeglądarką internetową. Jak wejść do konsoli przeglądarki? Zanim zaczniemy, chciałbym jeszcze nadmienić, że podczas całej serii będę testował grę na przeglądarce „Google Chrome” w (obecnie) najnowszej wersji – „83.0.4103.97”. Oczywiście, gra powinna otworzyć się mniej więcej tak samo na innych nowoczesnych przeglądarkach internetowych, ja korzystam z Chrome, gdyż po prostu tak mi najwygodniej. Sposobów jest na pewno kilka, ale pokażę prawdopodobnie najszybszy. Oczywiście, zanim będziemy otwierać konsolę, należy wejść na stronę gry, klikając dwukrotnie na plik „index.html” w folderze gry. Powinna nam się otworzyć nowa, (póki co) pusta karta przeglądarki internetowej. Następnie, klikamy kombinację klawiszy CTRL + SHIFT + i (CTRL, SHIFT, „i”). Po prawej stronie witryny, bądź w nowym oknie otworzą się narzędzia dla deweloperów. Znajdziemy tu różne narzędzia, które są przydatne podczas tworzenia stron internetowych, lecz nam podczas tej serii przyda się tylko jedna zakładka – „Console” / „Konsola”. Powyżej możesz zobaczyć zdjęcie konsoli przeglądarki Google Chrome. Jeśli korzystasz z innej przeglądarki, powinieneś/powinnaś zobaczyć coś podobnego. W dolnej części okna będziesz mogła/mógł zobaczyć wszystkie informacje wypisane przez siebie, czy też błędy w kodzie zgłaszane przez przeglądarkę. Możesz tu też testować małe fragmenty kodu, bądź przeglądać jaką wartość mają obecnie zmienne. Jak wyglądają błędy? Najłatwiej jest zobaczyć je samemu, więc otwórz plik „logic.js” za pomocą edytora tekstowego i wpisz jakiś błędy kod. Ja osobiście postawię na błędną składnię przypisania wartości zmiennej; Powyżej fragment kodu, który wpisałem do swojego pliku „logic.js”, jeśli pamiętasz poprzedni wpis, pomiędzy wartością zmiennej a jej nazwą powinien znaleźć się jeszcze znak równości. Jak widać, edytor już wie co się święci i podkreślił miejsce błędu falowaną linią, ale póki co, nie zwracajmy na to uwagi. Zapiszmy więc plik, przejdźmy z powrotem do przeglądarki i wciśnijmy F5. Strona powinna się odświeżyć, a po ponownym otwarciu konsoli powinien pojawić się Ci czerwony napis. Poniżej zdjęcie konsoli z błędem. „(x) Uncaught SyntaxError: Unexpected string logic.js:1”. Jak widzisz, będziesz musiał/musiała rozumieć podstawy języka angielskiego, by zrozumieć błędy, które popełniasz. Chociaż.. w sumie, wystarczy Ci tłumacz, te błędy zazwyczaj nie są skomplikowane. Rozbijmy sobie treść komunikatu na mniejsze fragmenty; Uncaught – z ang. „Nie złapany”, „nie przechwycony” SyntaxError – typ błędu, w tym wypadku „błąd składni” Unexpected String – treść błędu, w tym wypadku „niespodziewany ciąg znaków” logic.js:1 – Przed dwukropkiem komputer podaje nam nazwę pliku, w którym wystąpił błąd, a następnie numer linii, która prawdopodobnie go spowodowała. Znając ogólne tłumaczenie, możemy wywnioskować, że popełniliśmy błąd składni, Mówiąc ściślej; postawiliśmy gdzieś ciąg znaków, którego komputer w tym momencie się nie spodziewał. A to wszystko wydarzyło się w pierwszej linii pliku „logic.js”. Wracamy więc do pliku „logic.js” i sprawdzamy, co jest błędem. Podkreślony jest ciąg znaków „b”, który spowodował błąd. Jeśli chwilę nad tym pomyślimy, to rzeczywiście, komputer spodziewał się najpierw znaku równości, a potem dopiero ciągu znaków, dlatego po jego dodaniu błąd nie powinien się dalej wyświetlać. Jak możesz zauważyć, komputer nie zawsze powie wprost, co jest nie tak. Czasem da Ci właśnie taką wymijającą odpowiedź, a Ty będziesz musiała/musiał się domyślić, co zrobiłeś/zrobiłaś źle. Warte uwagi jest to, że czasem mimo wystąpienia błędu, program dalej się wykona, a ty możesz go nawet nie zauważyć, dlatego warto czasem dla zasady sprawdzić konsolę po wprowadzeniu nowych zmian w kodzie. Jeśli masz chwilę czasu, dobrze by było, byś na podstawie poprzedniego wpisu oswoił się z innymi błędami, które w trakcie pisania możesz popełnić. Oswoił to znaczy popełnił/popełniła je celowo i zobaczyła/zobaczył jak wyglądają.
  11. = WPROWADZENIE DO JAVASCRIPTU = Zanim zaczniesz czytać Zwróć uwagę, że ten wpis jest bardzo długi i to może Cię zniechęcić do jego przeczytania. Zachęcam jednak, by podzielić sobie czytanie na kilka części, ponieważ sam wpis jest podzielony na krótkie „rozdziały” ukazujący kolejne podstawowe elementy każdego języka programowania. Jeśli znudzi Ci się czytanie, rozważ doczytanie wpisu chociaż do końca jednego z rozdziałów, bo ciężko Ci będzie powrócić do połowy jednego z rozdziałów – zwyczajnie pewnie zapomnisz, co było w jego pierwszej połowie. Wiem, że niektóre z fragmentów wpisu mogą być trudne do zrozumienia, także jeśli czegoś nie rozumiesz, spróbuj przeczytać dany rozdział ponownie, a jeśli nadal nie załapiesz o co chodzi, zawsze możesz napisać do mnie w sekcji komentarzy, bądź w prywatnej wiadomości, a ja chętnie udzielę Ci pomocy. Sam wpis zamierzałem podzielić na kilka części, jednak zrezygnowałem, gdyż uważam, że lepiej przedstawić wszystko w jednym wpisie, który można sobie dodać do zakładek i wracać, gdy zapomni się pewnych rzeczy podczas pisania właściwej gry. Rozdziały: Zmienne Wyrażenia matematyczne Porównywanie liczb Instrukcje warunkowe Komentarze Funkcje Pętle Zmienne Jednym z podstawowych elementów każdego języka programowania są zmienne i stałe. Przy nauce jakiegokolwiek języka, często porównuje się je do szafki, czy też swego rodzaju pudełka. Ja jednak lubię je porównywać do kontenerów, bo potrafią zmieścić naprawdę dużo informacji. W skrócie, zmienna to takie pudełko/kontener w którym możesz przechowywać dowolną informację – liczbę, napis, obiekt czy też stan danej rzeczy. JavaScript w przeciwieństwie do innych języków, pozwala na zmianę typu zmiennej w locie, to znaczy; zmienna najpierw może przechowywać, dla przykładu, liczbę, a potem na przykład jakiś napis. Możesz dowolnie zmieniać wartość i typ zmiennej, kiedy chcesz i na jaki chcesz. Poniżej omówienie kilku typów zmiennych: Liczba (Number) – po prostu jakakolwiek liczba, czy to z przecinkiem, czy bez. Warto zauważyć, że jeśli chcemy zapisać liczbę z przecinkiem, to robimy to za pomocą kropki, na przykład „73.41”, a nie za pomocą przecinka. Napis (String) – Dowolny ciąg znaków. Gdy przypisujemy napis do zmiennej, bądź gdziekolwiek używamy stałego ciągu znaków, to sam ciąg wstawiamy w parę podwójnych cudzysłowów. Przykład: „ "Jakiś sobie napis" ”. Stan (Bool/Boolean) – Ten typ zmiennych przechowuje tylko dwie wartości – „true” (prawda) albo „false” (fałsz). Oba słówka kluczowe („true” i „false”) zapisuje się bez cudzysłowów. Zazwyczaj zmienne o takim typie przechowują informację o stanie jakiejś rzeczy, na przykład „czy pogoda jest dziś ładna” z wartością „true”. Obiekt (Object) – W skrócie, jest to zbiór różnych zmiennych i funkcji, które do niego należą, możemy odwoływać się do nich poprzez zastosowanie kropki po nazwie zmiennej, na przykład „samochod.kolor” zwraca wartość zmiennej „kolor”, która należy do obiektu „samochod”. Typów zmiennych jest trochę więcej, ale uważam, że te cztery starczą nam na początek zabawy w świecie komputerów. Mam też świadomość, że możesz jeszcze nie do końca rozumieć „Obiektu”, ale możesz go sobie porównać do takich mniejszych pudełek włożonych w jedno większe pudełko, można powiedzieć – taki segregator, można powiedzieć. Co do nazw zmiennych i funkcji, jest kilka zasad; Nazwy mogą posiadać tylko litery, cyfry, znaki podkreślenia oraz znaki dolara. Nazwa nie może zaczynać się cyfrą W nazwach, wielkość liter ma znaczenie (zmienna „abc” i zmienna „ABC” to dwie różne zmienne) Nazwa nie może być taka sama jak jedno z zarezerwowanych słów (Lista: https://www.w3schools.com/JS/js_reserved.asp) Streszczając tę listę – po prostu powinieneś/powinnaś używać liter i cyfr oraz nie zaczynać nazw od cyfry. Na poniższym obrazku przedstawiłem przykład przypisania wartości do zmiennej. Jak widać, wszystko wydaje się dość logiczne, mamy nazwę zmiennej, następnie znak „równa się” i wartość, którą chcemy jej przypisać. Na końcu linii znajduje się średnik, który oznajmia, że to koniec linii kodu. Dodatkowo, przed samą nazwą mamy słówko kluczowe „let” (w wolnym tłumaczeniu „Niech”), które oznajmia, że chcesz stworzyć nową zmienną. Powinieneś/Powinnaś pisać je tylko przy deklarowaniu zmiennej. Co to znaczy? Deklaracja zmiennej to nic innego jak powiedzenie komputerowi „hej, zrób mi pudełko o nazwie „obecnyRok””, a on jak pokorny podwładny po prostu je zrobi. Myślę, że zrozumiałym jest, że to pudełko tworzymy tylko raz, a więc słówka „let” też używasz tylko raz dla danej zmiennej, zazwyczaj na początku jej używania. Później nie musisz go pisać, wystarczy samo „obecnyRok = 2021;”. Słówko „let” możemy także zamienić na słówko „const” (constant, stała), wtedy komputer utworzy tak zwaną stałą, a nie zmienną. Wartość stałej można przypisać tylko raz, przy ich definiowaniu. Dodatkowo, słówko „let” ma swój starszy odpowiednik – „var”, który niczym się od niego nie różni (no, prawie..) i czasem mogę go używać w serii, gdyż po prostu jestem do niego przyzwyczajony. Jeśli zrozumiałeś/zrozumiałaś na czym polegają zmienne, możemy przejść do kolejnego „tematu” dzisiejszego wpisu. Wyrażenia Matematyczne Tytuł może trochę przerazić, zwłaszcza, że jest w nim słowo „Matematyka”, ale zapewniam, że to nic strasznego. Wyrażenia matematyczne, to nic innego, jak manipulacja liczbami. Nadal niejasno? Hm.. Wyrażenia matematyczne, to po prostu dodawanie/odejmowanie/(…) liczb. Oczywiście operacji jest więcej niż tylko dodawanie i odejmowanie, ale chodzi o samo zrozumienie koncepcji wyrażeń matematycznych. Myślę, że nie trzeba nadmieniać, że wyrażenia matematyczne zazwyczaj będą zwracać jakiś wynik w postaci liczby. Zazwyczaj wyrażenia będą miały następującą postać ogólną: Liczba1 Operator Liczba2 Nietrudne, no nie? Poniżej zamieszczę małą ściągawkę operatorów w JavaScriptcie. OPERATOR CO ROBI? Liczba1 + Liczba2 Dodaje Liczba2 do Liczba1 Liczba1 - Liczba2 Odejmuje Liczba2 od Liczba1 Liczba1 * Liczba2 Mnoży Liczba1 razy Liczba2 Liczba1 / Liczba2 Dzieli Liczba1 przez Liczba2 Liczba1 % Liczba2 Zwraca resztę z dzielenia Liczba1 przez Liczba2 Nooo… tego szło się domyślić (a przynajmniej większości), ale i tak wolałem podać dla zasady. Oczywiście pod hasłami „Liczba1” i „Liczba2” mogą kryć się zarówno liczby stałe, czyli po prostu jakieś liczby lub, co ważniejsze, nazwy zmiennych, które zawierają jakieś liczby. Poniżej przykład. W tym wypadku wartość zmiennej „liczbaKawalkowPizzy” została zmniejszona o jeden, więc posiada teraz wartość „7”. Wydaję mi się, że z łatwością przyswoiłaś/przyswoiłeś ten temat, także ruszamy do kolejnego. Porównywanie liczb Porównywanie liczb brzmi przyjaźnie i robi większość roboty w dużej części programów, dlatego warto upewnić się, że dobrze zrozumieliśmy ten temat. Porównywanie liczb zawsze zwracają dwie możliwe wartości; prawdę lub fałsz, czyli odpowiednio „true” lub „false”, więc gdy przypiszesz wynik porównania czegokolwiek do jakiejś zmiennej, będzie ona typu Bool (stan). Zazwyczaj porównania mają postać mniej więcej taką: Liczba1 Operator Liczba2 …czyli podobną do Wyrażeń Matematycznych. Warto zauważyć, że pod hasłami „Liczba1” i „Liczba2” nie muszą kryć się konkretnie jakieś stałe liczby – równie dobrze może to być wyrażenie matematyczne lub nazwa zmiennej, która przechowuje jakąś wartość. Poniżej znów zamieszczę małą ściągawkę operatorów. OPERATOR CO ROBI? Liczba1 == Liczba2 Sprawdza, czy Liczba1 jest równa Liczba2 Liczba1 != Liczba2 Sprawdza, czy Liczba1 jest nierówna Liczba2 Liczba1 > Liczba2 Sprawdza, czy Liczba1 jest większa od Liczba2 Liczba1 >= Liczba2 Sprawdza, czy Liczba1 jest większa lub równa od Liczba2 Liczba1 < Liczba2 Sprawdza, czy Liczba1 jest mniejsza od Liczba2 Liczba1 <= Liczba2 Sprawdza, czy Liczba1 jest mniejsza lub równa od Liczba2 Myślę, że dużym zaskoczeniem może być sprawdzanie, czy liczba1 jest równa liczbie2. Dlaczego dwa znaki równości zamiast jednego? Jeśli pamiętasz konstrukcję przypisywania wartości zmiennym, to wiesz, że musi tam znaleźć się jeden znak „równa się”. Tutaj wprowadzone zostały dwa takie znaki, by komputer mógł rozróżnić, czy chcesz porównać liczby, czy przypisać im takie same wartości, dlatego warto zwracać uwagę na ich ilość. Poniżej przykład prostego porównania liczb. W ten sposób zmienna „czyJestPizza” otrzymała wartość „true”, czyli prawda. Możesz spytać, ale po co porównywać to w ten sposób, skoro ja od razu mogę zobaczyć, że „liczbaKawalkowPizzy” to 8, więc mogę napisać, że „czyJestPizza” jest równa „true”(prawda). Noo… możesz, tylko w większości przypadków nie będziesz od razu wiedział/wiedziała, jaką wartość ma „liczbaKawalkowPizzy”, ta wartość może zostać jej nadana na przykład przez inteligentną lodówkę, a nie przez Ciebie. Instrukcje warunkowe Przechodzimy do trochę bardziej skomplikowanych rzeczy, ale na pewno sobie poradzisz. Instrukcje warunkowe to nic innego, jak wykonywanie określonego fragmentu kodu, gdy jakieś wyrażenie, porównanie, bądź zmienna jest zgodna z prawdą, a także wykonywanie innego fragmentu kodu, jeśli tą prawdą nie jest. Wygląda dość skomplikowanie, ale zapewniam Cię, że tak nie jest. Rozbijmy sobie ten obrazek na małe fragmenty. if – czyli pierwsze słówko kluczowe, to słówko, które oznajmia komputerowi, że chcesz w tym miejscu utworzyć instrukcję warunkową. „if” z języka angielskiego oznacza „Jeżeli”. Następnie mamy nawias, a właściwie parę nawiasów, pomiędzy którymi znajduje się jakieś porównanie liczb. Oczywiście możesz tu także umieścić samą nazwę zmiennej, która jest typu Bool (stan). Otwierający nawias klamrowy, który rozpoczyna tak zwany blok kodu, czyli po prostu jakąś część kodu. W tym wypadku, będzie on oznajmiał początek kodu, który chcesz wykonać, gdy wyrażenie (napisane w nawiasach okrągłych) jest prawdą. Następnie mamy jakiś kod, w tym wypadku jest to wywołanie funkcji „ZamowKolejnaPizze”, oczywiście można tu wpisać jakikolwiek fragment kodu. Zamykający nawias klamrowy, który oznajmia koniec bloku kodu Od razu za nim mamy słówko kluczowe „else”, czyli w wolnym tłumaczeniu „w przeciwnym razie”, jak możemy się domyślać, jest to słówko oznajmiające, że następny blok kodu chcesz wykonać, gdy wyrażenie jednak okazało się fałszem W tym momencie jest powtórka tego, co było poprzednio z nawiasami klamrowymi, czyli para nawiasów klamrowych, pomiędzy nimi jakiś kod, w tym wypadku wywołanie funkcji „ZjedzPizze”, który ma się wykonać, gdy wyrażenie jest fałszem. Jeśli uważasz, że zrozumiałaś/zrozumiałeś temat, możesz przejść do upragnionego końca wpisu. Komentarze Mały przerywnik - komentarze to po prostu napisy, które komputer ignoruje, gdy uruchamia program. Są one tylko dla nas. Możemy w nich opisać działanie jakiegoś skomplikowanego kodu poniżej, czy wpisać w nich cokolwiek nam się zamarzy. Jak widać, wystarczy przed tekstem dać dwa prawe ukośniki, a komputer zignoruje dalszą treść linii, w której się znajdują. Funkcje To może zacznijmy od przykładu użycia tym razem. Wyobraź sobie, że piszesz program wykonujący jakieś skomplikowane obliczenia matematyczne i w kilkudziesięciu miejscach potrzebujesz największego wspólnego dzielnika dwóch liczb. Tak więc piszesz algorytm, który wylicza największy wspólny dzielnik w jednym miejscu, a następnie kopiujesz i wklejasz go w inne, tam gdzie potrzebujesz. Program oczywiście działa, wykonuje obliczenia, ale okazuje się, że robi je za wolno, także postanawiasz zmienić algorytm wyszukiwania tych największych wspólnych dzielników. W tym celu przeszukujesz internet, znajdujesz jakiś super szybki i… no właśnie, musisz odszukać miejsca, gdzie wkleiłaś/wkleiłeś stary algorytm i zamienić go na nowy. Nudna robota, nie prawdaż? Zwłaszcza, jeśli tych miejsc jest więcej niż 20, a poprzedni algorytm wklejałeś/wklejałaś trzy lata temu. Po prostu szukanie igły w stogu siana. W tym momencie wkraczają funkcje, czyli fragmenty kodu, które są tu właśnie po to, żeby rozwiązać ten problem. Jeśli wcześniej użyłbyś funkcji, wystarczyłoby zmienić kod tylko w jednym miejscu. W kontekście funkcji używamy dwóch terminów Definicja funkcji – czyli sprecyzowanie jej nazwy, argumentów, których będziesz używać, a także całego kodu, który dana funkcja będzie wykonywać. Wywołanie funkcji – Polega po prostu na „zawołaniu” funkcji do pracy, czyli po prostu przekazaniu jej pożądanych argumentów, a następnie wykonanie jej kodu, zapisanego w definicji funkcji. Powyżej przedstawiłem prostą deklarację funkcji o nazwie „poleTrojkata”. Rozbijmy sobie obrazek na części, tak jak poprzednio. Najpierw słówko kluczowe „function” (z ang. Funkcja), który oznajmia, że chcesz zdefiniować nową funkcję Następnie podajesz nazwę swojej nowej funkcji, zasady nazewnictwa funkcji są takie same jak zasady nazewnictwa zmiennych, które opisałem już wcześniej w tym wpisie Para okrągłych nawiasów, pomiędzy którymi wprowadzasz nazwy argumentów (zmiennych), które będą przekazywane funkcji. Jeśli chcesz podać więcej niż jeden argument, po prostu daj przecinek pomiędzy nazwami argumentów. Jeśli nie chcesz w ogóle podawać funkcji argumentów, wystarczy, że nic nie wstawisz pomiędzy nawiasy. Warto zauważyć, że same nawiasy zawsze muszą znaleźć się po nazwie funkcji, nawet jeśli są puste Nawiasy klamrowe oznaczające początek bloku kodu, który w tym wypadku będzie wykonywany podczas wywoływania funkcji. W nich możesz umieścić dowolny fragment kodu. W bloku kodu funkcji, możesz użyć także słówka kluczowego „return” (z ang. „Zwrócić”), które zwróci podaną przez Ciebie wartość z powrotem do kodu, z którego funkcja została wywołana. Warto zauważyć, że po napotkaniu i wykonaniu słówka „return” komputer nie wykonuje kodu znajdującego się poniżej „return” – może to być wykorzystane jako swego rodzaju przerwanie wykonywania kodu funkcji. Trochę skomplikowane, ale mam nadzieje, że szybko zrozumiesz o co chodzi. Same funkcje mogą służyć także za „segregatory” kodu, czyli możemy umieścić w nich jakąś część kodu, która jest ze sobą powiązana, by było nam czytelniej patrzeć na kod. Teraz przyszedł czas na wywołanie funkcji, które jak widać, jest bardzo podobne jak pierwsza linia jej definicji. Oczywiście nie znajdziemy tutaj już słówka odpowiedzialnego za jej definicję, ale znajdziemy jej nazwę, parę nawiasów i taką samą ilość argumentów. Znajdziemy tu też zmienną „poleDzialki”, której zostanie przypisany wynik funkcji „poleTrojkata” wywołanej z argumentami „20” i „30”. Samo wywołanie ma postać nazwy funkcji, a następnie pary nawiasów, w których znajdują się opcjonalne argumenty przekazane funkcji. Warto zauważyć, że jeśli w definicji funkcji nie użylibyśmy „return”, to zmienna „poleDzialki” będzie miała pustą wartość. Pętle Pętle to nic innego jak powtarzanie pewnego kodu tak długo, aż warunek podany pętli jest prawdą. Pomaga to zautomatyzować niektóre rzeczy, jak na przykład wyświetlanie kilkuset obiektów. Typów pętli jest kilka, ale póki co podam tu tylko jedną. Powyżej możesz zobaczyć przykładowe użycie pętli „while”. Powtarza ona kod zawarty pomiędzy klamrowymi nawiasami, do póki wyrażenie podane w okrągłych nawiasach jest prawdą. Oczywiście wyrażenie może być także zmienną typu Bool (stan) lub porównanie liczb. W kodzie, który powtarza pętla, możemy umieścić także słówko kluczowe „continue”, które powoduje natychmiastowe przejście do kolejnej iteracji pętli, czyli po napotkaniu takiego słówka komputer pomija cały kod, który jest poniżej i ponownie sprawdza, czy wyrażenie w nawiasach jest prawdą. Jeśli jest, wykonuje znów ten sam kod, jeśli nie – przechodzi do kodu poza pętlą.
  12. RedziQ

    1.3 - Wprowadzenie do JavaScriptu

    klikasz dwa razy na obrazek i tam masz "adres url" i tam wklejasz gdzie chcesz zeby prowadzil obrazek ps polaczylem posty zeby sie nikt nie przyczepil jednak nie moge
  13. RedziQ

    1.3 - Wprowadzenie do JavaScriptu

    to sa obrazki po prostu zrobilem sb w gimp
  14. = CO ZNAJDZIEMY W FOLDERZE GRY? = No więc, gdy już się porządnie przygotowaliśmy, zainstalowaliśmy odpowiednie programy, to możemy zacząć od właściwego tworzenia gry. Na sam początek – coś prostego, czyli przygotowanie folderu zawierającego pliki gry. Powyżej widzisz, jak to powinno wyglądać – dwa pliki w folderze gry. Jeden z nazwą „index” i rozszerzeniem „html”, drugi z nazwą „logic” i rozszerzeniem „js”. Nazwy oczywiście mogą być dowolne, ważniejsze są tu rozszerzenia. Ważnym jest, by pliki rzeczywiście miały dane rozszerzenie, w tym celu najlepiej włączyć widoczność rozszerzeń w Opcjach Eksploratora Windows. W każdym razie, gdy faktycznie nadasz odpowiednie rozszerzenia plikom, ich ikonka powinna się zmienić. „index.html” prawdopodobnie będzie zawierał logo Twojej domyślnej przeglądarki internetowej, a „logic.js” będzie miał ikonkę skryptu. index.html Ten plik zawiera główną strukturę strony zapisaną w języku HTML, w nim raczej za dużo się nie zmienia, a sam plik jest mało treściwy. W jego wnętrzu używamy tak zwanych znaczników, z których większość występuje w dwóch wersjach – otwierającej i zamykającej. Poniżej mały schemat jednego ze znaczników. Na obrazku wyróżniłem główne elementy znacznika. Jak widać, znacznik otwierający składa się z pary nawiasów ostrokątnych, a po między nimi znajduje się nazwa znacznika oraz atrybuty i ich wartości. Znacznik zamykający jest prawie tak samo zbudowany, tylko nie zawiera żadnych atrybutów, a przed nazwą znacznika stoi prawy ukośnik. Myślę, że nie trzeba tłumaczyć, że najpierw powinno się pisać znacznik otwierający, a następnie zamykający. Warto nadmienić, że wartości atrybutów powinno zapisywać się w podwójnych cudzysłowach. Czasem też pomiędzy otwierającym i zamykającym znacznikiem będzie stać jakaś treść, którą zawiera dany znacznik. Powyżej możesz zobaczyć treść, jaką powinieneś/powinnaś wpisać do swojego „index.html”. Łącznie są to trzy linie, które pozostaną niezmienne do końca tej serii. Piszę trzy linie, mimo tego, że widocznych na obrazku jest pięć, ale tylko dlatego, że puste linie po prostu nic nie znaczą dla przeglądarki – równie dobrze może ich tu nie być, dodałem je głównie ze względów estetycznych. Po krótce omówimy sobie za co odpowiada każda linia. Pierwsza linia to znacznik „style”, który definiuje wygląd strony internetowej, w tym wypadku używamy go po prostu do usunięcia marginesów widocznej części strony, poprzez ustawienie ich na 0. Następna, trzecia linia to element, na którym właściwie będzie rysowana nasza gra, czyli znacznik „canvas” – z angielskiego „płótno”. Zawiera atrybut id z wartością „plate”, „id” jest nam potrzebny, żeby móc się łatwo odwołać do tego znacznika podczas rysowania na nim czegokolwiek. Oczywiście „id” może być dowolne, ja natomiast będę używał „plate”. Ostatnia linia, czyli piąta, zawiera znacznik „script”, który odpowiada za dołączenie całej logiki (skryptu) naszej gry do strony internetowej. Znacznik posiada atrybut „src” (skrót od source, z ang. źródło), który wskazuje jaki plik dołączyć. W tym wypadku „logic.js”, bądź jakakolwiek inna nazwa, która wpadła Ci do głowy, podczas tworzenia plików. Jeśli Twoja treść pliku mniej więcej zgadza się z moją, możesz zamknąć plik i przez resztę serii raczej do niego nie wracać. W następnych wpisach będziemy pracować głównie na dołączonym pliku „logic.js”. Mimo wszystko, sam „index.html” jest, wbrew pozorom, też bardzo ważny – żeby „uruchomić” grę, należy otworzyć właśnie ten plik w przeglądarce. Możesz przetestować, czy nadałaś/nadałeś odpowiednie rozszerzenie po prostu klikając dwukrotnie na ten plik. Jeśli wszystko jest dobrze, powinno ukazać Ci się nowa, zupełnie pusta karta przeglądarki internetowej. logic.js Jak sama (proponowana) nazwa wskazuje, ten plik przechowuje całą „logikę”, która steruje rysowaniem i ogólnym zachowaniem gry. W tym wpisie nie będę się zbyt rozwodził nad jego treścią, gdyż będzie to tematem wszystkich następnych wpisów.
  15. RedziQ

    Na początek kilka informacji

    szczerze jeśli da radę to ja bym wstawił ten prolog czy coś tutaj na bloga też, nie każdy czyta podania yo