DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».

«Мен ештеңе білмейтінімді білемін» Сократ

Кім үшін: барлық әзірлеушілерге түкіретін және олардың ойындарын ойнағысы келетін IT адамдары үшін!

Не жайлы: қажет болса, C/C++ тілінде ойын жазуды қалай бастау керек!

Мұны не үшін оқу керек: Қолданба әзірлеу менің жұмыс мамандығым емес, бірақ мен апта сайын кодтауға тырысамын. Өйткені мен ойындарды жақсы көремін!

Сәлем менің атым Андрей Гранкин, Мен Luxoft компаниясының DevOps қызметкерімін. Қолданбаларды әзірлеу менің жұмыс мамандығым емес, бірақ мен апта сайын кодтауға тырысамын. Өйткені мен ойындарды жақсы көремін!

Компьютерлік ойындар индустриясы орасан зор, бүгінде киноиндустриядан да көп қауесет. Ойындар қазіргі заманғы стандарттар бойынша күрделі және негізгі даму әдістерін қолдана отырып, компьютерлер пайда болғаннан бері жазылды. Уақыт өте келе бағдарламаланған графика, физика және дыбыс бар ойын қозғалтқыштары пайда бола бастады. Олар ойынның өзін дамытуға назар аударуға және оның негізі туралы алаңдамауға мүмкіндік береді. Бірақ олармен бірге қозғалтқыштармен бірге әзірлеушілер «соқыр болып» және нашарлайды. Ойындардың өзі конвейерге қойылады. Ал оның сапасына қарағанда өнім саны басым бола бастайды.

Сонымен қатар, басқа адамдардың ойындарын ойнаған кезде, біз үнемі басқа адамдар ойлап тапқан орындармен, сюжеттермен, кейіпкерлермен, ойын механикасымен шектелеміз. Сондықтан мен түсіндім ...

... тек маған бағынатын өз әлемдеріңізді жасайтын кез келді. Мен Әке, Ұл және Киелі Рух болатын әлемдер!

Мен өз ойын қозғалтқышыңызды және оған ойын жазу арқылы сіз тәжірибелі және интегралды бағдарламашы бола отырып, көзіңізді ашып, терезелерді сүртіп, кабинаңызды сорып алатыныңызға шын жүректен сенемін.

Бұл мақалада мен C / C ++ тілінде шағын ойындарды қалай жазуды бастағанымды, даму процесі дегеніміз не және бос емес ортада хоббиге уақытты қайдан табатынымды айтуға тырысамын. Ол субъективті және жеке бастау процесін сипаттайды. Надандық пен сенім туралы материал, қазіргі кездегі әлем туралы жеке суретім туралы. Басқаша айтқанда, «Әкімшілік сіздің жеке миыңызға жауап бермейді!».

Тәжірибе

«Тәжірибесіз білім пайдасыз, білімсіз тәжірибе қауіпті» Конфуций

Менің дәптерім менің өмірім!


Сонымен, іс жүзінде мен үшін барлығы дәптерден басталады деп айта аламын. Онда мен күнделікті тапсырмаларды ғана жазып қоймай, сонымен қатар сызып, бағдарламалап, блок-схемаларын құрастырып, есептер шығарамын, соның ішінде математикалық. Әрқашан блокнот пайдаланыңыз және тек қарындашпен жазыңыз. Бұл таза, ыңғайлы және сенімді, IMHO.

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Менің (толтырылған) дәптерім. Бұл осылай көрінеді. Онда күнделікті тапсырмалар, идеялар, сызбалар, диаграммалар, шешімдер, қара бухгалтерия, код және т.б.

