DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu

„Wiem, że nic nie wiem” Sokrates

Dla kogo: dla informatyków, którzy plują na wszystkich programistów i chcą grać w ich gry!

O czym: jak zacząć pisać gry w C/C++, jeśli tego potrzebujesz!

Dlaczego warto to przeczytać: Tworzenie aplikacji nie jest moją specjalnością, ale staram się programować co tydzień. Bo kocham gry!

cześć, mam na imię Andriej Grankin, jestem DevOpsem w firmie Luxoft. Tworzenie aplikacji nie jest moją specjalnością, ale staram się programować co tydzień. Bo kocham gry!

Przemysł gier komputerowych jest ogromny, o którym mówi się dziś jeszcze więcej niż o przemyśle filmowym. Gry były pisane od początku rozwoju komputerów, przy użyciu, według nowoczesnych standardów, złożonych i podstawowych metod programistycznych. Z czasem zaczęły pojawiać się silniki gier z zaprogramowaną grafiką, fizyką i dźwiękiem. Pozwalają skupić się na rozwoju samej gry i nie przejmować się jej fundamentami. Ale wraz z nimi, wraz z silnikami, programiści „ślepną” i degradują. Sama produkcja gier trafia na przenośnik. A ilość produkcji zaczyna przeważać nad jej jakością.

Jednocześnie, grając w gry innych osób, jesteśmy nieustannie ograniczeni przez lokalizacje, fabułę, postacie, mechanikę gry, które wymyślili inni. Więc zdałem sobie sprawę, że...

…nadszedł czas na tworzenie własnych światów, podlegających tylko mnie. Światy, w których jestem Ojcem i Synem i Duchem Świętym!

I szczerze wierzę, że pisząc własny silnik gry i grę na nim, będziesz mógł otworzyć oczy, wytrzeć szyby i napompować swoją kabinę, stając się bardziej doświadczonym i integralnym programistą.

W tym artykule postaram się opowiedzieć jak zacząłem pisać małe gry w C/C++, jak wygląda proces tworzenia i gdzie znajduję czas na hobby w zabieganym środowisku. Jest subiektywny i opisuje proces indywidualnego startu. Materiał o ignorancji i wierze, o moim osobistym obrazie świata w tej chwili. Innymi słowy, „Administracja nie jest odpowiedzialna za twoje osobiste mózgi!”.

Praktyka

„Wiedza bez praktyki jest bezużyteczna, praktyka bez wiedzy jest niebezpieczna.” Konfucjusz

Mój notatnik to moje życie!


Tak więc w praktyce mogę powiedzieć, że wszystko u mnie zaczyna się od zeszytu. Zapisuję tam nie tylko swoje codzienne zadania, ale także rysuję, programuję, projektuję schematy blokowe i rozwiązuję problemy, w tym matematyczne. Zawsze używaj notatnika i pisz tylko ołówkiem. Jest czysty, wygodny i niezawodny, IMHO.

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Mój (już wypełniony) notatnik. tak to wygląda. Zawiera codzienne zadania, pomysły, rysunki, diagramy, rozwiązania, czarną księgowość, kod i tak dalej.

Na tym etapie udało mi się ukończyć trzy projekty (jest to w moim rozumieniu „ostateczność”, bo każdy produkt można rozwijać stosunkowo w nieskończoność).

  • Projekt 0: to jest scena Architect Demo 3D napisana w języku C# przy użyciu silnika gry Unity. Dla platform macOS i Windows.
  • Gra 1: konsolowa gra Simple Snake (znana wszystkim jako „Snake”) dla systemu Windows. napisane w C.
  • Gra 2: gra konsolowa Crazy Tanks (znana wszystkim jako „Tanks”), napisana już w C ++ (przy użyciu klas), a także pod Windows.

Wersja demonstracyjna architekta projektu 0

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Demo architekta scen 3D

Pierwszy projekt został zaimplementowany nie w C/C++, ale w C# z wykorzystaniem silnika gry Unity. Ten silnik nie był tak wymagający sprzętowo jak Unreal Engine, a także wydawał mi się łatwiejszy w instalacji i obsłudze. Innych silników nie brałem pod uwagę.

