DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы

"Я ведаю, што нічога не ведаю" Сакрат

Для каго: для IT-шнікаў, якія плявалі на ўсіх распрацоўшчыкаў і хочуць пагуляць у свае гульні!

Аб чым: аб тым, як пачаць пісаць гульні на C/C++, калі раптам вам гэта трэба!

Навошта вам гэта чытаць: распрацоўка прыкладанняў - гэта не мая працоўная спецыялізацыя, але я імкнуся кожны тыдзень праграмаваць. Таму што люблю гульні!

Прывітанне, мяне клічуць Андрэй Гранкін, я DevOps у кампаніі Luxoft. Распрацоўка прыкладанняў - гэта не мая працоўная спецыялізацыя, але я імкнуся кожны тыдзень праграмаваць. Таму што люблю гульні!

Індустрыя камп'ютарных гульняў вялізная, па чутках, сёння нават большая, чым індустрыя кіно. Гульні пісалі з пачатку развіцця кампутараў, выкарыстоўваючы, па сучасных мерках, складаныя і базавыя метады распрацоўкі. З часам сталі з'яўляцца гульнявыя рухавічкі з ужо запраграмаванай графікай, фізікай, гукам. Яны дазваляюць засяродзіцца на распрацоўцы самой гульні і не затлумляцца з нагоды яе падставы. Але разам з імі, з рухавікамі, распрацоўшчыкі "слепнуць" і дэградуюць. Сама вытворчасць гульняў ставіцца на канвеер. А колькасць прадукцыі пачынае пераважаць яе якасць.

У той жа час, гуляючы ў чужыя гульні, мы ўвесь час абмежаваныя лакацыямі, сюжэтам, персанажамі, гульнявой механікай, якую прыдумалі іншыя людзі. Так што я зразумеў, што...

… надышоў час ствараць свае светы, падуладныя толькі мне. Міры, дзе я ёсць і Айцец, і Сын, і Святы Дух!

І я шчыра веру, што, напісаўшы свой уласны гульнявы ​​рухавічок і гульню на ім, атрымаецца разуць вочы, працерці фортачкі і прапампаваць сваю кабіну, стаўшы больш дасведчаным і суцэльным праграмістам.

У гэтым артыкуле паспрабую распавесці, як пачаў пісаць невялікія гульні на C/C++, які працэс распрацоўкі і дзе знаходжу час на хобі ва ўмовах вялікай загружанасці. Яна суб'ектыўная і апісвае працэс індывідуальнага старту. Матэрыял аб невуцтве і веры, аб маёй асабістай карціне свету ў дадзены момант. Іншымі словамі, «Адміністрацыя не нясе адказнасці за вашыя асабістыя мазгі!».

Практыка

"Веды без практыкі бескарысныя, практыка без ведаў небяспечная" Канфуцый

Мой нататнік - маё жыццё!


Такім чынам, на практыцы магу сказаць, што ўсё для мяне пачынаецца з блакнота. Туды запісваю не толькі свае паўсядзённыя задачы, у ім яшчэ і малюю, праграмую, канструюю блок-схемы і вырашаю задачы, у тым ліку матэматычныя. Заўсёды выкарыстоўвайце блакнот і пішыце толькі алоўкам. Гэта чыста, зручна і надзейна, ИМХО.

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Мой (ужо спісаны) нататнік. Вось так ён выглядае. У ім паўсядзённыя задачы, ідэі, малюнкі, схемы, рашэнні, чорная бухгалтэрыя, код і гэтак далей

На дадзеным этапе я паспеў скончыць тры праекты (гэта ў маім разуменні «скончанасці», бо любы прадукт можна развіваць адносна бясконца).

  • Праект 0: гэта 3D-сцэна Architect Demo, напісаная на C# з выкарыстаннем гульнявога рухавічка Unity. Для платформаў macOS і Windows.
  • Гульня 1: кансольная гульня Simple Snake (усім вядомая як "Змейка") пад Windows. Напісаная на C.
  • Гульня 2: кансольная гульня Crazy Tanks (усім вядомая як "Танчыкі"), напісаная ўжо на C++ (з выкарыстаннем класаў) і таксама пад Windows.

