DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant

"Je sais que je ne sais rien" Socrate

Pour qui: pour les informaticiens qui crachent sur tous les développeurs et veulent jouer à leurs jeux !

À propos de quoi: comment commencer à écrire des jeux en C/C++ si vous en avez besoin !

Pourquoi devriez-vous lire ceci : Le développement d'applications n'est pas ma spécialité professionnelle, mais j'essaie de coder chaque semaine. Parce que j'aime les jeux !

Bonjour, mon nom est Andrey Grankin, je suis DevOps chez Luxoft. Le développement d'applications n'est pas ma spécialité professionnelle, mais j'essaie de coder chaque semaine. Parce que j'aime les jeux !

L'industrie des jeux informatiques est énorme, encore plus répandue aujourd'hui que l'industrie du cinéma. Les jeux ont été écrits depuis le début du développement des ordinateurs, en utilisant, selon les normes modernes, des méthodes de développement complexes et basiques. Au fil du temps, des moteurs de jeu ont commencé à apparaître avec des graphismes, une physique et un son déjà programmés. Ils vous permettent de vous concentrer sur le développement du jeu lui-même et de ne pas vous soucier de sa fondation. Mais avec eux, avec les moteurs, les développeurs « deviennent aveugles » et se dégradent. La production même des jeux est mise sur le convoyeur. Et la quantité de production commence à prévaloir sur sa qualité.

En même temps, lorsque nous jouons aux jeux d'autres personnes, nous sommes constamment limités par les lieux, l'intrigue, les personnages, les mécanismes de jeu que d'autres personnes ont imaginés. Alors je me suis rendu compte que...

… il est temps de créer vos propres mondes, soumis uniquement à moi. Des mondes où je suis le Père, et le Fils, et le Saint-Esprit !

Et je crois sincèrement qu'en écrivant votre propre moteur de jeu et un jeu dessus, vous pourrez ouvrir les yeux, essuyer les vitres et pomper votre cabine, devenant un programmeur plus expérimenté et intégral.

Dans cet article, je vais essayer de vous dire comment j'ai commencé à écrire de petits jeux en C/C++, quel est le processus de développement et où je trouve du temps pour un passe-temps dans un environnement occupé. Il est subjectif et décrit le processus d'un démarrage individuel. Matériel sur l'ignorance et la foi, sur mon image personnelle du monde en ce moment. En d'autres termes, "L'administration n'est pas responsable de vos cerveaux personnels !".

Pratique

« La connaissance sans pratique est inutile, la pratique sans connaissance est dangereuse. » Confucius

Mon carnet c'est ma vie !


Donc, en pratique, je peux dire que tout commence pour moi par un cahier. J'y écris non seulement mes tâches quotidiennes, mais aussi dessiner, programmer, concevoir des organigrammes et résoudre des problèmes, y compris mathématiques. Utilisez toujours un bloc-notes et écrivez uniquement avec un crayon. C'est propre, confortable et fiable, à mon humble avis.

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Mon cahier (déjà rempli). C'est à quoi ça ressemble. Il contient des tâches quotidiennes, des idées, des dessins, des diagrammes, des solutions, de la comptabilité noire, du code, etc.

À ce stade, j'ai réussi à terminer trois projets (c'est dans ma compréhension de la «finalité», car tout produit peut être développé de manière relativement infinie).

  • Projet 0: il s'agit d'une scène Architect Demo 3D écrite en C# à l'aide du moteur de jeu Unity. Pour les plates-formes macOS et Windows.
  • Jeu 1: jeu de console Simple Snake (connu de tous sous le nom de "Snake") pour Windows. écrit en c.
  • Jeu 2: jeu de console Crazy Tanks (connu de tous sous le nom de "Tanks"), déjà écrit en C ++ (utilisant des classes) et également sous Windows.

Projet 0 Démo d'architecte

  • Plate-forme: Windows (Windows 7, 10), Mac OS (OS X El Capitan version 10.11.6)
  • Langue: C#
  • Moteur de jeu : Unité
  • Inspiration: Darrin Lile
  • Dépôt: GitHub

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Démo d'architecte de scène 3D

Le premier projet a été implémenté non pas en C/C++, mais en C# en utilisant le moteur de jeu Unity. Ce moteur n'était pas aussi exigeant sur le matériel que Unreal Engine, et m'a également semblé plus facile à installer et à utiliser. Je n'ai pas pensé aux autres moteurs.

