Guten Tag an alle Habrozhitel. Ich möchte Ihnen erzählen, wie ich nach mehr als drei Jahren zu einem Amateur-Spieleentwickler zurückgekehrt bin und das Tool (und auf dem Weg - meine Weltanschauung) grundlegend geändert habe und was daraus geworden ist. Unter dem Schnitt du:
- Eine kurze Darstellung aller Fakten zu Beginn der Reise. Wie das Bild "VOR" in der günstigen Online-Werbung "VOR" und "NACH".
- Ein freiwilliger Tauchgang in einem modernen Frontend im Stil von "Wo ist das Geld, Lebowski?!"
- Leichter Juckreiz an einem intimen Punkt, der zu einem brennenden Verlangen wird, etwas Neues zu lernen, indem man etwas Altes tut.
- Bewusstsein der eigenen Hilflosigkeit
- Überwindung
- Schönes Ende, genau wie in deinen Filmen.
Haftungsausschluss
Dieser Artikel war zwei Jahre lang in Entwurfsform auf github, seine fast vollständige Version wurde Ende 2017 in stürmischer Verfolgung von Ereignissen verfasst.
Bürger, stell dich vor!
In meinem vorherigen Artikel ( https://habrahabr.ru/post/244417/ ) habe ich ein wenig über mich selbst geschrieben, insbesondere darüber, wie ich und gamedev verbunden sind. De jure - auf keinen Fall, de facto - ich schreibe Spiele und Motoren zum Vergnügen und zur Teilnahme an Warm- und Lampenwettbewerben. Seitdem hat sich wenig geändert.
Für die weitere Erzählung und die nötige Atmosphäre ist es wichtig, dass ich zu Beginn dieser Geschichte ein professioneller .net-Webentwickler bin, der HTML5, CSS3 und ... JQuery verwenden kann. Um das unerwartete "Dies ist eine Wende" zu bekräftigen, fügen wir hinzu, dass Misstrauen und Ekel gegenüber JavaScript bestehen, gewürzt mit:
- offenes Missverständnis dieses ganzen Rummels um die Sprache;
- Eine Reihe von Witzen über Typisierung, beschleunigte Überalterung von Frameworks, Anzahl + Zeichenfolgen-Überraschungen und mehr. Wissen Sie, eine solche Gruppe von Entwicklern, die eine ältere und etabliertere Sprache verwenden (hey, ich weiß, dass die .net-Plattform jünger ist als js, aber nicht im wahrsten Sinne des Wortes "erwachsen").
Komm mit!
September 2017. Ich habe einen neuen Warm and Lamp-Job mit einem neuen Technologie-Stack (.net Core Web API + Angular 4) gestartet und meine Aufgabe war nur das Backend. Das Wort Angular klang für mich beleidigend, npm und nodejs waren stark mit Smoothies und einem Gyro-Roller verbunden. Als Timlid dies sah und verstand, brachte er mir einen kurzen Kurs bei, wie man all diesen Shaitanismus in Gang bringt. Genau wie in diesem Witz über Tschuktschen und Hunde im All. Ich erinnere mich an die Fledermaus-Spitznamen, die ich starten muss (erinnere mich an npm run start, ich fand es extrem unnötig für meine sanfte Natur) und tauche ein in ein warmes und Rohr LED .net Kern.
Oktober 2017. Die erste Glocke. Timlid sagt, dass unser Front-Mitarbeiter sofort 4 Projekte bearbeitet und mir anbietet, einen Abschnitt im Admin-Bereich zu schneiden. Um das zu motivieren, sagen sie, ist es dort einfach, wiederholen Sie einfach, wie es für Entität N gemacht wurde, nur jetzt für M. Zum Lachen der Kollegen, die für einen Gyro-Roller und einen Vape für mich weggelaufen sind und hastig ein kurzes Bildungsprogramm über Angular gelesen haben, indem ich kopiere und Glück habe Ich gebäre eine Abteilung, die unter Vorbehalt funktioniert. Timlid ist zufrieden, ich bin geschockt und es scheint, dass Aufgaben im Backend auf dem Board erschienen sind ...
Aber nein Es gibt viele Back-Endors, es gibt bereits wenige Aufgaben für sie, und vorne ist ein nicht gepflügtes Feld. Eine neue Aufgabe, die sich bereits direkt auf dem Portal befindet, bringt mich dazu, die Angelegenheit ernst zu nehmen. Kollegen bemühen sich, meine Hosen zu verstauen und mich in einen Friseursalon zu bringen, und eine Woche lang beschäftige ich mich mit Lesematerialien zu Angular, TypeScript, npm, Webpack und vielem mehr. Übrigens hat der Artikel über modernes Javascript für Dinosaurier sehr geholfen - https://habrahabr.ru/company/mailru/blog/340922/ .
Nach einiger Zeit konnte ich einfache Front-End-Aufgaben abschließen und fühlte mich wie ein Gatekeeper ohne Dienstmädchen. Ich schmunzele immer noch über Witze über das Frontend und schlage vor, dass sich meine Mitstreiter treffen und meine Bananen-Erdbeer-Erfahrung anhören. Jeder lacht, aber im Geheimen will jeder verstehen, welche Art von Blasenbildung in diesem schnellen Front-End stattfindet (in der Tat nein).
Ohne weitere Umstände erzähle ich den obigen Artikel von Habr nach und gewürze ihn mit meinen Grundkenntnissen von Angular. Mitap kommt mit einem Knall und anschließend gebe ich eine Reihe solcher aus - über das Frontend für das Backend, was jedoch für unsere Geschichte nicht so wichtig ist. Das einzig Wichtige ist, dass ihre Implementierung mich zu einer tieferen Untersuchung des modernen Stapels von Front-End-Technologien geführt hat.
Juckreiz
Bei der Arbeit stellte sich heraus, dass im Familienleben eine eher ruhige Zeit herrschte und Juckreiz auftrat. So klein, immer noch ziemlich zerbrechlich und irgendwo an der Grenze des Unterbewusstseins lebend. Vor drei Jahren, so heißt es, habe ich mein Hobby, das Programmieren von Spielen, fast vollständig aufgegeben. Aber was ist, wenn Sie neues Wissen kombinieren und? ..
Ich habe mich lange mit WebGL befasst, aber früher hatte ich Angst, dass mir bei der Verwendung keine Hilfe (Tippen, automatische Vervollständigung) zur Verfügung stand. Und hier, bitte - eine nicht existierende silberne Kugel im Fleisch, derselbe Hammer, wenn er genommen wird, wird alles zu Nägeln. TypeScript
Für mich als eine Person, die den Schmerz mit der Rückruf-Hölle kannte, ist var self = this, bind (this), undefined keine Funktion ... Also, TypeScript schien mir nicht einmal ein Hauch frischer Luft, sondern eine Art Zauberer auf einem blauen Raumschiff, der herabkommt Himmel, warf mich träge - Sohn, vergiss alles, was du vorher über js wusstest, und ich werde dir zeigen, wie tief das Kaninchenloch ist. Schaut die Analogie chaotisch und im Allgemeinen eine Art Durcheinander von anderen Analogien? Stimmt, wie TypeScript selbst auf einen Blick.
Klassen, Interfaces, Typing, Async, Kompilierungsfehler und Tippfehler, Code-Vervollständigung, Arbeiten ohne Tamburin, verständliches Let-Verhalten, anstatt fuck-the-scope var zu entmutigen. Natürlich wurde mir nach einer Weile klar, dass der Sponsor des größten Teils dieses Glücks überhaupt nicht TypeScript ist, sondern JavaScript selbst in seiner modernen Version (ES6 und höher). Aber in diesem Moment schien es, dass ich einen Propheten gefunden hatte, der das Frontend zu einem hellen führen würde, kommunistisch die Zukunft. Hinzu kommt der ernsthafte Fortschritt verschiedener IDEs im Bereich Intellisense und die Unterstützung des Entwicklers, und vielleicht werden Sie meine Welpenfreude verstehen.
Hilflosigkeit
Der erste ernsthafte Schlag in meinem Atem war TypeScript selbst. Versuche, es an ein leeres Projekt zu binden, haben mich verständlich gemacht - ich kann verdammt noch mal nichts ausserhalb von Angular und Angular-Cli verstehen, die mir eine Menge Drecksarbeit machen. Benötige ich einen Compiler? Ok, schraub es in package.json, installiere npm, starte tsc und ... nichts. Ah, müssen Sie es noch global installieren? Ich lasse die langweiligen Details meines Krieges mit all diesen Dingen aus und werde sagen, dass ich einige Zeit später gelernt habe, main.ts in main.js umzuwandeln. Aber vor mir hatte ich Probleme mit dem Webpack.
Ja, jetzt ist mir klar, dass es möglich war, ohne ihn auszukommen. Aber wenn man sich in Typescripts ungeschickten Händen befindet, sieht alles so aus, als wäre es eckig. Bereits nach der Implementierung von Webpack habe ich erfahren, dass der TypeScript-Compiler selbst Änderungen in Dateien „überwachen“ kann und dass das Problem beim Import / Export ohne Webpack gelöst werden kann.
Überwindung
Nach ungefähr einer Woche konnte ich ein Projekt erstellen, in dem ich TypeScript-Code schrieb, auf „Speichern“ klickte und alles so lief, wie es sollte. Das Webpack kompilierte alle meine Dateien automatisch zu einem einzigen Bundle, indem es zuerst den TypeScript-Compiler ausführte und dann den Build darin ablegte ein separater ordner, in den ich andere statische sachen kopiert und im browser lite-server die seite in diesem moment neu geladen habe. Ich sagte, dass alles automatisch passiert ist? Nein, alles ist automatisch passiert. Joy kannte keine Grenzen und ich setzte mich hin, um einen einfachen Arena-Schützen zu schreiben.
Wo fängt es an? Heimat ist das Spiel für mich? Natürlich mit grundlegenden Dingen wie mathematischen Vektoren und Matrizen. Ich habe das Not Invented Here-Syndrom bei der Arbeit erfolgreich überwunden, aber in einem Hobby ist es nicht verschwunden. Ich wollte keine fertigen Bibliotheken, also setzte ich mich hin, um meine Mathematik zu schreiben. Nein, das ist zu laut gesagt. Ich öffnete mein vorheriges FreePascal-Framework ( https://github.com/perfectdaemon/tiny-glr/ ) und begann, Mathe von dort aus zu konvertieren.
Mit Blick auf die Zukunft möchte ich sagen, dass mein ganz neues Framework im Allgemeinen die Konvertierung des alten von Free Pascal nach TypeScript ist. Nach mehr als drei Jahren Entwicklungspause konnte ich mir keine bessere Architektur ausdenken oder mich sogar an die Minuspunkte der Vergangenheit erinnern.
Nach einiger Zeit ging mir die Luft aus: Die Motivation nahm natürlich ab, die Arbeitsbelastung nahm zu. Und dann hat igdc einen weiteren Wettbewerb angekündigt. Und glauben Sie mir, der Wettbewerb ist ein hervorragender externer Motivator, der thematische, technische und zeitliche Grenzen setzt.
Wettbewerb
Ich habe bereits in meinem letzten Artikel gesagt, was ist Wahnsinn igdc , aber ich werde es hier kurz wiederholen - es ist eine so warme Lampengemeinschaft, die kurze oder mittlere Wettbewerbe veranstaltet, um Spiele zu einem bestimmten Thema zu entwickeln. Ohne Geldpreise, namhafte Sponsoren und Arbeitsplatzsicherheitsgarantien. Ach ja, auch ohne Werbung, Begeisterung und unter Mitwirkung einer freiwilligen Spende für Hosting und Domain. Und das seit fast 15 Jahren.
Wettbewerbsthema - Müllspiel . Angesichts eines umfangreichen und vielfältigen Pakets an grafischen Ressourcen. Die Aufgabe der Teilnehmer ist es, das Spiel nur mit ihm zu machen. Das Genre und das Thema sind nicht beschränkt, die Verwendung von Sounds und Musik ist erlaubt, da nur Grafiken im Pack enthalten sind. Es gibt eine historische technische Einschränkung im Zusammenhang mit dem Start ausschließlich offline, ohne Installer, Download und mehr.
Letzteres ist ein kleines Problem, da Chrome und das Unternehmen viele Dinge verbieten, wenn ein Benutzer eine HTML-Datei lokal öffnet. WebGL lässt sich möglicherweise nicht einschalten, Skripte möchten nicht abgerufen werden, ganz zu schweigen von Grafikressourcen. Es gibt einen Ausweg - wir erstellen einen lokalen, superkleinen Webserver und ein Startskript für den Benutzer, der es aufnimmt und den bevorzugten Browser des Benutzers an der gewünschten Adresse öffnet.
Die Aufgabe ist einfach, ich habe in C # eine 6-Kilobyte-Exe und in der Nähe einen Fledermaus-Spitznamen erhalten, der den Stammordner für den Server und den Port definiert.
Aber genug über dieses kleine Hindernis für ein großes und sauberes Ziel - ein Spiel für den Wettbewerb zu schreiben.
Wettbewerbsspiel
Als ich mir die Ressourcen ansah, stellte ich fest, dass der Arena-Schütze mit ihrem Einsatz ziemlich solide ausfallen würde.
Nachdem ich die grundlegenden Dinge erledigt hatte, ging ich zur Auswahl der benötigten Ressourcen über. Das endgültige Schneiden in Form eines Texturatlas sieht folgendermaßen aus:

Übrigens wurden einige Dinge, die auf dem Atlas gebacken wurden, nie im Spiel verwendet. Nachdem ich die Ressourcen geladen hatte, startete ich eine neue Funktion für mich - Sprite-Animation. Als Kind war ich glücklich, als sich herausstellte:

Eigene Physik
Die Physik anderer mit dem ungezügelten Wunsch, alles selbst zu erfinden, zu verbinden, schien zumindest blasphemisch und schien mir nicht einmal von meinem begeisterten Organismus in Betracht gezogen zu werden (ich habe gerade die Sprite-Animation besiegt, erinnerst du dich?). Was kann bei einer einfachen Kollisionsverarbeitung auf der Basis von Rechtecken (AABB = Axis Aligned Bounding Box) und Kreisen schwierig sein? Viele Dinge. Angefangen damit, einen Charakter in unsichtbaren Ecken festzuhalten, bis hin zur Tatsache, dass Sie alle Objekte Ihrer Welt zu Rechtecken und Kreisen zusammenfügen.
Es war nicht möglich, alle Probleme zu lösen, aber dennoch tauchte ein Teil der Physik auf:

Klingt
Diskret erwartet, dass es schwierig sein wird. In der Tat stellte sich heraus, irgendwie verdächtig einfach und effizient. Wir haben einen Audiokontext erstellt, einen Audiopuffer erstellt, Musik / Sounds in einem für den Browser akzeptablen Format dort abgelegt (ich habe wav verwendet), einen Knoten erstellt und gesagt, von welchem Puffer aus abgespielt werden soll.
Die Sounds, die ich mit bfxr ( https://www.bfxr.net/ ) generiert habe.
Khaki
Krücken, Ad-hoc-Entscheidungen, Podhachivaniya - es ist schwierig, eine Person zu finden, die diese Worte nur vom Hörensagen kennt. Am Ende des Wettbewerbs habe ich ein paar bemerkenswerte Backups eingefügt.
Es wurde kein Text ausgegeben - HTML verwendet
Am Ende des Wettbewerbs wurde klar, dass ich keine Zeit haben würde, das Rendering des Textes auf die Engine zu übertragen. Auch ohne Generator. Es gab viele Optionen, hier sind vier Hauptoptionen:
- Rendern von Text auf einer transparenten 2D-Leinwand, die mit WebGL über der Leinwand liegt.
- Mach ein Spiel ohne Text
- Backe die notwendigen Wörter und benutze sie als Sprites
- Ausgabe HUD in HTML
Gemäß den Wettbewerbsbedingungen war es möglich, nur die bereitgestellte benutzerdefinierte Pixelschrift zu verwenden, sodass die erste Option (Rendern von Text auf einer 2D-Leinwand) entfiel. Canvas kann nur mit Systemschriftarten gerendert werden. Über fontface in CSS geladene Schriften arbeiten extrem instabil.
Das Spielen ohne Text ist eine großartige und kreative Option. Schade, dass ich mich mit meiner Kreativität in diesem Moment schon schlecht gefühlt habe.
Das erforderliche Mindestvokabular war groß und vergrößerte das Vermögen. Darüber hinaus erforderte die Anzeige von Zahlen noch eine gewisse Logik.
Und schließlich kamen wir zu der echten Krücke, die ich benutzte - ich implementierte einfach das HUD als HTML-Markup unter dem Canvas, verband @fontface mit CSS und organisierte das Update über die Standard-DOM-API (getElementById).
Neustart des Spiels - document.location.reload ()
Wenn ein Spieler stirbt, möchte er das Spiel entweder beenden oder erneut starten. Wenn Sie von Anfang an keinen Neustartmechanismus vorsehen und den gesamten Status des Spiels in einigen schlecht organisierten Klassen verschmieren, erhalten Sie leider keinen netten Neustart. Es wird immer einen magischen Ort geben, der nicht auf Null zurückgesetzt wurde.
Eine ausgezeichnete Krücke in diesem Fall war ein banales Neuladen der Seite über den im Header erwähnten document.location.reload () -Header. Angesichts der geringen Größe des endgültigen Builds (weniger als 300 KB, einschließlich aller Ressourcen) und der Tatsache, dass das Spiel lokal funktioniert, kann die Neustartgeschwindigkeit vernachlässigt werden.
Was ist passiert?
Sie können es hier online ausprobieren: https://perfectdaemon.imtqy.com/151/index.html
Link zum Repository: https://github.com/perfectdaemon/ts-game
Die Repository-Version mit dem Quellcode dieses Spiels: https://github.com/perfectdaemon/ts-game/releases/tag/0.1.0
Der Abschluss ist ein angenehmes Ende.
Abschließend möchte ich kurz die subjektiven Vor- und Nachteile des Schreibens von Spielen auf WebGL + TypeScript umreißen.
Vorteile
- Einmal schreiben, überall spielen / debuggen. Es ist sehr cool, dass ich das Spiel einfach auf imtqy.com stellen kann und jeder es von jedem Gerät mit einem Browser abspielen kann. Natürlich mit einigen Vorbehalten.
- Nach bestimmten Einstellungen und dem Hinzufügen von TypeScript ist die Arbeit mit modernem JS nicht so schlecht.
- Praktisch, um Kontext zu erstellen (im Vergleich zu Win API und OpenGL)
- Es gibt ein praktisches Tool (Visual Studio Code), das gut mit Plugins ausgestattet ist und beim Schreiben von Code durch Tipps, Snippets und Notizen zu Problembereichen wirklich hilft.
Nachteile
- Javascript läuft in einem einzigen Thread. Und das Problem ist nicht einmal, dass Sie Physik oder Logik in getrennten Strömen betrachten möchten. Die Profilerstellung ergab, dass WebGL-Aufrufe blockiert werden, d. H. Sie warten, bis die Steuerung vom Grafikkartentreiber zurückgekehrt ist, bevor sie mit der Ausführung des Codes fortfahren. Obwohl die meisten WebGL-Aufrufe nichts als ungültig zurückgeben. Desktop-OpenGL-Implementierungen (in einigen Treibern) für viele Funktionen geben die Steuerung sofort zurück, wodurch die Rendergeschwindigkeit erheblich erhöht wird.
- Ein kleiner Schritt nach links / rechts - und Sie sind ganz alleine. Haben Sie ein Problem mit Angular und Typescript? Die ersten beiden Links zum Stapeln von Überläufen helfen Ihnen dabei. Es bestand der Wunsch, sich mit Typescript separat anzufreunden, und ein seltsamer Fehler / eine seltsame Frage trat auf? Machen Sie sich bereit für die Tatsache, dass Sie allein sein können. Natürlich bin ich als Person, die zuvor über den sehr beliebten (Nein-) Stapel von FreePascal + OpenGL geschrieben hat, daran gewöhnt. Aber bei einer ausgereiften Sprache wie C ++ wird es immer einen Inder geben, der ein solches Problem bereits gelöst hat. Und dann die Chinesen, die es mit dem Controller von Guitar Hero und Arduino gelöst haben.