Project 0. Architect Demo

  • платформа: Windows (Windows 7, 10), Mac OS (OS X El Capitan v. 10.11.6)
  • Мова: C#
  • Гульнявы ​​рухавічок: Адзінства
  • Натхненне: Darrin Lile
  • Рэпазітар: GitHub

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
3D-сцэна Architect Demo

Першы праект рэалізаваны не на C/C++, а на C# з дапамогай гульнявога рухавічка Unity. Гэты рухавік быў не такі патрабавальны да «жалезу», як Unreal Engine, а таксама мне здаўся лягчэй ва ўсталёўцы і выкарыстанні. Іншыя рухавічкі я не разглядаў.

Мэтай у Unity для мяне не была распрацоўка нейкай гульні. Я хацеў стварыць 3D-сцэну з нейкім персанажам. Ён, а дакладней Яна (я змадэляваў дзяўчыну, у якую быў закаханы =) павінна была рухацца і ўзаемадзейнічаць з навакольным светам. Важна было толькі зразумець, што такое Unity, які працэс распрацоўкі і колькі намаганняў патрабуецца для стварэння чаго-небудзь. Так нарадзіўся праект Architect Demo (назва прыдумана амаль ад балды). Праграмаванне, мадэляванне, анімаванне, тэкстураванне заняло ў мяне, мусіць, два месяцы штодзённай працы.

Стартаваў я з навучалых відэа на YouTube па стварэнні 3D-мадэляў у змяшальнік. Blender - гэта выдатны бясплатны тул для 3D-мадэлявання (і не толькі), які не патрабуе ўстаноўкі. І тут мяне чакала ўзрушэнне… Аказваецца, мадэляванне, анімаванне, тэкстураванне — гэта вялізныя асобныя тэмы, на якія можна кніжкі пісаць. Асабліва гэта датычыцца персанажаў. Каб мадэляваць пальцы, зубы, вочы і іншыя часткі цела, вам спатрэбяцца веды анатоміі. Як уладкованыя цягліцы асобы? Як людзі рухаюцца? Мне прыйшлося "ўстаўляць" косткі ў кожную руку, нагу, палец, фалангі пальцаў!

Мадэляваць ключыцы, дадатковыя косці-рычагі, для таго каб анімацыя выглядала натуральна. Пасля такіх урокаў усведамляеш, якую вялікую працу робяць стваральнікі анімацыйных фільмаў, абы стварыць 30 секунд відэа. Хоць 3D-фільмы доўжацца гадзінамі! А мы потым выходзім з кінатэатраў і гаворым нешта накшталт: «Тая, брудны мультык/фільм! Маглі зрабіць і лепей…» Дурні!

І яшчэ, што да праграмавання ў гэтым праекце. Як аказалася, самая цікавая для мяне частка была матэматычная. Калі вы запусціце сцэну (спасылка на рэпазітар у апісанні праекта), то заўважыце, што камера круціцца вакол персанажа-дзяўчынкі па сферы. Каб запраграмаваць такое кручэнне камеры, мне прыйшлося спачатку вылічваць каардынаты кропкі становішча на крузе (2D), а потым і на сферы (3D). Самае смешнае, што я ненавідзеў матэматыку ў школе і ведаў яе на тры з мінусам. Збольшага, мусіць, таму што ў школе табе папросту не тлумачаць, як, чорт вазьмі, гэтая матэматыка ўжываецца ў жыцці. Але калі ты апантаны сваёй мэтай, марай, то розум чысціцца, раскрываецца! І ты пачынаеш успрымаць складаныя задачы як займальную прыгоду. А потым думаеш: "Ну чаго ж "каханая" матэматычка не магла нармальна распавесці, дзе гэтыя формулы прыхіліць можна?".

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Пралік формул для вылічэння каардынат кропкі на крузе і на сферы (з майго блакнота)

Game 1. Simple Snake

  • платформа: Windows (тэставаў на Windows 7, 10)
  • Мова: па-мойму, пісаў на чыстым C
  • Гульнявы ​​рухавічок: кансоль Windows
  • Натхненне: javidx9
  • Рэпазітар: GitHub

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Гульня Simple Snake

