DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven

“Ik weet dat ik niets weet” Socrates

Voor wie: voor IT-mensen die niet om alle ontwikkelaars geven en hun games willen spelen!

Waarover: over hoe je kunt beginnen met het schrijven van games in C/C++, als je het plotseling nodig hebt!

Waarom zou je dit lezen: Applicatieontwikkeling is niet mijn vakgebied, maar ik probeer wel wekelijks te coderen. Omdat ik van spelletjes houd!

Hallo mijn naam is Andrey Grankin, Ik ben DevOps bij Luxoft. Applicatieontwikkeling is niet mijn specialiteit, maar ik probeer elke week te coderen. Omdat ik van spelletjes houd!

De computergame-industrie is enorm, en er wordt gezegd dat deze zelfs groter is dan de huidige filmindustrie. Sinds het ontstaan ​​van computers worden games geschreven, waarbij naar moderne maatstaven complexe en basale ontwikkelingsmethoden worden gebruikt. Na verloop van tijd begonnen game-engines met reeds geprogrammeerde graphics, fysica en geluid te verschijnen. Ze zorgen ervoor dat je je kunt concentreren op het ontwikkelen van het spel zelf en dat je je geen zorgen hoeft te maken over de basis ervan. Maar samen met hen, met de motoren, worden ontwikkelaars ‘blind’ en degraderen ze. De productie van games zelf wordt op de lopende band gezet. En de kwantiteit van de producten begint de overhand te krijgen op de kwaliteit ervan.

Tegelijkertijd worden we bij het spelen van de games van anderen voortdurend beperkt door de locaties, het plot, de personages en de spelmechanismen die andere mensen hebben bedacht. Dus ik besefte dat...

... de tijd is gekomen om mijn eigen werelden te creëren, die alleen aan mij onderworpen zijn. Werelden waar ik de Vader, de Zoon en de Heilige Geest ben!

En ik geloof oprecht dat je, door je eigen game-engine te schrijven en erop te spelen, je schoenen kunt uittrekken, de ramen kunt vegen en je cabine kunt upgraden, waardoor je een meer ervaren en complete programmeur wordt.

In dit artikel zal ik proberen te vertellen hoe ik ben begonnen met het schrijven van kleine games in C/C++, hoe het ontwikkelproces verloopt en waar ik tijd vind voor een hobby in een drukke omgeving. Het is subjectief en beschrijft het proces van een individuele start. Materiaal over onwetendheid en geloof, over mijn persoonlijke wereldbeeld op dit moment. Met andere woorden: “De administratie is niet verantwoordelijk voor uw persoonlijke hersenen!”

Praktijk

“Kennis zonder praktijk is nutteloos, praktijk zonder kennis is gevaarlijk” Confucius

Mijn notitieboekje is mijn leven!


Dus in de praktijk kan ik zeggen dat voor mij alles begint met een notitieblok. Niet alleen schrijf ik daar mijn dagelijkse taken op, ik teken, programmeer, ontwerp stroomdiagrammen en los problemen op, ook wiskundige. Gebruik altijd een notitieblok en schrijf uitsluitend met potlood. Het is schoon, handig en betrouwbaar, IMHO.

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Mijn (al vol) notitieboekje. Dit is hoe hij eruit ziet. Het bevat alledaagse taken, ideeën, tekeningen, diagrammen, oplossingen, zwarte boekhouding, code enzovoort

In dit stadium ben ik erin geslaagd drie projecten te voltooien (dit is in mijn opvatting van “volledigheid”, omdat elk product relatief eindeloos kan worden ontwikkeld).

  • Project 0: Dit is een 3D Architect Demo-scène geschreven in C# met behulp van de Unity-game-engine. Voor macOS- en Windows-platforms.
  • Game 1: consolespel Simple Snake (bij iedereen bekend als “Snake”) voor Windows. Geschreven in C.
  • Game 2: consolespel Crazy Tanks (bij iedereen bekend als “Tanks”), geschreven in C++ (met behulp van klassen) en ook voor Windows.

Project 0. Architectendemo

  • platform: Windows (Windows 7, 10), Mac OS (OS X El Capitan v. 10.11.6)
  • Taal: C#
  • Game-engine: Eenheid
  • Inspiratie: Darrin Lile
  • Opslagplaats: GitHub

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Demo voor 3D-scènearchitect

Het eerste project werd niet in C/C++ geïmplementeerd, maar in C# met behulp van de Unity-game-engine. Deze motor was niet zo veeleisend op het gebied van hardware als Unreal Engine, en leek ook eenvoudiger te installeren en te gebruiken. Andere motoren heb ik niet overwogen.

