DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben

„Ich weiß, dass ich nichts weiß“ Sokrates

Für wen: für IT-Leute, die auf alle Entwickler spucken und deren Spiele spielen wollen!

Worüber: Wie Sie bei Bedarf mit dem Schreiben von Spielen in C/C++ beginnen können!

Warum sollten Sie das lesen: App-Entwicklung ist nicht mein Spezialgebiet, aber ich versuche jede Woche zu programmieren. Weil ich Spiele liebe!

Hallo, ich heiße Andrey Grankin, ich bin DevOps bei Luxoft. Anwendungsentwicklung ist nicht mein Spezialgebiet, aber ich versuche jede Woche zu programmieren. Weil ich Spiele liebe!

Die Computerspielindustrie ist riesig und wird heute noch häufiger gemunkelt als die Filmindustrie. Spiele wurden seit Beginn der Computerentwicklung geschrieben, wobei nach modernen Maßstäben komplexe und grundlegende Entwicklungsmethoden zum Einsatz kamen. Im Laufe der Zeit erschienen Spiel-Engines mit bereits programmierter Grafik, Physik und Sound. Sie ermöglichen es Ihnen, sich auf die Entwicklung des Spiels selbst zu konzentrieren und müssen sich nicht um dessen Grundlagen kümmern. Aber zusammen mit ihnen, mit den Motoren, „erblinden“ die Entwickler und verschlechtern sich. Die eigentliche Produktion von Spielen wird aufs Fließband gebracht. Und die Quantität der Produktion beginnt Vorrang vor ihrer Qualität zu haben.

Gleichzeitig sind wir beim Spielen anderer Spiele ständig durch Orte, Handlung, Charaktere und Spielmechaniken eingeschränkt, die andere Leute erfunden haben. Also wurde mir klar, dass...

… es ist Zeit, eure eigenen Welten zu erschaffen, die nur mir unterworfen sind. Welten, in denen ich der Vater, der Sohn und der Heilige Geist bin!

Und ich bin fest davon überzeugt, dass Sie durch das Schreiben Ihrer eigenen Spiel-Engine und eines darauf basierenden Spiels in der Lage sein werden, Ihre Augen zu öffnen, die Fenster zu wischen und Ihre Kabine aufzupumpen und ein erfahrenerer und ganzheitlicherer Programmierer zu werden.

In diesem Artikel werde ich versuchen, Ihnen zu erzählen, wie ich angefangen habe, kleine Spiele in C/C++ zu schreiben, wie der Entwicklungsprozess abläuft und wo ich in einer geschäftigen Umgebung Zeit für ein Hobby finde. Es ist subjektiv und beschreibt den Prozess eines einzelnen Starts. Material über Unwissenheit und Glauben, über mein persönliches Bild der Welt im Moment. Mit anderen Worten: „Die Verwaltung ist nicht für Ihr persönliches Gehirn verantwortlich!“.

Praxis

„Wissen ohne Praxis ist nutzlos, Praxis ohne Wissen ist gefährlich.“ Konfuzius

Mein Notizbuch ist mein Leben!


In der Praxis kann ich also sagen, dass für mich alles mit einem Notizbuch beginnt. Dort schreibe ich nicht nur meine täglichen Aufgaben auf, sondern zeichne, programmiere, entwerfe Flussdiagramme und löse Probleme, auch mathematische. Benutzen Sie immer einen Notizblock und schreiben Sie nur mit einem Bleistift. Meiner Meinung nach ist es sauber, komfortabel und zuverlässig.

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Mein (bereits gefülltes) Notizbuch. So sieht es aus. Es enthält alltägliche Aufgaben, Ideen, Zeichnungen, Diagramme, Lösungen, schwarze Buchführung, Code usw.

Zu diesem Zeitpunkt gelang es mir, drei Projekte abzuschließen (das entspricht meinem Verständnis von „Endgültigkeit“, da jedes Produkt relativ endlos weiterentwickelt werden kann).

  • Projekt 0: Dies ist eine Architect-Demo-3D-Szene, die in C# unter Verwendung der Unity-Spiel-Engine geschrieben wurde. Für macOS- und Windows-Plattformen.
  • Spiel 1: Konsolenspiel Simple Snake (allen bekannt als „Snake“) für Windows. geschrieben in C.
  • Spiel 2: Konsolenspiel Crazy Tanks (allen als „Tanks“ bekannt), bereits in C++ (unter Verwendung von Klassen) und auch unter Windows geschrieben.