3D-сцэна - гэта не гульня. Да таго ж мадэляваць і анімаваць 3D-аб'екты (асабліва персанажы) доўга і складана. Пагуляўшы з Unity, да мяне прыйшло ўсведамленне, што трэба было працягваць, а дакладней пачынаць, з асноў. Чагосьці простага і хуткага, але ў той жа час глабальнага, каб зразумець саму прыладу гульняў.

А што ў нас простае і хуткае? Правільна, кансоль і 2D. Дакладней нават кансоль і знакі. Ізноў палез шукаць натхненне ў інтэрнэт (наогул, лічу інтэрнэт найболей рэвалюцыйным і небяспечным вынаходствам XXI стагоддзі). Накапаў відэа аднаго праграміста, які рабіў кансольны тэтрыс. І па падабенстве яго гульні вырашыў запілаваць "змейку". З відэа я даведаўся пра дзве фундаментальныя рэчы - гульнявы ​​цыкл (з трыма базавымі функцыямі/часткамі) і выснову ў буфер.

Гульнявы ​​цыкл можа выглядаць прыкладна так:

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

У кодзе прадстаўлена адразу ўся функцыя main(). А гульнявы ​​цыкл пачынаецца пасля які адпавядае каментара. У цыкле тры базавыя функцыі: Input(), Logic(), Draw(). Спачатку ўвод дадзеных Input (у асноўным кантроль націску клавіш), потым апрацоўка уведзеных дадзеных Logic, затым выснова на экран – Draw. І так кожны кадр. У такі спосаб ствараецца анімацыя. Гэта як у маляваных мульціках. Звычайна апрацоўка уведзеных дадзеных адбірае больш за ўсё часу і, наколькі я ведаю, вызначае фрэймрэйт гульні. Але тут функцыя Logic() выконваецца вельмі хутка. Таму кантраляваць хуткасць змены кадраў даводзіцца функцыяй Sleep() з параметрам gameSpeed, які і вызначае гэтую хуткасць.

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Гульнявы ​​цыкл. Праграмаванне "змейкі" ў блакноце

Калі распрацоўваць знакавую кансольную гульню, то выводзіць дадзеныя на экран з дапамогай звычайнай струменевай высновы 'cout' не атрымаецца - ён вельмі павольны. Таму вывад трэба праводзіць у буфер экрана. Так значна хутчэй і гульня будзе працаваць без глюкаў. Сапраўды кажучы, я не зусім разумею, што такое буфер экрана і як гэта працуе. Але я прывяду тут прыклад кода, і, магчыма, у каментарах нехта зможа праясніць сітуацыю.

Атрыманне буфера экрана (калі можна так сказаць):

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

Непасрэдная выснова на экран нейкага радка scoreLine (радок адлюстравання ачкоў):

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

Па ідэі, нічога складанага ў гэтай гульні няма, мне яна ўяўляецца добрым прыкладам пачатковага ўзроўню. Код напісаны ў адным файле і аформлены ў некалькіх функцыях. Няма класаў, няма ўспадкоўвання. Вы і самі ўсё можаце паглядзець у зыходніках гульні, перайшоўшы ў рэпазітар на GitHub.

Game 2. Crazy Tanks

  • платформа: Windows (тэставаў на Windows 7, 10)
  • Мова: C + +
  • Гульнявы ​​рухавічок: кансоль Windows
  • Натхненне: кніга Beginning C++ Through Game Programming
  • Рэпазітар: GitHub

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Гульня Crazy Tanks

Выводзіць знакі ў кансоль - гэта, мусіць, самае простае, што вы можаце ператварыць у гульню. Але тады з'яўляецца адна непрыемнасць: знакі маюць розную вышыню і шырыню (вышыня больш, чым шырыня). Такім чынам, усё будзе выглядаць непрапарцыйна, а рух уніз ці ўверх здавацца значна хутчэй, чым налева ці направа. Гэты эфект вельмі прыкметны ў "Змейцы" (Game 1). «Танчыкі» (Game 2) пазбаўленыя такога недахопу, бо выснова тамака арганізаваны праз зафарбоўванне экранных пікселяў рознымі колерамі. Можна сказаць, я напісаў рэндэрэр. Праўда, гэта ўжо крыху больш складана, хоць і значна цікавей.