Le but dans Unity pour moi n'était pas de développer une sorte de jeu. Je voulais créer une scène 3D avec une sorte de personnage. Lui, ou plutôt Elle (j'ai modelé la fille dont j'étais amoureux =) devait bouger et interagir avec le monde extérieur. Il était seulement important de comprendre ce qu'est Unity, quel est le processus de développement et combien d'efforts il faut pour créer quelque chose. C'est ainsi qu'est né le projet Architect Demo (le nom a été inventé presque à partir de conneries). Programmation, modélisation, animation, texturing m'ont pris probablement deux mois de travail quotidien.

J'ai commencé avec des vidéos de tutoriel sur YouTube sur la façon de créer des modèles 3D dans Mixeur. Blender est un excellent outil gratuit pour la modélisation 3D (et plus) qui ne nécessite pas d'installation. Et là, un choc m'attendait ... Il s'avère que la modélisation, l'animation, la texturation sont d'énormes sujets distincts sur lesquels vous pouvez écrire des livres. C'est particulièrement vrai pour les personnages. Pour modéliser les doigts, les dents, les yeux et d'autres parties du corps, vous aurez besoin de connaissances en anatomie. Comment sont disposés les muscles du visage ? Comment les gens se déplacent-ils ? J'ai dû « insérer » des os dans chaque bras, jambe, doigt, phalanges !

Simulez des clavicules, des leviers osseux supplémentaires, pour que l'animation soit naturelle. Après de telles leçons, on se rend compte de l'énorme travail que font les créateurs de films d'animation, rien que pour créer 30 secondes de vidéo. Mais les films 3D durent des heures ! Et puis on sort des cinémas et on dit un truc du genre : « Ta, un dessin animé/film de merde ! Ils auraient pu mieux faire… » Imbéciles !

Et encore une chose à propos de la programmation dans ce projet. Il s'est avéré que la partie la plus intéressante pour moi était la partie mathématique. Si vous exécutez la scène (lien vers le référentiel dans la description du projet), vous remarquerez que la caméra tourne autour du personnage fille dans une sphère. Pour programmer une telle rotation de caméra, je devais d'abord calculer les coordonnées du point de position sur le cercle (2D), puis sur la sphère (3D). Le plus drôle, c'est que je détestais les maths à l'école et que je les connaissais avec un moins. En partie, probablement, parce qu'à l'école, ils ne vous expliquent tout simplement pas comment diable ces mathématiques sont appliquées dans la vie. Mais lorsque vous êtes obsédé par votre objectif, rêvez, alors l'esprit s'éclaircit, se révèle ! Et vous commencez à percevoir les tâches complexes comme une aventure passionnante. Et puis vous pensez: "Eh bien, pourquoi le mathématicien *bien-aimé* ne pourrait-il pas dire normalement où ces formules peuvent être penchées?".

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Calcul de formules pour calculer les coordonnées d'un point sur un cercle et sur une sphère (à partir de mon cahier)

Jeu 1

  • Plate-forme: Windows (testé sur Windows 7, 10)
  • Langue: Je pense qu'il a été écrit en C pur
  • Moteur de jeu : Console Windows
  • Inspiration: javidx9
  • Dépôt: GitHub

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Jeu de serpent simple

La scène 3D n'est pas un jeu. De plus, modéliser et animer des objets 3D (surtout des personnages) est long et difficile. Après avoir joué avec Unity, j'ai réalisé que je devais continuer, ou plutôt commencer, par les bases. Quelque chose de simple et rapide, mais en même temps global, pour comprendre la structure même des jeux.