Project 0 Architect Demo

  • Plattform: Windows (Windows 7, 10), Mac OS (OS X El Capitan v. 10.11.6)
  • Sprache: C#
  • Spiel-Engine: Einheit
  • Inspiration: Darrin Lile
  • Repository: GitHub

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Demo zum 3D-Szenenarchitekten

Das erste Projekt wurde nicht in C/C++, sondern in C# unter Verwendung der Unity-Game-Engine umgesetzt. Dieser Motor stellte keine so hohen Anforderungen an die Hardware wie Unreal Engineund schien mir auch einfacher zu installieren und zu verwenden. Andere Motoren habe ich nicht in Betracht gezogen.

Das Ziel bei Unity war für mich nicht, irgendein Spiel zu entwickeln. Ich wollte eine 3D-Szene mit einer Art Charakter erstellen. Er, oder besser gesagt sie (ich habe das Mädchen modelliert, in das ich verliebt war =), musste sich bewegen und mit der Außenwelt interagieren. Wichtig war nur zu verstehen, was Unity ist, wie der Entwicklungsprozess abläuft und wie viel Aufwand nötig ist, um etwas zu schaffen. So entstand das Architect Demo-Projekt (der Name wurde fast aus dem Bullshit erfunden). Das Programmieren, Modellieren, Animieren und Texturieren hat mich wahrscheinlich zwei Monate täglicher Arbeit gekostet.

Ich begann mit Tutorial-Videos auf YouTube zum Erstellen von 3D-Modellen Mixer. Blender ist ein großartiges kostenloses Tool für die 3D-Modellierung (und mehr), das keine Installation erfordert. Und hier erwartete mich ein Schock ... Es stellte sich heraus, dass Modellierung, Animation und Texturierung große separate Themen sind, über die man Bücher schreiben kann. Dies gilt insbesondere für die Charaktere. Um Finger, Zähne, Augen und andere Körperteile zu modellieren, sind anatomische Kenntnisse erforderlich. Wie sind die Gesichtsmuskeln angeordnet? Wie bewegen sich Menschen? Ich musste Knochen in jeden Arm, jedes Bein, jeden Finger und jede Knöchel „einführen“!

Modellieren Sie das Schlüsselbein und zusätzliche Knochenhebel, damit die Animation natürlich aussieht. Nach solchen Lektionen wird einem klar, was für eine gewaltige Arbeit die Macher von Animationsfilmen leisten, allein schon die Erstellung eines 30-sekündigen Videos. Aber 3D-Filme halten stundenlang! Und dann kommen wir aus den Kinos und sagen so etwas wie: „Ta, ein beschissener Cartoon/Film! Sie hätten es besser machen können …“ Dummköpfe!

Und noch etwas zur Programmierung in diesem Projekt. Wie sich herausstellte, war der mathematische Teil für mich der interessanteste. Wenn Sie die Szene abspielen (Link zum Repository in der Projektbeschreibung), werden Sie feststellen, dass sich die Kamera in einer Kugel um die Mädchenfigur dreht. Um eine solche Kameradrehung zu programmieren, musste ich zunächst die Koordinaten des Positionspunkts auf dem Kreis (2D) und dann auf der Kugel (3D) berechnen. Das Lustige ist, dass ich Mathe in der Schule gehasst habe und es mit einem Minus gelernt habe. Zum Teil wahrscheinlich, weil einem in der Schule einfach nicht erklärt wird, wie zum Teufel diese Mathematik im Leben angewendet wird. Aber wenn Sie von Ihrem Ziel, Ihrem Traum, besessen sind, dann ist der Geist klar und offenbart! Und Sie beginnen komplexe Aufgaben als spannendes Abenteuer wahrzunehmen. Und dann denken Sie: „Warum konnte der *geliebte* Mathematiker normalerweise nicht sagen, woher diese Formeln abgeleitet werden können?“

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Berechnung von Formeln zur Berechnung der Koordinaten eines Punktes auf einem Kreis und auf einer Kugel (aus meinem Notizbuch)