Па дадзенай гульні будзе дастаткова апісаць маю сістэму вываду пікселяў на экран. Лічу гэта асноўнай часткай гульні. А ўсё астатняе можна прыдумаць самастойна.

Такім чынам, тое, што вы бачыце на экране - гэта проста набор рухомых рознакаляровых прастакутнікаў.

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Набор прамавугольнікаў

Кожны прастакутнік прадстаўлены матрыцай, запоўненай лікамі. Дарэчы, магу вылучыць адзін цікавы нюанс – усе матрыцы ў гульні запраграмаваны як аднамерны масіў. Не двухмерны, а аднамерны! З аднамернымі масівамі значна прасцей і хутчэй працаваць.

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Прыклад матрыцы гульнявога танка

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Прадстаўленне матрыцы гульнявога танка аднамерным масівам

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Больш наглядны прыклад падання матрыцы аднамерным масівам

Але доступ да элементаў масіва адбываецца ў падвойным цыкле, як быццам гэта не аднамерны, а двухмерны масіў. Так зроблена таму, што мы ўсё ж такі працуем з матрыцамі.

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Абыход аднамернага масіва ў падвойным цыкле. Y - ідэнтыфікатар радкоў, X - ідэнтыфікатар слупкоў

Звярніце ўвагу: замест звыклых матрычных ідэнтыфікатараў i, j я выкарыстоўваю ідэнтыфікатары x і y. Так, мне здаецца, прыемней для вачэй і больш зразумела для мозгу. Да таго ж такі запіс дазваляе зручна праецыраваць выкарыстоўваныя матрыцы на восі каардынат двухмернага малюнка.

Зараз пра пікселі, колер і вывад на экран. Для вываду выкарыстоўваецца функцыя StretchDIBits (Header: windows.h; Library: gdi32.lib). У гэтую функцыю, апроч усяго іншага, перадаецца наступнае: прылада, на якое выводзіцца малюнак (у маім выпадку гэта кансоль Windows), каардынаты старту адлюстравання малюначка, яе шырыня/вышыня і сама карцінка ў выглядзе бітавай карты (bitmap), прадстаўленай масівам байтаў. Бітавая карта ў выглядзе масіва байт!

Функцыя StretchDIBits() у працы:

// 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
               );

Пад гэтую бітавую карту загадзя вылучаецца памяць з дапамогай функцыі VirtualAlloc(). Гэта значыць рэзервуецца неабходная колькасць байт для захоўвання інфармацыі аб усіх пікселях, якія потым будуць выведзены на экран.

Стварэнне бітавай карты 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);

Грубіянска кажучы, бітавая карта складаецца з набору пікселяў. Кожныя чатыры байта ў масіве - гэта піксель у фармаце RGB. Адзін байт на значэнне чырвонага колеру, адзін байт на значэнне зялёнага колеру (G) і адзін байт на сіні колер (B). Плюс застаецца адзін байт на водступ. Гэтыя тры колеры – Red/Green/Blue (RGB) – змешваюцца адзін з адным у розных прапорцыях – і атрымліваецца выніковы колер пікселя.

Зараз, паўтаруся, кожны прастакутнік, ці гульнявы ​​аб'ект, прадстаўлены лічбавай матрыцай. Усе гэтыя гульнявыя аб'екты змяшчаюцца ў калекцыю. І затым расстаўляюцца па гульнявым полі, фармуючы адну вялікую лікавую матрыцу. Кожны лік у матрыцы я супаставіў з вызначаным колерам. Напрыклад, ліку 8 ​​адпавядае сіні колер, ліку 9 - жоўты, ліку 10 - цёмна-шэры колер і гэтак далей. Такім чынам, можна сказаць, у нас атрымалася матрыца гульнявога поля, дзе кожны лік - гэта нейкі колер.