Et qu'avons-nous de simple et rapide ? C'est vrai, console et 2D. Plus précisément, même la console et les symboles. Encore une fois, j'ai commencé à chercher l'inspiration sur Internet (en général, je considère Internet comme l'invention la plus révolutionnaire et la plus dangereuse du XNUMXème siècle). J'ai déterré une vidéo d'un programmeur qui a fait la console Tetris. Et à l'image de son jeu, il a décidé d'abattre le "serpent". De la vidéo, j'ai appris deux choses fondamentales - la boucle de jeu (avec trois fonctions/parties de base) et la sortie vers le tampon.

La boucle de jeu pourrait ressembler à ceci :

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

Le code présente l'intégralité de la fonction main() en une seule fois. Et le cycle de jeu démarre après le commentaire correspondant. Il y a trois fonctions de base dans la boucle : Input(), Logic(), Draw(). Tout d'abord, les données d'entrée d'entrée (principalement le contrôle des frappes), puis le traitement de la logique de données saisies, puis l'affichage à l'écran - Dessiner. Et donc chaque image. L'animation est créée de cette manière. C'est comme les dessins animés. Habituellement, le traitement des données d'entrée prend le plus de temps et, pour autant que je sache, détermine la fréquence d'images du jeu. Mais ici la fonction Logic() est très rapide. Par conséquent, la fréquence d'images doit être contrôlée par la fonction Sleep() avec le paramètre gameSpeed, qui détermine cette fréquence.

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
cycle de jeu. Programmation de serpent dans le bloc-notes

Si vous développez un jeu de console symbolique, l'affichage des données à l'écran à l'aide de la sortie de flux habituelle "cout" ne fonctionnera pas - c'est très lent. Par conséquent, la sortie doit être effectuée dans le tampon d'écran. Tellement plus rapide et le jeu fonctionnera sans problèmes. Pour être honnête, je ne comprends pas très bien ce qu'est un tampon d'écran et comment cela fonctionne. Mais je vais donner un exemple de code ici, et peut-être que quelqu'un dans les commentaires pourra clarifier la situation.

Obtenir le tampon d'écran (si je puis dire):

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

Sortie directe à l'écran d'une certaine ligne scoreLine (la ligne d'affichage des scores) :

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

En théorie, il n'y a rien de compliqué dans ce jeu, il me semble un bon exemple de jeu d'entrée de gamme. Le code est écrit dans un fichier et organisé en plusieurs fonctions. Pas de classes, pas d'héritage. Vous pouvez vous-même tout voir dans le code source du jeu en vous rendant sur le dépôt sur GitHub.

Jeu 2 chars fous

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Jeu Crazy Tanks

Imprimer des personnages sur la console est probablement la chose la plus simple que vous puissiez transformer en jeu. Mais alors un problème apparaît : les caractères ont des hauteurs et des largeurs différentes (la hauteur est supérieure à la largeur). Ainsi, tout semblera disproportionné, et se déplacer vers le bas ou vers le haut semblera beaucoup plus rapide que de se déplacer vers la gauche ou la droite. Cet effet est très perceptible dans "Snake" (Game 1). Les "Tanks" (jeu 2) n'ont pas un tel inconvénient, car la sortie y est organisée en peignant les pixels de l'écran avec des couleurs différentes. Vous pourriez dire que j'ai écrit un moteur de rendu. Certes, c'est déjà un peu plus compliqué, bien que beaucoup plus intéressant.

Pour ce jeu, il suffira de décrire mon système d'affichage des pixels à l'écran. Je pense que c'est la partie principale du jeu. Et tout ce que vous pouvez inventer vous-même.

Ainsi, ce que vous voyez à l'écran n'est qu'un ensemble de rectangles colorés en mouvement.

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Ensemble de rectangles

Chaque rectangle est représenté par une matrice remplie de nombres. Soit dit en passant, je peux mettre en évidence une nuance intéressante - toutes les matrices du jeu sont programmées comme un tableau unidimensionnel. Pas bidimensionnel, mais unidimensionnel ! Les tableaux unidimensionnels sont beaucoup plus faciles et rapides à utiliser.

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Un exemple de matrice de réservoir de jeu

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Représentation de la matrice d'un réservoir de jeu avec un tableau unidimensionnel

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Un exemple plus illustratif de représentation matricielle par un tableau unidimensionnel

Mais l'accès aux éléments du tableau se fait dans une double boucle, comme s'il ne s'agissait pas d'un tableau à une dimension, mais à deux dimensions. Ceci est fait parce que nous travaillons toujours avec des matrices.

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Traversée d'un tableau unidimensionnel dans une double boucle. Y est l'ID de ligne, X est l'ID de colonne

Veuillez noter qu'au lieu des identifiants de matrice habituels i, j, j'utilise les identifiants x et y. Donc, il me semble, plus agréable à l'œil et plus clair pour le cerveau. De plus, une telle notation permet de projeter commodément les matrices utilisées sur les axes de coordonnées d'une image en deux dimensions.

Parlons maintenant des pixels, de la couleur et de l'affichage. La fonction StretchDIBits (en-tête : windows.h ; bibliothèque : gdi32.lib) est utilisée pour la sortie. On passe entre autres à cette fonction : l'appareil sur lequel l'image est affichée (dans mon cas, il s'agit de la console Windows), les coordonnées du début d'affichage de l'image, sa largeur/hauteur, et l'image lui-même sous la forme d'un bitmap (bitmap), représenté par un tableau d'octets. Bitmap sous forme de tableau d'octets !

La fonction StretchDIBits() au travail :

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

La mémoire est allouée à l'avance pour ce bitmap à l'aide de la fonction VirtualAlloc(). C'est-à-dire que le nombre d'octets requis est réservé pour stocker des informations sur tous les pixels, qui seront ensuite affichées à l'écran.

Création d'un bitmap 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);

Grosso modo, un bitmap est constitué d'un ensemble de pixels. Tous les quatre octets du tableau correspondent à un pixel RVB. Un octet par valeur rouge, un octet par valeur verte (G) et un octet par couleur bleue (B). De plus, il y a un octet par retrait. Ces trois couleurs - Rouge / Vert / Bleu (RVB) - sont mélangées les unes aux autres dans des proportions différentes - et la couleur de pixel résultante est obtenue.

Maintenant, encore une fois, chaque rectangle, ou objet de jeu, est représenté par une matrice numérique. Tous ces objets de jeu sont placés dans une collection. Et puis ils sont placés sur le terrain de jeu, formant une grande matrice numérique. J'ai mappé chaque numéro de la matrice sur une couleur spécifique. Par exemple, le chiffre 8 est bleu, le chiffre 9 est jaune, le chiffre 10 est gris foncé, etc. Ainsi, nous pouvons dire que nous avons une matrice du terrain de jeu, où chaque numéro est une sorte de couleur.

Nous avons donc une matrice numérique de l'ensemble du terrain de jeu d'une part et un bitmap pour afficher l'image d'autre part. Jusqu'à présent, le bitmap est "vide" - il ne contient pas encore d'informations sur les pixels de la couleur souhaitée. Cela signifie que la dernière étape consistera à remplir le bitmap avec des informations sur chaque pixel en fonction de la matrice numérique du terrain de jeu. Un exemple illustratif d'une telle transformation est dans l'image ci-dessous.

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Un exemple de remplissage d'un bitmap (Pixel matrix) avec des informations basées sur la matrice numérique (Digital matrix) du terrain de jeu (les indices de couleur ne correspondent pas aux indices du jeu)

Je présenterai également un morceau de code réel du jeu. La variable colorIndex à chaque itération de la boucle se voit attribuer une valeur (color index) issue de la matrice numérique du terrain de jeu (mainDigitalMatrix). Ensuite, la couleur elle-même est écrite dans la variable de couleur en fonction de l'index. De plus, la couleur résultante est divisée en un rapport de rouge, vert et bleu (RVB). Et avec l'indentation (pixelPadding), ces informations sont écrites encore et encore sur le pixel, formant une image couleur dans le bitmap.

Le code utilise des pointeurs et des opérations au niveau du bit, ce qui peut être difficile à comprendre. Je vous conseille donc de lire séparément quelque part comment fonctionnent ces structures.

Remplissage d'un bitmap avec des informations basées sur la matrice numérique du terrain de jeu :

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

Selon la méthode décrite ci-dessus, une image (cadre) est formée dans le jeu Crazy Tanks et affichée à l'écran dans la fonction Draw(). Après avoir enregistré les frappes dans la fonction Input() et leur traitement ultérieur dans la fonction Logic(), une nouvelle image (frame) est formée. Certes, les objets du jeu peuvent déjà avoir une position différente sur le terrain de jeu et, par conséquent, sont dessinés à un endroit différent. C'est ainsi que l'animation (mouvement) se produit.

En théorie (si vous n'avez rien oublié), il suffit de comprendre la boucle de jeu du premier jeu ("Snake") et le système d'affichage des pixels à l'écran du deuxième jeu ("Tanks") pour écrire n'importe quel de vos jeux 2D pour Windows. Silencieux! 😉 Le reste des pièces n'est qu'une fantaisie.

Bien sûr, le jeu "Tanks" est conçu beaucoup plus compliqué que le "Snake". J'ai déjà utilisé le langage C++, c'est-à-dire que j'ai décrit différents objets de jeu avec des classes. J'ai créé ma propre collection - vous pouvez voir le code dans headers/Box.h. Soit dit en passant, la collection a très probablement une fuite de mémoire. Pointeurs utilisés. Travaillé avec la mémoire. Je dois dire que le livre m'a beaucoup aidé. Commencer C ++ via la programmation de jeux. C'est un bon début pour les débutants en C++. C'est petit, intéressant et bien organisé.

Il a fallu environ six mois pour développer ce jeu. J'écrivais principalement pendant le déjeuner et les collations au travail. Il s'est assis dans la cuisine du bureau, a piétiné de la nourriture et écrit du code. Ou à la maison pour le dîner. J'ai donc eu de telles "guerres de cuisine". Comme toujours, j'ai activement utilisé un cahier, et toutes les choses conceptuelles y sont nées.

A la fin de la partie pratique, je sortirai quelques scans de mon cahier. Pour montrer exactement ce que j'écrivais, dessinais, comptais, dessinais…

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Conception d'image de réservoir. Et la définition du nombre de pixels que chaque réservoir doit occuper à l'écran

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Calcul de l'algorithme et des formules pour la rotation du réservoir autour de son axe

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Diagramme de ma collection (celle avec la fuite de mémoire, très probablement). La collection est créée en tant que liste liée

DevOps C++ et "kitchen wars", ou comment j'ai commencé à écrire des jeux en mangeant
Et ce sont de vaines tentatives de visser l'intelligence artificielle dans le jeu

Теория

"Même un voyage de mille kilomètres commence par le premier pas" (Ancienne sagesse chinoise)

Passons de la pratique à la théorie ! Comment trouvez-vous du temps pour votre passe-temps?

  1. Déterminez ce que vous voulez vraiment (hélas, c'est le plus difficile).
  2. Fixer les priorités.
  3. Sacrifiez tout le "superflu" au profit de priorités plus élevées.
  4. Avancez vers vos objectifs chaque jour.
  5. Ne vous attendez pas à ce qu'il y ait deux ou trois heures de temps libre pour un passe-temps.

D'une part, vous devez déterminer ce que vous voulez et prioriser. En revanche, il est possible d'abandonner certains cas/projets au profit de ces priorités. En d'autres termes, vous devrez sacrifier tout ce qui est "superflu". J'ai entendu quelque part que dans la vie il devrait y avoir au maximum trois activités principales. Ensuite, vous pourrez les traiter de la meilleure façon possible. Et des projets/directions supplémentaires commenceront à surcharger ringard. Mais tout cela est probablement subjectif et individuel.

Il y a une certaine règle d'or : ne jamais avoir une journée à 0 % ! Je l'ai appris dans un article d'un développeur indépendant. Si vous travaillez sur un projet, faites quelque chose tous les jours. Et peu importe combien vous gagnez. Écrivez un mot ou une ligne de code, regardez un didacticiel vidéo ou enfoncez un clou dans le tableau, faites simplement quelque chose. Le plus dur est de démarrer. Une fois que vous aurez commencé, vous en ferez probablement un peu plus que vous ne le vouliez. Ainsi vous avancerez constamment vers votre objectif et, croyez-moi, très rapidement. Après tout, le principal frein à toute chose est la procrastination.

Et il est important de se rappeler qu'il ne faut pas sous-estimer et ignorer la "sciure" gratuite du temps en 5, 10, 15 minutes, attendre quelques grosses "bûches" d'une durée d'une heure ou deux. Êtes-vous en ligne? Pensez à quelque chose pour votre projet. Vous montez l'escalator ? Écrivez quelque chose dans un cahier. Vous mangez dans le bus ? D'accord, lisez un article. Utilisez chaque opportunité. Arrêtez de regarder les chats et les chiens sur YouTube ! Ne jouez pas avec votre cerveau!

Et le dernier. Si, après avoir lu cet article, vous avez aimé l'idée de créer des jeux sans utiliser de moteurs de jeu, alors souvenez-vous du nom de Casey Muratori. Ce gars a site Web. Dans la section "regarder -> ÉPISODES PRÉCÉDENTS", vous trouverez d'incroyables didacticiels vidéo gratuits sur la façon de créer un jeu professionnel à partir de zéro. Vous pouvez en apprendre plus en cinq leçons d'introduction au C pour Windows qu'en cinq années d'études à l'université (quelqu'un a écrit à ce sujet dans les commentaires sous la vidéo).

Casey explique également qu'en développant votre propre moteur de jeu, vous aurez une meilleure compréhension de tous les moteurs existants. Dans le monde des frameworks, où tout le monde essaie d'automatiser, vous apprendrez à créer, pas à utiliser. Comprendre la nature même des ordinateurs. Et vous deviendrez également un programmeur beaucoup plus intelligent et mature - un pro.

Bonne chance sur votre chemin choisi! Et rendons le monde plus professionnel.

Auteur: Grankin Andreï, DevOps



Source: habr.com