Spiel 1

  • Plattform: Windows (getestet unter Windows 7, 10)
  • Sprache: Ich glaube, es wurde in reinem C geschrieben
  • Spiel-Engine: Windows-Konsole
  • Inspiration: javidx9
  • Repository: GitHub

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Einfaches Snake-Spiel

Die 3D-Szene ist kein Spiel. Darüber hinaus ist das Modellieren und Animieren von 3D-Objekten (insbesondere Charakteren) langwierig und schwierig. Nachdem ich mit Unity herumgespielt hatte, wurde mir klar, dass ich mit den Grundlagen fortfahren oder besser gesagt beginnen musste. Etwas Einfaches und Schnelles, aber gleichzeitig Globales, um die Struktur von Spielen zu verstehen.

Und was haben wir einfach und schnell? Genau, Konsole und 2D. Genauer gesagt, sogar die Konsole und Symbole. Wieder begann ich, im Internet nach Inspiration zu suchen (im Allgemeinen halte ich das Internet für die revolutionärste und gefährlichste Erfindung des XNUMX. Jahrhunderts). Ich habe ein Video von einem Programmierer ausgegraben, der die Tetris-Konsole entwickelt hat. Und passend zu seinem Spiel beschloss er, die „Schlange“ zu fällen. Aus dem Video habe ich zwei grundlegende Dinge gelernt – die Spielschleife (mit drei Grundfunktionen/Teilen) und die Ausgabe in den Puffer.

Die Spielschleife könnte etwa so aussehen:

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

Der Code stellt die gesamte main()-Funktion auf einmal dar. Und der Spielzyklus beginnt nach dem entsprechenden Kommentar. Es gibt drei Grundfunktionen in der Schleife: Input(), Logic(), Draw(). Zuerst Eingabedateneingabe (hauptsächlich Steuerung von Tastenanschlägen), dann Verarbeitung der eingegebenen Datenlogik, dann Anzeige auf dem Bildschirm – Zeichnen. Und so jedes Bild. Auf diese Weise entsteht eine Animation. Es ist wie in Cartoons. Normalerweise nimmt die Verarbeitung der Eingabedaten die meiste Zeit in Anspruch und bestimmt meines Wissens die Bildrate des Spiels. Aber hier ist die Funktion Logic() sehr schnell. Daher muss die Bildrate durch die Sleep()-Funktion mit dem gameSpeed-Parameter gesteuert werden, der diese Rate bestimmt.

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Spielzyklus. Snake-Programmierung im Notizblock

Wenn Sie ein symbolisches Konsolenspiel entwickeln, funktioniert die Anzeige von Daten auf dem Bildschirm mit der üblichen Stream-Ausgabe „cout“ nicht – sie ist sehr langsam. Daher muss die Ausgabe im Bildschirmpuffer erfolgen. So viel schneller und das Spiel läuft ohne Störungen. Ehrlich gesagt verstehe ich nicht ganz, was ein Bildschirmpuffer ist und wie er funktioniert. Aber ich werde hier ein Codebeispiel geben, und vielleicht kann jemand in den Kommentaren die Situation klären.

Den Bildschirmpuffer abrufen (wenn ich das so sagen darf):

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

Direkte Ausgabe einer bestimmten Zeile „ScoreLine“ (Zeile zur Anzeige der Ergebnisse) auf dem Bildschirm:

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

Theoretisch gibt es in diesem Spiel nichts Kompliziertes, es scheint mir ein gutes Beispiel für ein Einsteigerspiel zu sein. Der Code ist in einer Datei geschrieben und in mehreren Funktionen angeordnet. Keine Klassen, keine Vererbung. Sie selbst können alles im Quellcode des Spiels sehen, indem Sie das Repository auf GitHub aufrufen.

Spiel 2 Verrückte Panzer

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Crazy Tanks-Spiel

Das Drucken von Charakteren auf der Konsole ist wahrscheinlich die einfachste Sache, die man in ein Spiel umwandeln kann. Doch dann taucht ein Problem auf: Die Zeichen haben unterschiedliche Höhen und Breiten (die Höhe ist größer als die Breite). Dadurch sieht alles unverhältnismäßig aus und die Bewegung nach unten oder oben scheint viel schneller zu sein als die Bewegung nach links oder rechts. Dieser Effekt ist in „Snake“ (Spiel 1) sehr deutlich zu spüren. „Tanks“ (Spiel 2) haben einen solchen Nachteil nicht, da die Ausgabe dort durch das Malen der Bildschirmpixel mit unterschiedlichen Farben organisiert wird. Man könnte sagen, ich habe einen Renderer geschrieben. Das ist zwar schon etwas komplizierter, aber viel interessanter.