Осы кезеңде мен үш жобаны аяқтадым (бұл менің түсінігім бойынша «түпкілікті», өйткені кез келген өнімді салыстырмалы түрде шексіз әзірлеуге болады).

  • 0-жоба: бұл Unity ойын механизмі арқылы C# тілінде жазылған Architect Demo 3D көрінісі. macOS және Windows платформалары үшін.
  • Ойын 1: Windows жүйесіне арналған Simple Snake консольдық ойыны (барлығына «Жылан» ретінде белгілі). C тілінде жазылған.
  • Ойын 2: Crazy Tanks консольдық ойыны (барлығына «Танк» деген атпен белгілі), қазірдің өзінде C ++ тілінде (сыныптарды пайдалану) және Windows жүйесінде жазылған.

Жоба 0 Сәулетші демо

  • Платформа: Windows (Windows 7, 10), Mac OS (OS X El Capitan v. 10.11.6)
  • Тіл: C#
  • Ойын қозғалтқышы: бірлік
  • Шабыт: Даррин Лил
  • Репозиторий: GitHub

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
3D Scene Architect демонстрациясы

Бірінші жоба C/C++ тілінде емес, C# тілінде Unity ойын механизмі арқылы жүзеге асырылды. Бұл қозғалтқыш аппараттық құрал сияқты талап етілмеді Unreal Engine, сонымен қатар маған орнату және пайдалану оңайырақ болып көрінді. Мен басқа қозғалтқыштарды қарастырмадым.

Бірлікте мен үшін мақсат ойын түрін дамыту емес еді. Мен қандай да бір кейіпкері бар 3D көріністі жасағым келді. Ол, дәлірек айтсақ, Ол (мен ғашық болған қызды үлгі еттім =) қозғалып, сыртқы әлеммен араласуы керек еді. Бірлік дегеннің не екенін, даму үдерісінің не екенін және бір нәрсені жасау үшін қанша күш жұмсалатынын түсіну ғана маңызды болды. Сәулетші демо жобасы осылай дүниеге келді (атауы ақымақтықтан ойлап тапты). Бағдарламалау, модельдеу, анимация, текстуралау маған екі ай күнделікті жұмысты қажет етті.

Мен YouTube сайтында 3D модельдерін жасау туралы оқулық бейнелерден бастадым Блендер. Блендер - орнатуды қажет етпейтін 3D модельдеу (және т.б.) үшін тамаша тегін құрал. Міне, мені шок күтіп тұрды... Модельдеу, анимация, текстуралау кітап жазуға болатын үлкен бөлек тақырыптар екені белгілі болды. Бұл әсіресе кейіпкерлерге қатысты. Саусақтарды, тістерді, көздерді және дененің басқа бөліктерін модельдеу үшін сізге анатомияны білу қажет. Бет бұлшықеттері қалай орналасады? Адамдар қалай қозғалады? Мен әр қолға, аяққа, саусаққа, буындарға сүйектерді «кіргізу» керек болды!

Анимация табиғи көрінуі үшін бұғана, қосымша сүйек рычагтарын модельдеңіз. Осындай сабақтардан кейін сіз анимациялық фильм жасаушылардың 30 секундтық бейнені жасау үшін қандай үлкен жұмыс атқаратынын түсінесіз. Бірақ 3D фильмдері бірнеше сағатқа созылады! Содан кейін біз театрлардан шығып, бірдеңе айтамыз: «Та, сұмдық мультфильм / фильм! Олар жақсырақ істей алар еді...» Ақымақ!

Бұл жобада бағдарламалау туралы тағы бір нәрсе. Белгілі болғандай, мен үшін ең қызықтысы математикалық бөлім болды. Егер сіз көріністі іске қоссаңыз (жоба сипаттамасындағы репозиторийге сілтеме), камераның сферадағы қыз кейіпкерінің айналасында айналатынын байқайсыз. Камераның мұндай айналуын бағдарламалау үшін алдымен шеңбердегі (2D), содан кейін сферада (3D) орналасу нүктесінің координаталарын есептеу керек болды. Бір қызығы, мен мектепте математиканы жек көретінмін және оны минуспен білетінмін. Ішінара, мүмкін, мектепте олар сізге бұл математиканың өмірде қалай қолданылатынын түсіндірмейді. Бірақ мақсатыңа, арманыңа батқанда санаң тазарады, ашылады! Ал сіз күрделі тапсырмаларды қызықты шытырман оқиға ретінде қабылдай бастайсыз. Сосын сіз ойлайсыз: «Неліктен *сүйікті* математик бұл формулаларды қай жерге сүйенуге болатынын айта алмады?».

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Шеңбердегі және шардағы нүктенің координаталарын есептеу формулаларын есептеу (дәптерімнен)