Mijn doel in Unity was niet om een ​​game te ontwikkelen. Ik wilde een 3D-scène met een bepaald karakter creëren. Hij, of beter gezegd Zij (ik modelleerde het meisje op wie ik verliefd was =) moest bewegen en communiceren met de wereld om hem heen. Het was alleen belangrijk om te begrijpen wat Unity is, wat het ontwikkelingsproces is en hoeveel moeite er nodig is om iets te creëren. Zo ontstond het Architect Demo-project (de naam werd bijna uit het niets verzonnen). Programmeren, modelleren, animeren en texturen kostte me waarschijnlijk twee maanden dagelijks werk.

Ik begon met instructievideo's op YouTube over het maken van 3D-modellen in Blenders. Blender is een uitstekende gratis tool voor 3D-modellering (en meer) waarvoor geen installatie vereist is. En hier wachtte me een schok... Het blijkt dat modellering, animatie en texturen enorme afzonderlijke onderwerpen zijn waarover je boeken kunt schrijven. Dit geldt vooral voor karakters. Om vingers, tanden, ogen en andere lichaamsdelen te modelleren, heb je kennis van anatomie nodig. Hoe zijn de gezichtsspieren opgebouwd? Hoe bewegen mensen? Ik moest botten in elke arm, been, vinger en vingerkootjes van de vingers "inbrengen"!

Modelleer de sleutelbeenderen en extra hefboombeenderen om de animatie er natuurlijk uit te laten zien. Na zulke lessen besef je hoeveel werk de makers van animatiefilms verzetten om slechts 30 seconden video te maken. Maar 3D-films gaan uren mee! En dan verlaten we de bioscopen en zeggen iets als: “Dat is een onzin tekenfilm/film! Ze hadden het beter kunnen doen..." Dwazen!

En nog iets over programmeren in dit project. Het bleek dat het meest interessante deel voor mij het wiskundige deel was. Als je de scène uitvoert (link naar de repository in de projectbeschrijving), zul je merken dat de camera in een bol rond het meisjespersonage draait. Om zo'n rotatie van de camera te programmeren, moest ik eerst de coördinaten van het positiepunt op de cirkel (2D) berekenen, en vervolgens op de bol (3D). Het grappige is dat ik op school een hekel had aan wiskunde en het met een C-min kende. Gedeeltelijk waarschijnlijk omdat ze je op school simpelweg niet uitleggen hoe deze wiskunde in het leven wordt toegepast. Maar als je geobsedeerd bent door je doel, je droom, wordt je geest helder en open! En je begint moeilijke taken als een spannend avontuur te zien. En dan denk je: “Waarom zou je *favoriete* wiskundige je niet normaal kunnen vertellen waar deze formules kunnen worden toegepast?”

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Berekening van formules voor het berekenen van de coördinaten van een punt op een cirkel en op een bol (uit mijn notitieboekje)

Spel 1. Eenvoudige slang

  • platform: Windows (getest op Windows 7, 10)
  • Taal: Ik denk dat ik het in pure C heb geschreven
  • Game-engine: Windows-console
  • Inspiratie: javidx9
  • Opslagplaats: GitHub

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Eenvoudig slangenspel

Een 3D-scène is geen spel. Bovendien is het modelleren en animeren van 3D-objecten (vooral karakters) tijdrovend en moeilijk. Nadat ik met Unity had gespeeld, kwam het besef dat ik verder moest gaan, of beter gezegd, moest beginnen bij de basis. Iets eenvoudigs en snels, maar tegelijkertijd mondiaal, om de structuur van games te begrijpen.

Wat is eenvoudig en snel? Dat klopt, console en 2D. Om precies te zijn, zelfs de console en symbolen. Opnieuw ging ik op zoek naar inspiratie op internet (in het algemeen denk ik dat internet de meest revolutionaire en gevaarlijke uitvinding van de XNUMXe eeuw is). Ik heb een video opgegraven van een programmeur die console Tetris maakte. En in de gelijkenis van zijn spel besloot ik een "slang" te maken. Uit de video leerde ik twee fundamentele dingen: de gameloop (met drie basisfuncties/onderdelen) en uitvoer naar de buffer.

De spellus zou er ongeveer zo uit kunnen zien:

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