Такім чынам, мы маем лікавую матрыцу ўсяго гульнявога поля з аднаго боку і бітавую карту для вываду выявы з другога. Пакуль што бітавая карта "пустая" - у ёй яшчэ няма інфармацыі аб пікселях патрэбнага колеру. Гэта значыць, што апошнім этапам будзе запаўненне бітавай карты інфармацыяй аб кожным пікселі на аснове лічбавай матрыцы гульнявога поля. Наглядны прыклад такога пераўтварэння на малюнку ніжэй.

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Прыклад запаўнення бітавай карты (Pixel matrix) інфармацыяй на аснове лічбавай матрыцы (Digital matrix) гульнявога поля (індэксы кветак не супадаюць з індэксамі ў гульні)

Таксама прадстаўлю кавалак рэальнага кода з гульні. Пераменнай colorIndex на кожнай ітэрацыі цыклу прысвойваецца значэнне (індэкс колеру) з лічбавай матрыцы гульнявога поля (mainDigitalMatrix). Затым у зменную color запісваецца сам колер на аснове азначніка. Далей атрыманы колер падзяляецца на суадносіны чырвонага, зялёнага і сіняга адцення (RGB). І разам з водступам (pixelPadding) штораз гэта інфармацыя запісваецца ў піксель, фармуючы каляровы малюнак у бітавай карце.

У кодзе выкарыстоўваюцца паказальнікі і пабітавыя аперацыі, якія могуць быць складаны для разумення. Так што раю яшчэ асобна недзе пачытаць, як працуюць такія канструкцыі.

Запаўненне бітавай карты інфармацыяй на аснове лічбавай матрыцы гульнявога поля:

// 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;
   }

Па апісаным вышэй метадзе ў гульні Crazy Tanks фармуецца адна карцінка (кадр) і выводзіцца на экран у функцыі Draw(). Пасля рэгістрацыі націску клавіш у функцыі Input() і наступнай іх апрацоўкі ў функцыі Logic() фармуецца новая карцінка (кадр). Праўда, гульнявыя аб'екты ўжо могуць мець іншае становішча на гульнявым полі і адпаведна адмалёўваюцца ў іншым месцы. Так і адбываецца анімацыя (рух).

Па ідэі (калі нічога не забыўся), разуменне гульнявога цыклу з першай гульні («Змейка») і сістэмы вываду пікселяў на экран з другой гульні («Танчыкі») — гэта ўсё, што вам трэба, каб напісаць любую сваю 2D-гульню пад Windows. Без гуку! 😉 Астатнія ж часткі - проста палёт фантазіі.

Вядома, гульня "Танчыкі" сканструявана значна складаней, чым "Змейка". Я выкарыстоўваў ужо мову C++, гэта значыць апісваў розныя гульнявыя аб'екты класамі. Стварыў уласную калекцыю - код можна паглядзець у headers/Box.h. Дарэчы, у калекцыі, хутчэй за ўсё, ёсць уцечка памяці (memory leak). Выкарыстоўваў паказальнікі. Працаваў з памяццю. Мушу сказаць, што мне вельмі дапамагла кніга Beginning C++ Through Game Programming. Гэта выдатны старт для пачаткоўцаў у C++. Яна невялікая, цікавая і нядрэнна арганізавана.

На распрацоўку гэтай гульні спатрэбілася недзе паўгода. Пісаў, у асноўным, падчас абеду і перакусаў на працы. Садзіўся на офіснай кухні, таптаў харчы і пісаў код. Або ж за вячэрай дома. Вось і атрымаліся ў мяне такія "кухонныя войны". Як заўсёды, я актыўна выкарыстоўваў блакнот, і ўсе канцэптуальныя штукі нараджаліся менавіта ў ім.

У завяршэнне практычнай часткі пульну некалькі сканаў майго нататніка. Каб паказаць, што менавіта я запісваў, маляваў, лічыў, праектаваў…

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Праектаванне выявы танкаў. І отпределенеі таго, колькі пікселяў кожны танк павінен займаць на экране

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Пралік алгарытму і формул па абарачэнні танка вакол сваёй восі

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
Схема маёй калекцыі (той самай, у якой ёсць memory leak, хутчэй за ўсё). Калегкцыя створана па тыпе Linked List