Für dieses Spiel reicht es aus, mein System zur Anzeige von Pixeln auf dem Bildschirm zu beschreiben. Ich denke, das ist der Hauptteil des Spiels. Und alles andere können Sie sich selbst ausdenken.

Was Sie also auf dem Bildschirm sehen, ist nur eine Reihe sich bewegender farbiger Rechtecke.

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Rechteck-Set

Jedes Rechteck wird durch eine mit Zahlen gefüllte Matrix dargestellt. Übrigens kann ich eine interessante Nuance hervorheben: Alle Matrizen im Spiel sind als eindimensionales Array programmiert. Nicht zweidimensional, sondern eindimensional! Mit eindimensionalen Arrays lässt sich viel einfacher und schneller arbeiten.

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Ein Beispiel für eine Spielpanzermatrix

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Darstellung der Matrix eines Wildpanzers mit einem eindimensionalen Array

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Ein anschaulicheres Beispiel einer Matrixdarstellung durch ein eindimensionales Array

Der Zugriff auf die Elemente des Arrays erfolgt jedoch in einer Doppelschleife, als wäre es kein eindimensionales, sondern ein zweidimensionales Array. Dies geschieht, weil wir immer noch mit Matrizen arbeiten.

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Durchlaufen eines eindimensionalen Arrays in einer Doppelschleife. Y ist die Zeilen-ID, X ist die Spalten-ID

Bitte beachten Sie, dass ich anstelle der üblichen Matrixbezeichner i, j die Bezeichner x und y verwende. Es scheint mir also angenehmer für das Auge und klarer für das Gehirn. Darüber hinaus ermöglicht eine solche Notation eine komfortable Projektion der verwendeten Matrizen auf die Koordinatenachsen eines zweidimensionalen Bildes.

Nun zu Pixeln, Farbe und Anzeige. Für die Ausgabe wird die Funktion StretchDIBits (Header: windows.h; Bibliothek: gdi32.lib) verwendet. An diese Funktion wird unter anderem Folgendes übergeben: das Gerät, auf dem das Bild angezeigt wird (in meinem Fall ist dies die Windows-Konsole), die Koordinaten des Beginns der Bildanzeige, seine Breite/Höhe und das Bild selbst in Form einer Bitmap (Bitmap), dargestellt durch ein Array von Bytes. Bitmap als Array von Bytes!

Die Funktion StretchDIBits() bei der Arbeit:

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

Speicher wird dieser Bitmap im Voraus mit der Funktion VirtualAlloc() zugewiesen. Das heißt, die erforderliche Anzahl an Bytes wird reserviert, um Informationen über alle Pixel zu speichern, die dann auf dem Bildschirm angezeigt werden.

Erstellen einer m_p_bitmapMemory-Bitmap:

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

Grob gesagt besteht eine Bitmap aus einer Reihe von Pixeln. Alle vier Bytes im Array sind ein RGB-Pixel. Ein Byte pro Rotwert, ein Byte pro Grünwert (G) und ein Byte pro Blaufarbe (B). Außerdem gibt es ein Byte pro Einzug. Diese drei Farben – Rot/Grün/Blau (RGB) – werden in unterschiedlichen Anteilen miteinander gemischt – und man erhält die resultierende Pixelfarbe.

Auch hier wird jedes Rechteck bzw. Spielobjekt durch eine Zahlenmatrix dargestellt. Alle diese Spielobjekte werden in einer Sammlung abgelegt. Und dann werden sie auf das Spielfeld gelegt und bilden eine große numerische Matrix. Ich habe jede Zahl in der Matrix einer bestimmten Farbe zugeordnet. Beispielsweise ist die Zahl 8 blau, die Zahl 9 gelb, die Zahl 10 dunkelgrau und so weiter. Wir können also sagen, dass wir eine Matrix des Spielfelds haben, in der jede Zahl eine bestimmte Farbe hat.