De code presenteert de volledige functie main() in één keer. En de spelcyclus begint na het juiste commentaar. Er zijn drie basisfuncties in de lus: Input(), Logic(), Draw(). Eerst invoer van gegevensinvoer (voornamelijk controle van toetsaanslagen), vervolgens verwerking van de ingevoerde gegevens Logica, en vervolgens uitvoer naar het scherm - Tekenen. En zo op elk frame. Zo ontstaat animatie. Het is net als in tekenfilms. Normaal gesproken kost het verwerken van de ingevoerde gegevens de meeste tijd en wordt, voor zover ik weet, de framesnelheid van het spel bepaald. Maar hier wordt de functie Logic() zeer snel uitgevoerd. Daarom moet je de framesnelheid regelen met behulp van de Sleep()-functie met de gameSpeed-parameter, die deze snelheid bepaalt.

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Spelcyclus. Programmeren van een “slang” in een notitieblok

Als je een op karakters gebaseerd consolespel ontwikkelt, kun je geen gegevens naar het scherm uitvoeren met behulp van de reguliere 'cout'-streamuitvoer - dat is erg traag. Daarom moet de uitvoer naar de schermbuffer worden gestuurd. Dit is veel sneller en het spel draait zonder problemen. Eerlijk gezegd begrijp ik niet helemaal wat een schermbuffer is en hoe deze werkt. Maar ik zal hier een voorbeeldcode geven, en misschien kan iemand de situatie in de opmerkingen verduidelijken.

Een schermbuffer verkrijgen (om zo te zeggen):

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

Directe weergave van een bepaalde string scoreLine (partituurweergaveregel):

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

In theorie is er niets ingewikkelds aan dit spel; ik denk dat het een goed instapvoorbeeld is. De code wordt in één bestand geschreven en in verschillende functies opgemaakt. Geen klassen, geen erfenis. Je kunt alles zelf zien in de broncode van het spel door naar de repository op GitHub te gaan.

Spel 2. Gekke tanks

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Spel Gekke tanks

Het afdrukken van karakters op de console is waarschijnlijk het eenvoudigste wat je in een spel kunt veranderen. Maar dan ontstaat er één probleem: de symbolen hebben verschillende hoogtes en breedtes (de hoogte is groter dan de breedte). Op deze manier ziet alles er buiten proporties uit en zal naar beneden of naar boven bewegen veel sneller lijken dan naar links of rechts bewegen. Dit effect is erg merkbaar in Snake (Game 1). "Tanks" (Game 2) hebben dit nadeel niet, omdat de uitvoer daar wordt georganiseerd door de schermpixels met verschillende kleuren te verven. Je zou kunnen zeggen dat ik een renderer heb geschreven. Toegegeven, dit is iets ingewikkelder, hoewel veel interessanter.

Voor dit spel is het voldoende om mijn systeem voor het weergeven van pixels op het scherm te beschrijven. Ik beschouw dit als het belangrijkste onderdeel van het spel. En de rest kun je zelf bedenken.

Wat u dus op het scherm ziet, is slechts een reeks bewegende, veelkleurige rechthoeken.

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Set rechthoeken

Elke rechthoek wordt weergegeven door een matrix gevuld met cijfers. Ik kan trouwens één interessante nuance benadrukken: alle matrices in het spel zijn geprogrammeerd als een eendimensionale array. Niet tweedimensionaal, maar eendimensionaal! Eendimensionale arrays zijn veel eenvoudiger en sneller om mee te werken.

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Voorbeeld van een gametankmatrix

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Weergave van de speltankmatrix als een eendimensionale array

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Een meer visueel voorbeeld van het weergeven van een matrix als een eendimensionale array

Maar toegang tot de elementen van de array vindt plaats in een dubbele lus, alsof het geen eendimensionale array is, maar een tweedimensionale. Dit wordt gedaan omdat wij nog steeds met matrices werken.

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Het doorkruisen van een eendimensionale array in een dubbele lus. Y - rij-ID, X - kolom-ID

Let op: in plaats van de gebruikelijke matrixidentificatoren i, j, gebruik ik de identificatoren x en y. Op deze manier lijkt het mij prettiger voor het oog en begrijpelijker voor de hersenen. Bovendien maakt een dergelijke notatie het mogelijk om de gebruikte matrices gemakkelijk te projecteren op de coördinaatassen van een tweedimensionaal beeld.

Nu over pixels, kleur en schermuitvoer. De StretchDIBits-functie wordt gebruikt voor uitvoer (Header: windows.h; Bibliotheek: gdi32.lib). Deze functie ontvangt onder meer het volgende: het apparaat waarop de afbeelding wordt weergegeven (in mijn geval is dit de Windows-console), de startcoördinaten van de afbeeldingsweergave, de breedte/hoogte ervan en de afbeelding zelf in de vorm van een bitmap, weergegeven door een array van bytes. Bitmap als byte-array!