Celem Unity nie było dla mnie stworzenie jakiejś gry. Chciałem stworzyć scenę 3D z jakąś postacią. On, a raczej Ona (wzorowałem się na dziewczynie, w której byłem zakochany =) musiał się poruszać i wchodzić w interakcje ze światem zewnętrznym. Ważne było tylko zrozumienie, czym jest Unity, czym jest proces tworzenia i ile wysiłku wymaga stworzenie czegoś. Tak narodził się projekt Architect Demo (nazwa została wymyślona niemal z bzdur). Programowanie, modelowanie, animacja, teksturowanie zajęło mi chyba dwa miesiące codziennej pracy.

Zacząłem od filmów instruktażowych na YouTube, jak tworzyć modele 3D w mikser. Blender to świetne darmowe narzędzie do modelowania 3D (i nie tylko), które nie wymaga instalacji. I tu czekał mnie szok... Okazuje się, że modelowanie, animacja, teksturowanie to ogromne osobne tematy, o których można pisać książki. Dotyczy to zwłaszcza postaci. Do modelowania palców, zębów, oczu i innych części ciała niezbędna będzie znajomość anatomii. Jak ułożone są mięśnie twarzy? Jak ludzie się poruszają? Musiałem „włożyć” kości w każdą rękę, nogę, palec, kostkę!

Wymodeluj obojczyk, dodatkowe dźwignie kostne, aby animacja wyglądała naturalnie. Po takich lekcjach zdajesz sobie sprawę, jak ogromną pracę wykonują twórcy filmów animowanych, aby stworzyć 30 sekund wideo. Ale filmy 3D trwają godzinami! A potem wychodzimy z kin i mówimy coś w stylu: „Ta, gówniana kreskówka / film! Mogli zrobić to lepiej… Głupcy!

I jeszcze jedno o programowaniu w tym projekcie. Jak się okazało, najbardziej interesująca dla mnie była część matematyczna. Jeśli uruchomisz scenę (link do repozytorium w opisie projektu), zauważysz, że kamera obraca się wokół postaci dziewczyny w kuli. Aby zaprogramować taki obrót kamery, musiałem najpierw obliczyć współrzędne punktu położenia na okręgu (2D), a następnie na kuli (3D). Zabawne jest to, że w szkole nienawidziłem matematyki i znałem ją z minusem. Po części prawdopodobnie dlatego, że w szkole po prostu nie tłumaczą ci, jak do cholery ta matematyka ma zastosowanie w życiu. Ale kiedy masz obsesję na punkcie swojego celu, snu, wtedy umysł jest czysty, odsłaniany! I zaczynasz postrzegać złożone zadania jako ekscytującą przygodę. A potem myślisz: „Cóż, dlaczego *ukochany* matematyk normalnie nie mógłby powiedzieć, gdzie można oprzeć te formuły?”.

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Obliczanie wzorów do obliczania współrzędnych punktu na okręgu i na kuli (z mojego zeszytu)

Gra 1

  • Platforma: Windows (testowane na Windows 7, 10)
  • Język: Myślę, że został napisany w czystym C
  • Silnik gry: Konsola Windowsa
  • Inspiracja: javidx9
  • Magazyn: GitHub

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Prosta gra w węża

Scena 3D to nie gra. Ponadto modelowanie i animowanie obiektów 3D (zwłaszcza postaci) jest długie i trudne. Po zabawie z Unity zdałem sobie sprawę, że muszę kontynuować, a raczej zacząć od podstaw. Coś prostego i szybkiego, ale jednocześnie globalnego, aby zrozumieć samą strukturę gier.

A co mamy proste i szybkie? Zgadza się, konsola i 2D. Dokładniej, nawet konsola i symbole. Znów zacząłem szukać inspiracji w internecie (ogólnie internet uważam za najbardziej rewolucyjny i niebezpieczny wynalazek XXI wieku). Wykopałem wideo jednego programisty, który stworzył konsolę Tetris. I na podobieństwo swojej gry postanowił ściąć „węża”. Z filmu dowiedziałem się o dwóch podstawowych rzeczach - pętli gry (z trzema podstawowymi funkcjami/częściami) oraz wyjściu do bufora.

Pętla gry może wyglądać mniej więcej tak:

int main()
   {
      Setup();
      // a game loop
      while (!quit)
      {
          Input();
          Logic();
          Draw();
          Sleep(gameSpeed);  // game timing
      }
      return 0;
   }

Kod przedstawia od razu całą funkcję main(). A cykl gry rozpoczyna się po odpowiednim komentarzu. W pętli występują trzy podstawowe funkcje: Input(), Logic(), Draw(). Najpierw wprowadzamy dane Input (głównie sterowanie naciśnięciami klawiszy), następnie przetwarzamy wprowadzone dane Logiczne, następnie wyświetlamy na ekranie - Draw. I tak każdy kadr. Animacja jest tworzona w ten sposób. To jak kreskówki. Zwykle przetwarzanie danych wejściowych zajmuje najwięcej czasu i, o ile mi wiadomo, decyduje o liczbie klatek na sekundę gry. Ale tutaj funkcja Logic() jest bardzo szybka. Dlatego szybkość klatek musi być kontrolowana przez funkcję Sleep() z parametrem gameSpeed, który określa tę szybkość.

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
cykl gry. Programowanie węża w notatniku

Jeśli tworzysz symboliczną grę konsolową, to wyświetlanie danych na ekranie przy użyciu zwykłego strumienia wyjściowego „cout” nie będzie działać - jest bardzo powolne. Dlatego wyjście musi być wykonane w buforze ekranu. O wiele szybciej, a gra będzie działać bez zakłóceń. Szczerze mówiąc, nie do końca rozumiem, czym jest bufor ekranu i jak działa. Ale podam tutaj przykład kodu i być może ktoś w komentarzach będzie w stanie wyjaśnić sytuację.

Pobieranie bufora ekranu (jeśli mogę tak powiedzieć):

// create screen buffer for drawings
   HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0,
 							   NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
   DWORD dwBytesWritten = 0;
   SetConsoleActiveScreenBuffer(hConsole);

Bezpośrednie wyjście na ekran określonej linii scoreLine (linii do wyświetlania wyników):

// draw the score
   WriteConsoleOutputCharacter(hConsole, scoreLine, GAME_WIDTH, {2,3}, &dwBytesWritten);

Teoretycznie nie ma w tej grze nic skomplikowanego, wydaje mi się, że to dobry przykład gry dla początkujących. Kod jest zapisany w jednym pliku i ułożony w kilka funkcji. Bez klas, bez dziedziczenia. Sam możesz zobaczyć wszystko w kodzie źródłowym gry, przechodząc do repozytorium na GitHub.

Gra 2 Szalone czołgi

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Gra Szalone czołgi

Drukowanie postaci na konsoli to prawdopodobnie najprostsza rzecz, jaką można zamienić w grę. Ale wtedy pojawia się problem: znaki mają różną wysokość i szerokość (wysokość jest większa niż szerokość). W ten sposób wszystko będzie wyglądać nieproporcjonalnie, a poruszanie się w dół lub w górę będzie wydawać się znacznie szybsze niż poruszanie się w lewo lub w prawo. Efekt ten jest bardzo widoczny w grze „Snake” (gra 1). „Czołgi” (Gra 2) nie mają takiej wady, ponieważ dane wyjściowe są tam zorganizowane poprzez malowanie pikseli ekranu różnymi kolorami. Można powiedzieć, że napisałem renderer. To prawda, że ​​\uXNUMXb\uXNUMXbjest to już trochę bardziej skomplikowane, choć o wiele bardziej interesujące.

W przypadku tej gry wystarczy opisać mój system wyświetlania pikseli na ekranie. Myślę, że to jest główna część gry. I wszystko inne możesz wymyślić sam.

Tak więc to, co widzisz na ekranie, to tylko zestaw ruchomych kolorowych prostokątów.

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Zestaw prostokątów

Każdy prostokąt jest reprezentowany przez macierz wypełnioną liczbami. Przy okazji mogę zwrócić uwagę na jeden ciekawy niuans – wszystkie macierze w grze są zaprogramowane jako jednowymiarowa tablica. Nie dwuwymiarowy, ale jednowymiarowy! Praca z tablicami jednowymiarowymi jest znacznie prostsza i szybsza.

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Przykład macierzy czołgu do gry

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Reprezentowanie macierzy czołgu gry za pomocą tablicy jednowymiarowej

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Bardziej ilustrujący przykład reprezentacji macierzowej za pomocą jednowymiarowej tablicy