Ойын 1

  • Платформа: Windows (Windows 7, 10 жүйелерінде тексерілген)
  • Тіл: Менің ойымша, бұл таза С тілінде жазылған
  • Ойын қозғалтқышы: Windows консолі
  • Шабыт: javidx9
  • Репозиторий: GitHub

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Қарапайым Жылан ойыны

3D көрініс ойын емес. Сонымен қатар, 3D нысандарын (әсіресе кейіпкерлерді) модельдеу және анимациялау ұзақ және қиын. Бірлікпен ойнағаннан кейін, мен жалғастыру керек екенін түсіндім, дәлірек айтсақ, негізгілерден бастау керек. Ойындардың құрылымын түсіну үшін қарапайым және жылдам, бірақ сонымен бірге жаһандық нәрсе.

Ал бізде қарапайым және жылдам не бар? Дұрыс, консоль және 2D. Дәлірек айтқанда, тіпті консоль мен таңбалар. Мен қайтадан интернеттен шабыт іздей бастадым (жалпы, мен Интернетті XNUMX ғасырдың ең революциялық және қауіпті өнертабысы деп санаймын). Мен консольді Tetris жасаған бір бағдарламашының бейнесін қазып алдым. Ал өз ойынына ұқсап, «жыланды» кесіп тастауды ұйғарды. Бейнеден мен екі негізгі нәрсе туралы білдім - ойын циклі (үш негізгі функциясы/бөлігі бар) және буферге шығару.

Ойын циклі келесідей болуы мүмкін:

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

Код барлық негізгі() функциясын бірден көрсетеді. Ал ойын циклі сәйкес түсініктемеден кейін басталады. Циклда үш негізгі функция бар: Input(), Logic(), Draw(). Алдымен деректерді енгізу Енгізу (негізінен пернелерді басу арқылы басқару), содан кейін енгізілген деректерді өңдеу Logic, содан кейін экранда көрсету - Сурет салу. Және де әрбір кадр. Анимация осылай жасалады. Бұл мультфильмдер сияқты. Әдетте кіріс деректерін өңдеу көп уақытты алады және менің білуімше, ойынның кадр жиілігін анықтайды. Бірақ мұнда 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);

Белгілі бір сызықтың экранына тікелей шығару ұпайLine (ұпайларды көрсетуге арналған сызық):

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

Теориялық тұрғыдан, бұл ойында күрделі ештеңе жоқ, бұл маған бастапқы деңгейдегі ойынның жақсы үлгісі болып көрінеді. Код бір файлда жазылады және бірнеше функцияларда орналасады. Сыныптар жоқ, мұра жоқ. Сіз GitHub репозиторийіне өту арқылы ойынның бастапқы кодында барлығын көре аласыз.

Ойын 2 Crazy Tanks

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Crazy Tanks ойыны

Консольге кейіпкерлерді басып шығару ойынға айналдыруға болатын ең қарапайым нәрсе болуы мүмкін. Бірақ содан кейін бір қиындық пайда болады: кейіпкерлердің биіктігі мен ені әртүрлі (биіктігі енінен үлкен). Осылайша, бәрі пропорционалды емес болып көрінеді және төмен немесе жоғары жылжу солға немесе оңға жылжудан әлдеқайда жылдамырақ көрінеді. Бұл әсер «Жыланда» (1-ойын) өте байқалады. «Танктерде» (2-ойын) мұндай кемшілік жоқ, өйткені ондағы шығу экран пикселдерін әртүрлі түстермен бояу арқылы ұйымдастырылады. Мен рендерер жаздым деп айтуға болады. Рас, бұл әлдеқайда күрделірек, бірақ әлдеқайда қызықты.