StretchDIBits()-functie in actie:

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

Voor deze bitmap wordt vooraf geheugen toegewezen met behulp van de functie VirtualAlloc(). Dat wil zeggen dat het vereiste aantal bytes wordt gereserveerd om informatie over alle pixels op te slaan, die vervolgens op het scherm wordt weergegeven.

De m_p_bitmapMemory-bitmap maken:

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

Grofweg bestaat een bitmap uit een verzameling pixels. Elke vier bytes in de array is een RGB-pixel. Eén byte per rode kleurwaarde, één byte per groene kleurwaarde (G) en één byte per blauwe kleurwaarde (B). Bovendien is er nog één byte over voor inspringen. Deze drie kleuren - Rood/Groen/Blauw (RGB) - worden in verschillende verhoudingen met elkaar gemengd om de resulterende pixelkleur te creëren.

Ook nu wordt elke rechthoek of spelobject weergegeven door een numerieke matrix. Al deze spelobjecten worden in een verzameling geplaatst. En vervolgens worden ze op het speelveld geplaatst en vormen ze één grote numerieke matrix. Ik heb elk getal in de matrix aan een specifieke kleur gekoppeld. Het getal 8 komt bijvoorbeeld overeen met blauw, het getal 9 met geel, het getal 10 met donkergrijs, enzovoort. We kunnen dus zeggen dat we een matrix van het speelveld hebben, waarbij elk getal een kleur heeft.

We hebben dus aan de ene kant een numerieke matrix van het hele speelveld en aan de andere kant een bitmap voor het weergeven van de afbeelding. Tot nu toe is de bitmap "leeg" - deze bevat nog geen informatie over de pixels van de gewenste kleur. Dit betekent dat de laatste stap het vullen van de bitmap zal zijn met informatie over elke pixel op basis van de numerieke matrix van het speelveld. Een duidelijk voorbeeld van een dergelijke transformatie staat in de onderstaande afbeelding.

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Een voorbeeld van het vullen van een bitmap (pixelmatrix) met informatie op basis van de digitale matrix van het speelveld (kleurindexen komen niet overeen met de indices in het spel)

Ik zal ook een stukje echte code uit het spel presenteren. De variabele colorIndex krijgt bij elke iteratie van de lus een waarde (kleurindex) toegewezen uit de numerieke matrix van het speelveld (mainDigitalMatrix). De kleurvariabele wordt vervolgens op de kleur zelf ingesteld op basis van de index. De resulterende kleur wordt vervolgens verdeeld in de verhouding rood, groen en blauw (RGB). En samen met de pixelPadding wordt deze informatie keer op keer in de pixel geschreven, waardoor een kleurenafbeelding in de bitmap ontstaat.

De code maakt gebruik van pointers en bitsgewijze bewerkingen, wat moeilijk te begrijpen kan zijn. Ik raad je dus aan om ergens apart te lezen hoe dergelijke structuren werken.

De bitmap vullen met informatie op basis van de numerieke matrix van het speelveld:

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

Volgens de hierboven beschreven methode wordt in het spel Crazy Tanks één afbeelding (frame) gevormd en op het scherm weergegeven in de functie Draw(). Na het registreren van toetsaanslagen in de functie Input() en de daaropvolgende verwerking ervan in de functie Logic() wordt een nieuw beeld (frame) gevormd. Het is waar dat spelobjecten al een andere positie op het speelveld hebben en dienovereenkomstig op een andere plaats worden getekend. Dit is hoe animatie (beweging) plaatsvindt.

In theorie (als ik niets ben vergeten) is het begrijpen van de gameloop uit het eerste spel ("Snake") en het systeem voor het weergeven van pixels op het scherm uit het tweede spel ("Tanks") alles wat je nodig hebt om iets te schrijven van uw 2D-games onder Windows. Geluidloos! 😉 De rest van de onderdelen is slechts een fantasietje.

Natuurlijk is het spel "Tanks" veel complexer dan "Snake". Ik heb de taal C++ al gebruikt, dat wil zeggen dat ik verschillende spelobjecten met klassen heb beschreven. Ik heb mijn eigen verzameling gemaakt - de code kan worden bekeken in headers/Box.h. Overigens heeft de collectie hoogstwaarschijnlijk een geheugenlek. Gebruikte wijzers. Gewerkt met geheugen. Ik moet zeggen dat het boek mij enorm heeft geholpen Beginnen met C++ via gameprogrammering. Dit is een goede start voor beginners in C++. Het is klein, interessant en goed georganiseerd.