Ale dostęp do elementów tablicy odbywa się w podwójnej pętli, tak jakby nie była to tablica jednowymiarowa, ale dwuwymiarowa. Dzieje się tak, ponieważ nadal pracujemy z macierzami.

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Przechodzenie przez jednowymiarową tablicę w podwójnej pętli. Y to identyfikator wiersza, X to identyfikator kolumny

Proszę zauważyć, że zamiast zwykłych identyfikatorów macierzy i, j używam identyfikatorów x i y. Wydaje mi się więc, że jest to przyjemniejsze dla oka i jaśniejsze dla mózgu. Ponadto taki zapis umożliwia wygodne rzutowanie zastosowanych macierzy na osie współrzędnych dwuwymiarowego obrazu.

Teraz o pikselach, kolorze i wyświetlaczu. Funkcja StretchDIBits (nagłówek: windows.h; biblioteka: gdi32.lib) jest używana do wyprowadzania. Do tej funkcji przekazywane są między innymi: urządzenie, na którym wyświetlany jest obraz (w moim przypadku jest to konsola Windows), współrzędne początku wyświetlania obrazu, jego szerokość/wysokość oraz obraz siebie w postaci mapy bitowej (mapy bitowej), reprezentowanej przez tablicę bajtów. Bitmapa jako tablica bajtów!

Funkcja StretchDIBits() w działaniu:

// screen output for game field
   StretchDIBits(
               deviceContext,
               OFFSET_LEFT, OFFSET_TOP,
               PMATRIX_WIDTH, PMATRIX_HEIGHT,
               0, 0,
               PMATRIX_WIDTH, PMATRIX_HEIGHT,
               m_p_bitmapMemory, &bitmapInfo,
               DIB_RGB_COLORS,
               SRCCOPY
               );

Pamięć jest przydzielana z góry dla tej mapy bitowej za pomocą funkcji VirtualAlloc(). Oznacza to, że wymagana liczba bajtów jest zarezerwowana do przechowywania informacji o wszystkich pikselach, które następnie zostaną wyświetlone na ekranie.

Tworzenie mapy bitowej m_p_bitmapMemory:

// create bitmap
   int bitmapMemorySize = (PMATRIX_WIDTH * PMATRIX_HEIGHT) * BYTES_PER_PIXEL;
   void* m_p_bitmapMemory = VirtualAlloc(0, bitmapMemorySize, MEM_COMMIT, PAGE_READWRITE);

Z grubsza mówiąc bitmapa składa się z zestawu pikseli. Każde cztery bajty w tablicy to piksel RGB. Jeden bajt na wartość koloru czerwonego, jeden bajt na wartość koloru zielonego (G) i jeden bajt na kolor niebieski (B). Ponadto na wcięcie przypada jeden bajt. Te trzy kolory – Czerwony/Zielony/Niebieski (RGB) – miesza się ze sobą w różnych proporcjach – i uzyskuje się wynikowy kolor piksela.

Teraz znowu każdy prostokąt lub obiekt gry jest reprezentowany przez macierz liczbową. Wszystkie te obiekty gry są umieszczone w kolekcji. Następnie umieszcza się je na boisku, tworząc jedną dużą matrycę numeryczną. Odwzorowałem każdą liczbę w matrycy na określony kolor. Na przykład liczba 8 jest niebieska, liczba 9 jest żółta, liczba 10 jest ciemnoszara i tak dalej. Możemy więc powiedzieć, że mamy macierz pola gry, w której każda liczba jest jakimś kolorem.

Mamy więc z jednej strony matrycę numeryczną całego pola gry, a z drugiej bitmapę do wyświetlania obrazu. Na razie bitmapa jest „pusta” – nie ma jeszcze informacji o pikselach żądanego koloru. Oznacza to, że ostatnim krokiem będzie wypełnienie bitmapy informacjami o każdym pikselu na podstawie numerycznej matrycy pola gry. Ilustracyjny przykład takiej transformacji znajduje się na poniższym rysunku.

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Przykład wypełnienia mapy bitowej (Matryca pikseli) informacjami opartymi na matrycy numerycznej (Matryca cyfrowa) pola gry (wskaźniki kolorów nie odpowiadają indeksom w grze)