Wir haben also einerseits eine numerische Matrix des gesamten Spielfeldes und andererseits eine Bitmap zur Darstellung des Bildes. Bisher ist die Bitmap „leer“ – sie enthält noch keine Informationen über die Pixel der gewünschten Farbe. Das bedeutet, dass der letzte Schritt darin besteht, die Bitmap mit Informationen zu jedem Pixel zu füllen, basierend auf der numerischen Matrix des Spielfelds. Ein anschauliches Beispiel für eine solche Transformation finden Sie im Bild unten.

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Ein Beispiel für das Füllen einer Bitmap (Pixelmatrix) mit Informationen basierend auf der numerischen Matrix (digitale Matrix) des Spielfelds (Farbindizes stimmen nicht mit den Indizes im Spiel überein)

Ich werde auch einen echten Code aus dem Spiel vorstellen. Der Variablen colorIndex wird bei jeder Iteration der Schleife ein Wert (Farbindex) aus der numerischen Matrix des Spielfelds (mainDigitalMatrix) zugewiesen. Anschließend wird die Farbe selbst basierend auf dem Index in die Farbvariable geschrieben. Darüber hinaus wird die resultierende Farbe in das Verhältnis von Rot, Grün und Blau (RGB) unterteilt. Und zusammen mit dem Einzug (pixelPadding) werden diese Informationen immer wieder auf das Pixel geschrieben und bilden so ein Farbbild in der Bitmap.

Der Code verwendet Zeiger und bitweise Operationen, die schwer zu verstehen sein können. Ich rate Ihnen daher, irgendwo separat zu lesen, wie solche Strukturen funktionieren.

Füllen einer Bitmap mit Informationen basierend auf der numerischen Matrix des Spielfelds:

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

Gemäß der oben beschriebenen Methode wird im Spiel Crazy Tanks ein Bild (Rahmen) erstellt und in der Funktion Draw() auf dem Bildschirm angezeigt. Nach der Registrierung von Tastenanschlägen in der Funktion Input() und deren anschließender Verarbeitung in der Funktion Logic() wird ein neues Bild (Frame) erstellt. Zwar können Spielobjekte bereits eine andere Position auf dem Spielfeld haben und dementsprechend an einer anderen Stelle gezeichnet werden. So geschieht Animation (Bewegung).

Theoretisch (falls Sie nichts vergessen haben) ist es alles, was Sie brauchen, um die Spielschleife des ersten Spiels („Snake“) und das System zur Anzeige von Pixeln auf dem Bildschirm des zweiten Spiels („Tanks“) zu verstehen, um etwas zu schreiben Ihrer 2D-Spiele für Windows. Lautlos! 😉 Die restlichen Teile sind reine Fantasie.

Natürlich ist das Spiel „Tanks“ deutlich komplizierter gestaltet als „Snake“. Ich habe bereits die Sprache C++ verwendet, das heißt, ich habe verschiedene Spielobjekte mit Klassen beschrieben. Ich habe meine eigene Sammlung erstellt – Sie können den Code in headers/Box.h sehen. Übrigens weist die Sammlung höchstwahrscheinlich einen Speicherverlust auf. Verwendete Zeiger. Arbeitete mit dem Gedächtnis. Ich muss sagen, dass mir das Buch sehr geholfen hat. Einstieg in C++ durch Spieleprogrammierung. Dies ist ein großartiger Einstieg für Anfänger in C++. Es ist klein, interessant und gut organisiert.

Die Entwicklung dieses Spiels dauerte etwa sechs Monate. Ich habe hauptsächlich während des Mittagessens und der Snacks bei der Arbeit geschrieben. Er saß in der Büroküche, stampfte auf Essen herum und schrieb Code. Oder zu Hause zum Abendessen. Also habe ich solche „Küchenkriege“ bekommen. Wie immer nutzte ich aktiv ein Notizbuch und alle konzeptionellen Dinge wurden darin geboren.

Am Ende des praktischen Teils werde ich noch ein paar Scans aus meinem Notizbuch hervorholen. Um zu zeigen, was genau ich aufgeschrieben, gezeichnet, gezählt, entworfen habe …

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Panzerbilddesign. Und die Definition, wie viele Pixel jeder Tank auf dem Bildschirm einnehmen soll

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Berechnung des Algorithmus und der Formeln für die Drehung des Tanks um seine Achse

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Diagramm meiner Sammlung (höchstwahrscheinlich die mit dem Speicherverlust). Die Sammlung wird als verknüpfte Liste erstellt