Het duurde ongeveer zes maanden om dit spel te ontwikkelen. Ik schreef voornamelijk tijdens de lunch en tussendoortjes op het werk. Hij zat in de kantoorkeuken, vertrapte eten en schreef code. Of tijdens het etentje thuis. Dus eindigde ik met deze ‘keukenoorlogen’. Zoals altijd gebruikte ik actief een notitieboekje en alle conceptuele dingen werden erin geboren.

Om het praktische gedeelte af te ronden, maak ik een paar scans van mijn notitieboekje. Om te laten zien wat ik precies heb opgeschreven, getekend, geteld, ontworpen...

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Afbeeldingen van tanks ontwerpen. En bepalen hoeveel pixels elke tank op het scherm moet innemen

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Berekening van het algoritme en formules voor de rotatie van de tank om zijn as

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
Schema van mijn verzameling (die waarin hoogstwaarschijnlijk een geheugenlek zit). De collectie wordt gemaakt volgens het type Gekoppelde lijst

DevOps C++ en "keukenoorlogen", of hoe ik tijdens het eten games begon te schrijven
En dit zijn nutteloze pogingen om kunstmatige intelligentie aan het spel te koppelen

Теория

“Zelfs een reis van duizend mijl begint met de eerste stap” (Oude Chinese wijsheid)

Laten we van praktijk naar theorie gaan! Hoe vind je tijd voor je hobby?

  1. Bepaal wat je echt wilt (helaas, dit is het moeilijkste deel).
  2. Prioriteiten stellen.
  3. Offer alles ‘extra’ op ter wille van hogere prioriteiten.
  4. Ga elke dag richting doelen.
  5. Verwacht niet dat je twee of drie uur vrije tijd aan een hobby besteedt.

Aan de ene kant moet je bepalen wat je wilt en prioriteiten stellen. Aan de andere kant is het mogelijk om bepaalde activiteiten/projecten op te geven ten gunste van deze prioriteiten. Met andere woorden, je zult alles “extra” moeten opofferen. Ik heb ergens gehoord dat er maximaal drie hoofdactiviteiten in het leven mogen zijn. Dan kun je ze op de hoogste kwaliteit uitvoeren. En aanvullende projecten/richtingen zullen eenvoudigweg overbelast raken. Maar dit is waarschijnlijk allemaal subjectief en individueel.

Er is een bepaalde gouden regel: heb nooit een 0%-dag! Ik hoorde erover in een artikel van een indie-ontwikkelaar. Als je aan een project werkt, doe er dan elke dag iets aan. En het maakt niet uit hoeveel je doet. Schrijf één woord of één regel code, bekijk één instructievideo of sla één spijker in een bord - doe gewoon iets. Het moeilijkste is om te beginnen. Als je eenmaal begint, zul je waarschijnlijk iets meer doen dan je wilde. Zo kom je voortdurend op weg naar je doel en, geloof me, heel snel. Het belangrijkste obstakel voor alle dingen is immers uitstelgedrag.

En het is belangrijk om te onthouden dat je het gratis "zaagsel" van een tijd van 5, 10, 15 minuten niet moet onderschatten en negeren, wacht op enkele grote "blokken" die een uur of twee duren. Sta je in de rij? Bedenk iets voor uw project. De roltrap nemen? Schrijf iets op in een notitieblok. Reist u met de bus? Geweldig, lees een artikel. Profiteer van elke kans. Kijk niet langer naar katten en honden op YouTube! Vervuil je hersenen niet!

En nog een laatste ding. Als je na het lezen van dit artikel het idee leuk vond om games te maken zonder game-engines te gebruiken, onthoud dan de naam Casey Muratori. Deze man heeft сайт. In de sectie "bekijken -> VORIGE EPISODEN" vindt u prachtige gratis video-tutorials over het helemaal opnieuw maken van een professioneel spel. In vijf lessen Intro to C for Windows leer je waarschijnlijk meer dan in vijf jaar universitaire studie (iemand schreef hierover in de reacties onder de video).

Casey legt ook uit dat je door het ontwikkelen van je eigen game-engine een beter inzicht krijgt in de bestaande engine. In een wereld vol raamwerken waarin iedereen probeert te automatiseren, leer je creëren in plaats van gebruiken. Je begrijpt de aard van computers. En je zult ook een veel intelligentere en volwassener programmeur worden - een professional.

Veel succes op jouw gekozen pad! En laten we de wereld professioneler maken.

auteur: Grankin Andrey, DevOps



Bron: www.habr.com