Przedstawię też kawałek prawdziwego kodu z gry. Zmiennej colorIndex przy każdej iteracji pętli przypisywana jest wartość (indeks koloru) z numerycznej macierzy pola gry (mainDigitalMatrix). Następnie sam kolor jest zapisywany do zmiennej koloru na podstawie indeksu. Ponadto wynikowy kolor jest dzielony na stosunek czerwieni, zieleni i błękitu (RGB). Wraz z wcięciem (pixelPadding) informacje te są wielokrotnie zapisywane w pikselach, tworząc kolorowy obraz na mapie bitowej.

Kod wykorzystuje wskaźniki i operacje bitowe, co może być trudne do zrozumienia. Radzę więc poczytać gdzieś osobno, jak działają takie struktury.

Wypełnianie bitmapy informacjami na podstawie numerycznej matrycy boiska:

// set pixel map variables
   int colorIndex;
   COLORREF color;
   int pitch;
   uint8_t* p_row;
 
   // arrange pixels for game field
   pitch = PMATRIX_WIDTH * BYTES_PER_PIXEL;     // row size in bytes
   p_row = (uint8_t*)m_p_bitmapMemory;       //cast to uint8 for valid pointer arithmetic
   							(to add by 1 byte (8 bits) at a time)   
   for (int y = 0; y < PMATRIX_HEIGHT; ++y)
   {
       uint32_t* p_pixel = (uint32_t*)p_row;
       for (int x = 0; x < PMATRIX_WIDTH; ++x)
       {
           colorIndex = mainDigitalMatrix[y * PMATRIX_WIDTH + x];
           color = Utils::GetColor(colorIndex);
           uint8_t blue = GetBValue(color);
           uint8_t green = GetGValue(color);
           uint8_t red = GetRValue(color);
           uint8_t pixelPadding = 0;
 
           *p_pixel = ((pixelPadding << 24) | (red << 16) | (green << 8) | blue);
           ++p_pixel;
       }
       p_row += pitch;
   }

Zgodnie z metodą opisaną powyżej w grze Crazy Tanks powstaje jeden obrazek (ramka) i wyświetlany na ekranie w funkcji Draw(). Po zarejestrowaniu naciśnięć klawiszy w funkcji Input() i ich późniejszym przetworzeniu w funkcji Logic() powstaje nowy obraz (ramka). To prawda, że ​​\uXNUMXb\uXNUMXbobiekty gry mogą już mieć inną pozycję na boisku i odpowiednio są rysowane w innym miejscu. W ten sposób powstaje animacja (ruch).

Teoretycznie (jeśli o niczym nie zapomniałeś), zrozumienie pętli gry z pierwszej gry („Snake”) i systemu wyświetlania pikseli na ekranie z drugiej gry („Tanks”) wystarczy, aby napisać dowolny swoich gier 2D dla systemu Windows. Bezdźwięczny! 😉 Reszta części to już tylko fantazja.

Oczywiście gra „Czołgi” jest znacznie bardziej skomplikowana niż „Wąż”. Użyłem już języka C++, czyli opisałem różne obiekty gry klasami. Stworzyłem własną kolekcję - możesz zobaczyć kod w headers/Box.h. Nawiasem mówiąc, kolekcja najprawdopodobniej ma wyciek pamięci. Używane wskaźniki. Pracował z pamięcią. Muszę przyznać, że książka bardzo mi pomogła. Począwszy od C++ poprzez programowanie gier. To świetny początek dla początkujących w C++. Jest mały, ciekawy i dobrze zorganizowany.

Opracowanie tej gry zajęło około sześciu miesięcy. Pisałem głównie podczas lunchu i przekąsek w pracy. Siedział w biurowej kuchni, nadepnął na jedzenie i napisał kod. Albo w domu na obiad. Dostałem więc takie „kuchenne wojny”. Jak zawsze aktywnie korzystałem z zeszytu iw nim narodziły się wszystkie rzeczy koncepcyjne.