DevOps C++ und „Kitchen Wars“ oder wie ich beim Essen anfing, Spiele zu schreiben
Und das sind vergebliche Versuche, künstliche Intelligenz ins Spiel zu bringen

Теория

„Sogar eine Reise von tausend Meilen beginnt mit dem ersten Schritt“ (alte chinesische Weisheit)

Kommen wir von der Praxis zur Theorie! Wie finden Sie Zeit für Ihr Hobby?

  1. Bestimmen Sie, was Sie wirklich wollen (leider ist das am schwierigsten).
  2. Prioritäten setzen.
  3. Opfern Sie alles „Überflüssige“ zugunsten höherer Prioritäten.
  4. Gehen Sie jeden Tag Ihren Zielen entgegen.
  5. Erwarten Sie nicht, dass für ein Hobby zwei oder drei Stunden Freizeit zur Verfügung stehen.

Einerseits müssen Sie festlegen, was Sie wollen und Prioritäten setzen. Andererseits ist es möglich, einige Fälle/Projekte zugunsten dieser Prioritäten aufzugeben. Mit anderen Worten, Sie müssen alles „Überflüssige“ opfern. Ich habe irgendwo gehört, dass es im Leben maximal drei Hauptaktivitäten geben sollte. Dann können Sie bestmöglich mit ihnen umgehen. Und zusätzliche Projekte/Richtungen werden anfangen, kitschig zu werden. Aber das ist wahrscheinlich alles subjektiv und individuell.

Es gibt eine bestimmte goldene Regel: Es gibt nie einen 0 %-Tag! Ich habe davon in einem Artikel eines Indie-Entwicklers erfahren. Wenn Sie an einem Projekt arbeiten, dann tun Sie jeden Tag etwas dafür. Und es spielt keine Rolle, wie viel Sie verdienen. Schreiben Sie ein Wort oder eine Codezeile, schauen Sie sich ein Tutorial-Video an oder schlagen Sie einen Nagel in die Tafel – tun Sie einfach etwas. Der schwierigste Teil ist der Anfang. Wenn Sie einmal angefangen haben, werden Sie wahrscheinlich etwas mehr tun, als Sie wollten. So kommen Sie Ihrem Ziel ständig näher und, glauben Sie mir, sehr schnell. Schließlich ist die Hauptbremse für alle Dinge das Aufschieben.

Und es ist wichtig, sich daran zu erinnern, dass Sie die kostenlose „Sägemehl“-Zeit in 5, 10, 15 Minuten nicht unterschätzen und ignorieren sollten, warten Sie auf einige große „Protokolle“, die ein oder zwei Stunden dauern. Stehen Sie in der Schlange? Überlegen Sie sich etwas für Ihr Projekt. Gehst du die Rolltreppe hinauf? Schreiben Sie etwas in ein Notizbuch. Isst du im Bus? Okay, lies einen Artikel. Nutzen Sie jede Gelegenheit. Hören Sie auf, Katzen und Hunde auf YouTube anzuschauen! Leg dich nicht mit deinem Gehirn an!

Und der letzte. Wenn Ihnen nach der Lektüre dieses Artikels die Idee gefallen hat, Spiele ohne den Einsatz von Game-Engines zu erstellen, dann erinnern Sie sich an den Namen Casey Muratori. Dieser Typ hat Webseite. Im Abschnitt „Ansehen -> VORHERIGE EPISODEN“ finden Sie tolle kostenlose Video-Tutorials, wie Sie ein professionelles Spiel von Grund auf erstellen. Möglicherweise lernen Sie in fünf Lektionen „Einführung in C für Windows“ mehr als in fünf Jahren Studium an der Universität (jemand hat in den Kommentaren unter dem Video darüber geschrieben).

Casey erklärt auch, dass Sie durch die Entwicklung Ihrer eigenen Spiel-Engine ein besseres Verständnis aller vorhandenen Engines erhalten. In der Welt der Frameworks, in der jeder versucht zu automatisieren, lernen Sie, wie man erstellt, nicht wie man sie verwendet. Verstehen Sie die Natur von Computern. Und Sie werden auch ein viel intelligenterer und reiferer Programmierer – ein Profi.

Viel Glück auf deinem gewählten Weg! Und lasst uns die Welt professioneller machen.

Autor: Grankin Andrey, DevOps



Source: habr.com