Бұл ойын үшін экранда пикселдерді көрсетуге арналған жүйені сипаттау жеткілікті болады. Менің ойымша, бұл ойынның негізгі бөлігі. Ал қалғанының бәрін өзіңіз ойлап таба аласыз.

Сонымен, экранда көретін нәрсе - бұл қозғалатын түрлі-түсті төртбұрыштардың жиынтығы.

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Тіктөртбұрыштар жинағы

Әрбір тіктөртбұрыш сандармен толтырылған матрицамен ұсынылған. Айтпақшы, мен бір қызықты нюансты атап өте аламын - ойындағы барлық матрицалар бір өлшемді массив ретінде бағдарламаланған. Екі өлшемді емес, бір өлшемді! Бір өлшемді массивтермен жұмыс істеу әлдеқайда оңай және жылдамырақ.

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Ойын танкінің матрицасының мысалы

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Бір өлшемді массивпен ойын танкінің матрицасын көрсету

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Бір өлшемді массив арқылы матрицаны көрсетудің көрнекі мысалы

Бірақ массивтің элементтеріне қол жеткізу бір өлшемді емес, екі өлшемді массив сияқты қос циклде жүреді. Бұл әлі де матрицалармен жұмыс істеп жатқандықтан жасалды.

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Қос циклде бір өлшемді массивті өту. Y - жол идентификаторы, X - баған идентификаторы

Кәдімгі i, j матрицалық идентификаторларының орнына x және y идентификаторларын қолданатынымды ескеріңіз. Демек, бұл маған көзге ұнамдырақ, миға айқынырақ көрінеді. Сонымен қатар, мұндай белгілеу екі өлшемді кескіннің координат осіне қолданылатын матрицаларды ыңғайлы түрде проекциялауға мүмкіндік береді.

Енді пикселдер, түс және дисплей туралы. Шығару үшін StretchDIBits функциясы (Тақырып: windows.h; Кітапхана: gdi32.lib) пайдаланылады. Басқа нәрселермен қатар, бұл функцияға келесілер беріледі: сурет көрсетілетін құрылғы (менің жағдайда бұл Windows консолі), кескінді көрсетуді бастау координаттары, оның ені / биіктігі және кескін өзі байттардың массивімен ұсынылған нүктелік кескін (разрядтық кескін) түрінде. Растрлық байттардың массиві ретінде!

Жұмыстағы 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). Сонымен қатар, шегініс үшін бір байт бар. Бұл үш түс - Қызыл / Жасыл / Көк (RGB) - әртүрлі пропорцияларда бір-бірімен араласады - нәтижесінде пиксель түсі алынады.

Енді тағы да әрбір тіктөртбұрыш немесе ойын нысаны сандық матрица арқылы берілген. Осы ойын нысандарының барлығы жинаққа орналастырылған. Содан кейін олар бір үлкен сандық матрицаны құра отырып, ойын алаңына орналастырылады. Мен матрицадағы әрбір санды белгілі бір түспен салыстырдым. Мысалы, 8 саны көк, 9 саны сары, 10 саны қою сұр т.б. Осылайша, бізде ойын өрісінің матрицасы бар деп айта аламыз, онда әрбір сан қандай да бір түсті болады.