Na koniec części praktycznej wyciągnę kilka skanów mojego zeszytu. Żeby pokazać, co dokładnie spisywałam, rysowałam, liczyłam, projektowałam…

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Projekt obrazu czołgu. I określenie, ile pikseli każdy czołg powinien zajmować na ekranie

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Obliczenie algorytmu i wzorów na obrót zbiornika wokół własnej osi

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
Schemat mojej kolekcji (najprawdopodobniej tej z wyciekiem pamięci). Kolekcja jest tworzona jako połączona lista

DevOps C++ i „wojny kuchenne”, czyli jak zacząłem pisać gry przy jedzeniu
I są to daremne próby wkręcenia sztucznej inteligencji do gry

Teoria

„Nawet podróż tysiąca mil zaczyna się od pierwszego kroku” (mądrość starożytnych Chin)

Przejdźmy od praktyki do teorii! Jak znajdujesz czas na swoje hobby?

  1. Określ, czego naprawdę chcesz (niestety, to jest najtrudniejsze).
  2. Ustal priorytety.
  3. Poświęć wszystko „zbędne” na rzecz wyższych priorytetów.
  4. Dąż do swoich celów każdego dnia.
  5. Nie oczekuj, że będą dwie lub trzy godziny wolnego czasu na hobby.

Z jednej strony musisz określić, czego chcesz i ustalić priorytety. Z drugiej strony istnieje możliwość rezygnacji z niektórych spraw/projektów na rzecz tych priorytetów. Innymi słowy, będziesz musiał poświęcić wszystko „zbędne”. Słyszałam gdzieś, że w życiu powinny być maksymalnie trzy główne czynności. Wtedy będziesz mógł sobie z nimi poradzić w najlepszy możliwy sposób. A dodatkowe projekty/kierunki zaczną przeładowywać banał. Ale to wszystko jest prawdopodobnie subiektywne i indywidualne.

Jest pewna złota zasada: nigdy nie miej dnia 0%! Dowiedziałem się o tym z artykułu niezależnego dewelopera. Jeśli pracujesz nad projektem, rób coś z nim każdego dnia. I nie ma znaczenia, ile zarabiasz. Napisz jedno słowo lub jeden wiersz kodu, obejrzyj jeden samouczek wideo lub wbij jeden gwóźdź w tablicę — po prostu coś zrób. Najtrudniejsza część to zacząć. Kiedy zaczniesz, prawdopodobnie zrobisz trochę więcej, niż chciałeś. Będziesz więc stale dążyć do celu i uwierz mi, bardzo szybko. W końcu głównym hamulcem wszystkiego jest prokrastynacja.

I ważne jest, aby pamiętać, że nie należy lekceważyć i ignorować darmowych „trocin” czasu w 5, 10, 15 minut, czekać na duże „kłody” trwające godzinę lub dwie. Stoisz w kolejce? Pomyśl o czymś do swojego projektu. Wchodzisz po ruchomych schodach? Zapisz coś w zeszycie. Czy jesz w autobusie? Dobra, przeczytaj jakiś artykuł. Wykorzystaj każdą okazję. Przestań oglądać koty i psy na YouTube! Nie zadzieraj sobie z mózgiem!

I ostatni. Jeśli po przeczytaniu tego artykułu spodobał Ci się pomysł tworzenia gier bez użycia silników gier, to zapamiętaj nazwisko Casey Muratori. Ten facet ma broker. W dziale "obejrzyj -> POPRZEDNIE ODCINKI" znajdziesz niesamowite darmowe filmy instruktażowe, jak stworzyć profesjonalną grę od podstaw. Na pięciu lekcjach Intro to C for Windows można dowiedzieć się więcej niż w ciągu pięciu lat studiów na uczelni (ktoś o tym pisał w komentarzach pod filmem).

Casey wyjaśnia również, że opracowując własny silnik gry, lepiej zrozumiesz istniejące silniki. W świecie frameworków, w którym wszyscy próbują automatyzować, nauczysz się tworzyć, a nie używać. Zrozumieć samą naturę komputerów. Staniesz się też o wiele bardziej inteligentnym i dojrzałym programistą - profesjonalistą.

Powodzenia na wybranej drodze! I uczyńmy świat bardziej profesjonalnym.

Autor: Grankin Andrzej, DevOps



Źródło: www.habr.com