DevOps'ны C++ і "кухонныя войны", або Як я пачаў пісаць гульні падчас ежы
А гэта дарэмныя спробы прыкруціць да гульні штучны інтэлект.

Тэорыя

"Нават шлях у тысячу міль пачынаецца з першага кроку" (старажытнакітайская мудрасць)

Пяройдзем ад практыкі да тэорыі! Як жа знайсці час на сваё хобі?

  1. Вызначыць, чаго вы сапраўды жадаеце (нажаль, гэта самае складанае).
  2. Расставіць прыярытэты.
  3. Ахвяраваць усім "лішнім" ва ўгоду вышэйшым прыярытэтам.
  4. Рухацца да мэт кожны дзень.
  5. Не чакаць, што з'явіцца дзве-тры гадзіны вольнага часу на хобі.

З аднаго боку, вам трэба вызначыць, чаго вы хочаце і расставіць прыярытэты. А з другога, магчыма, адмовіцца ад нейкіх спраў/праектаў на карысць гэтых прыярытэтаў. Іншымі словамі, давядзецца ахвяраваць усім «лішнім». Я недзе чуў, што ў жыцці павінна быць максімум тры асноўныя заняткі. Тады вы зможаце імі займацца найболей якасна. А дадатковыя праекты/напрамкі пачнуць банальна перагружаць. Але гэта ўсё, мусіць, суб'ектыўна і індывідуальна.

Існуе нейкае залатое правіла: 0% day! Аб ім я пазнаў у артыкуле аднаго indie-распрацоўніка. Калі працуеце над нейкім праектам, то рабіце па ім нешта кожны дзень. І ўсё роўна, колькі вы зробіце. Напішыце адно слова ці адзін радок кода, паглядзіце адно навучалае відэа ці забіце адзін цвік у дошку - проста зрабіце хоць нешта. Самае складанае - гэта пачаць. Як толькі пачнеце, то напэўна зробіце крыху больш, чым хацелі. Так вы будзеце ўвесь час рухацца да сваёй мэты і, паверце, вельмі хутка. Бо асноўны тормаз усіх спраў гэта пракрасцінацыя.

І важна памятаць, што не варта недаацэньваць і ігнараваць вольныя «пілавінне» часу ў 5, 10, 15 хвілін, чакаць нейкіх вялікіх «бярвёнаў» працягласцю ў гадзіну ці два. Стаіце ў чарзе? Прадумайце нешта па вашым праекце. Падымаецеся па эскалатары? Запішыце нешта ў блакнот. Едзіце ў аўтобусе? Выдатна, прачытайце нейкі артыкул. Выкарыстоўвайце кожную магчымасць. Хопіць глядзець коцікаў і сабачак на YouTube! Не засмечвайце сабе мозг!

І апошняе. Калі, прачытаўшы гэты артыкул, вам спадабалася ідэя стварэння гульняў без выкарыстання гульнявых рухавічкоў, то запомніце імя Casey Muratori. У гэтага хлопца ёсць сайт. У секцыі "watch -> PREVIOUS EPISODES" вы знойдзеце цудоўныя бясплатныя відэаўрокі па стварэнні прафесійнай гульні з поўнага нуля. За пяць урокаў Intro to C for Windows вы, магчыма, даведаецеся больш, чым за пяць гадоў навучання ва ўніверсітэце (пра гэта нехта напісаў у каментарах пад відэа).

Таксама Кейсі тлумачыць, што, распрацаваўшы свой уласны гульнявы ​​рухавічок, вы будзеце лепш разумець любыя існуючыя рухавічкі. У свеце фрэймворкаў, дзе ўсё спрабуюць аўтаматызаваць, вы навучыцеся ствараць, а не выкарыстоўваць. Усведамляеце саму прыроду кампутараў. А таксама станеце значна больш талковым і сталым праграмістам – профі.

Удачы вам на абраным шляху! І давайце зробім свет больш прафесійным.

Аўтар: Гранкін Андрэй, DevOps



Крыніца: habr.com