Сонымен, бізде бір жағынан бүкіл ойын өрісінің сандық матрицасы, ал екінші жағынан кескінді көрсетуге арналған нүктелік кескін бар. Әзірге растрлық кескін «бос» - оның қажетті түстің пикселдері туралы ақпараты әлі жоқ. Бұл соңғы қадам нүктелік кескінді ойын өрісінің сандық матрицасына негізделген әрбір пиксел туралы ақпаратпен толтыру болатынын білдіреді. Мұндай түрлендірудің көрнекі мысалы төмендегі суретте.

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Ойын өрісінің сандық матрицасына (Сандық матрица) негізделген ақпаратпен нүктелік кескінді (пиксельдік матрица) толтыру мысалы (түс индекстері ойындағы индекстерге сәйкес келмейді)

Мен ойыннан нақты кодтың бір бөлігін ұсынамын. Циклдің әрбір итерациясында colorIndex айнымалысына ойын өрісінің (mainDigitalMatrix) сандық матрицасынан мән (түс индексі) тағайындалады. Содан кейін түстің өзі индекс негізінде түс айнымалысына жазылады. Әрі қарай, алынған түс қызыл, жасыл және көк (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() функциясында кейіннен өңдеуден кейін жаңа сурет (кадр) қалыптасады. Рас, ойын нысандары ойын алаңында басқа позицияға ие болуы мүмкін және сәйкесінше басқа жерде сызылады. Анимация (қозғалыс) осылай болады.

Теориялық тұрғыдан (егер сіз ештеңені ұмытпаған болсаңыз), бірінші ойындағы («Жылан») ойын циклін және екінші ойыннан («Танк») экранда пикселдерді көрсету жүйесін түсіну - кез келген нәрсені жазу үшін қажет. Windows жүйесіне арналған 2D ойындарыңыздың. Дауыссыз! 😉 Қалған бөліктер жай ғана қиял ұшағы.

Әрине, «Танк» ойыны «Жыланға» қарағанда әлдеқайда күрделірек жобаланған. Мен C++ тілін қолдандым, яғни сыныптары бар әртүрлі ойын нысандарын сипаттадым. Мен өз коллекциямды жасадым - кодты headers/Box.h ішінен көре аласыз. Айтпақшы, коллекцияда жадтың ағып кетуі ықтимал. Қолданылған көрсеткіштер. Есте сақтаумен жұмыс жасады. Кітаптың маған көп көмегі тигенін айтуым керек. Ойындық бағдарламалау арқылы C++ тілін бастау. Бұл C++ тілін жаңадан бастаушылар үшін тамаша бастама. Бұл кішкентай, қызықты және жақсы ұйымдастырылған.

Бұл ойынды әзірлеуге шамамен алты ай қажет болды. Негізінен жұмыста түскі және жеңіл тамақ кезінде жаздым. Кеңсе асханасында отырып, тамақты таптап, код жазды. Немесе кешкі асқа үйде. Сондықтан менде осындай «асхана соғыстары» болды. Әдеттегідей, мен блокнотты белсенді қолдандым және барлық концептуалды нәрселер оның ішінде дүниеге келді.

Практикалық бөлімнің соңында мен дәптерімнің бірнеше сканерін шығарамын. Нені жазып, сызып, санап, жобалағанымды көрсету үшін...

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Танк кескінінің дизайны. Әр резервуардың экранда қанша пиксельді алуы керектігі туралы анықтама

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Резервуардың өз осінің айналасында айналу алгоритмі мен формулаларын есептеу

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Менің коллекциямның диаграммасы (жады ағып кеткен, ең алдымен). Жинақ Байланыстырылған тізім ретінде жасалған

DevOps C++ және «ас үйдегі соғыстар», немесе «Мен тамақ ішіп отырып, ойын жаза бастадым».
Бұл жасанды интеллектті ойынға қосудың бекер әрекеттері

Теория

«Тіпті мың шақырымдық жол да бірінші қадамнан басталады» (Ежелгі Қытай даналығы)

Практикадан теорияға көшейік! Сіз хоббиіңізге уақытты қалай табасыз?

  1. Сіз шынымен не қалайтыныңызды анықтаңыз (өкінішке орай, бұл ең қиын).
  2. Басымдықтарды орнату.
  3. Жоғары басымдықтар үшін барлық «артықтарды» құрбан етіңіз.
  4. Күн сайын мақсаттарыңызға қарай жылжыңыз.
  5. Хобби үшін екі-үш сағат бос уақыт болады деп күтпеңіз.

Бір жағынан, сіз өзіңіз қалаған нәрсені анықтап, басымдық беруіңіз керек. Екінші жағынан, осы басымдықтардың пайдасына кейбір істерден/жобалардан бас тартуға болады. Басқаша айтқанда, сіз «артық» бәрін құрбан етуге тура келеді. Өмірде ең көбі үш негізгі әрекет болуы керек деп бір жерден естідім. Сонда сіз олармен ең жақсы жолмен күресе аласыз. Ал қосымша жобалар/бағыттар corny шамадан тыс жүктеле бастайды. Бірақ мұның бәрі, мүмкін, субъективті және жеке.

Белгілі бір алтын ереже бар: ешқашан 0% күн болмайды! Мен бұл туралы инди әзірлеушісінің мақаласынан білдім. Егер сіз жобамен жұмыс істеп жатсаңыз, онда ол туралы күн сайын бірдеңе жасаңыз. Және қанша жасағаныңыз маңызды емес. Бір сөзді немесе кодтың бір жолын жазыңыз, бір оқулық бейнені қараңыз немесе тақтаға бір шеге соғыңыз — жай ғана бірдеңе жасаңыз. Ең қиыны - бастау. Сіз бастағаннан кейін, сіз қалағаныңыздан біраз көп нәрсені жасай аласыз. Осылайша сіз әрқашан мақсатыңызға қарай жылжисыз және маған сеніңіз, өте жылдам. Өйткені, барлық нәрсенің басты тежегіші - кейінге қалдыру.

Және 5, 10, 15 минутта уақыттың бос «үгінділерін» елемеуге және елемеуге болмайды, бір-екі сағатқа созылатын кейбір үлкен «бөренелер» күту керек екенін есте ұстаған жөн. Сіз кезекте тұрсыз ба? Жобаңыз үшін бір нәрсе туралы ойланыңыз. Сіз эскалатормен көтерілесіз бе? Дәптерге бірдеңе жазып ал. Сіз автобуста тамақ ішесіз бе? Жарайды, мақаланы оқыңыз. Әр мүмкіндікті пайдаланыңыз. YouTube-те мысықтар мен иттерді көруді доғарыңыз! Миыңызбен араласпаңыз!

Және соңғысы. Егер осы мақаланы оқығаннан кейін сізге ойын қозғалтқыштарын пайдаланбай ойын жасау идеясы ұнаса, Кейси Муратори есімін есте сақтаңыз. Бұл жігітте бар веб-сайт. «Көру -> АЛДЫҢҒЫ ЭПИСОДТАР» бөлімінде сіз нөлден бастап кәсіби ойынды қалай жасауға болатыны туралы таңғажайып тегін бейне оқулықтарды таба аласыз. Windows жүйесіне арналған C-ге кіріспе бес сабағында сіз университетте бес жыл оқығаннан көп нәрсені білуіңіз мүмкін (бұл туралы біреу бейне астындағы түсініктемелерде жазған).

Кейси сонымен қатар өз ойын қозғалтқышын жасау арқылы сіз кез келген бар қозғалтқыштарды жақсырақ түсінесіз деп түсіндіреді. Барлығы автоматтандыруға тырысатын фреймворктар әлемінде сіз пайдалануды емес, жасауды үйренесіз. Компьютерлердің табиғатын түсіну. Сондай-ақ, сіз әлдеқайда ақылды және жетілген бағдарламашы - кәсіпқой боласыз.

Таңдаған жолыңызда сәттілік! Ал әлемді кәсіпқой етейік.

автор: Гранкин Андрей, DevOps



Ақпарат көзі: www.habr.com