Wie ich ein Spiel für Notepad gemacht habe



Beim Lesen über ungewöhnliche Lösungen von Indie-Entwicklern stieß ich auf Gold. Hier ist ein Artikel über das Spiel in einem Texteditor. Kunst, Animation, Handlung - alles ist so, wie es sein sollte.

Ich habe das Spiel erstellt. Und doch tat es weh ( vielleicht wollte der Autor sagen, dass es weh tut, aber ich könnte diese Option absichtlich verwenden - ungefähr ).


Das Projekt kann hier heruntergeladen und der Code auf Github angezeigt werden .

Alles begann im Jahr 2017 mit der Frage: "Ist es möglich, ein Spiel im Editor zu erstellen?" Dann grinste ich nur. Drei Jahre sind vergangen. Nachdem ich darüber nachgedacht hatte, wie alles funktionieren wird und sichergestellt hatte, dass es real ist, entschied ich mich für dieses Spiel.

Normalerweise drückst du einen Knopf und etwas passiert im Spiel. Drücke A und Mario springt. Alles ist an Informationen und Feedback gebunden. Das Spiel erhält Eingaben und zeigt seine eigenen an.

Im Spiel für Notepad gibt es Änderungen an der Eingabe, die der Benutzer an der Datei vornimmt, und an der Ausgabe Änderungen, die das Spiel an der Datei vornimmt. Zu diesem Zweck verfolgt die Anwendung die Zeit, zu der die Datei zuletzt gespeichert wurde. Wenn es sich geändert hat, liest das Spiel den Inhalt der Datei und fügt neue Daten hinzu.

Es gibt ein Problem: Notepad von Microsoft überprüft nicht, ob die Datei geändert wurde. Ich müsste die Datei speichern, schließen und wieder öffnen. Das Erstellen eines solchen Spiels ist möglich, klingt aber nicht sehr lustig. Ich musste nach einer Alternative suchen.

Ich kann Ihre Enttäuschung aufgrund der Tatsache verstehen, dass das Spiel als Ergebnis nicht im üblichen Editor gemacht wurde. Mein Titel kann darin ausgeführt werden - nur ein wenig verwirrter Prozess. Ich beschloss, die Coolness des Projekts zu opfern, um das Spiel angenehmer zu machen.



Alternative


Ich musste nach einem anderen Texteditor suchen. Die einzige Voraussetzung war die automatische Aktualisierung der Dateien. Obwohl Sie etwas später sehen werden, dass ich eine andere Funktion verwendet habe.

Zuerst kamen Notepad ++ und Sublime Text in den Sinn. Aber sie sehen im Aussehen überhaupt nicht wie Notepad aus, der Charme des Projekts wäre völlig verschwunden. Außerdem fragen sie den Spieler, ob er die Datei aktualisieren möchte. Dies ist viel besser als das Schließen und Öffnen einer Datei, lenkt aber dennoch vom Gameplay ab. Ich wollte, dass die Datei automatisch aktualisiert wird. Dann fiel mir Notepad2 auf. Er war fast perfekt.

Der Editor kann so konfiguriert werden, dass er wie MS Notepad aussieht, und vor allem überprüft er die an der Datei vorgenommenen Änderungen. Aber genau wie Notepad ++ und Sublime Text fragt Notepad2 den Player, ob die Datei geändert werden muss. Glücklicherweise hat der Editor Open Source Code und ich könnte ihn perfekt polieren.



Notepad2 ist in C geschrieben. Ich bin mit dieser Sprache ein wenig vertraut, auch wenn ich nicht als Experte bezeichnet werden kann. Ein erfahrener Javascript-Programmierer kann das allgemeine Wesen des Codes lesen und verstehen, aber es war nicht so einfach, den Quellcode von Notepad2 zu verstehen, um die erforderlichen Änderungen vorzunehmen.

Zunächst habe ich mich entschlossen, im Dialogfeld nach Text zu suchen: „Die Datei wurde von einem externen Programm geändert. Datei neu laden? ". Dies ist der Wert der Variablen, die als Argument in der Dialogfeldfunktion verwendet wird. Und ich habe sie gefunden.

if ((iFileWatchingMode == 2 && !bModified && iEncoding == iOriginalEncoding) ||
        MsgBox(MBYESNO,IDS_FILECHANGENOTIFY) == IDYES) {

Dieser Code prüft, ob sich der Inhalt der Datei geändert hat. Wenn es sich geändert hat, wird ein Fenster geöffnet und das Programm prüft, ob der Benutzer "Ja" gewählt hat. Ich musste nur ein Stück ersetzen

MsgBox(MBYESNO,IDS_FILECHANGENOTIFY) == IDYES

auf TRUE, und das Programm begann, die Datei automatisch zu aktualisieren. Also habe ich ein ASCII-basiertes Rendering erstellt. Es bleibt ein geeigneter Motor zu schaffen.

Zeichnung


Das Spiel ist mit Liebe gemacht: LÖVE ist ein Open Source Framework für 2D-Spiele, die in Lua geschrieben wurden. Ich habe diese Plattform viele Jahre lang genutzt und sogar ein Tutorial zusammengestellt . Für dieses Projekt wurde hauptsächlich das LÖVE-Modul des Dateisystems verwendet, da es alle notwendigen Funktionen bietet. Normalerweise erstellt LÖVE ein Bild, das dann auf dem Bildschirm angezeigt wird.

Ich brauchte fast das Gleiche: die Ausgabe von ASCII-Kunst in einer Textdatei. Ich begann mit einem Haus und einem Vogel, und der Vogel sollte durch eine Akte fliegen. Ich habe die Kunst genommen, die ich auf ASCII Art gefunden habe , aber im Spiel werden nur Originalwerke verwendet (außer Schriftarten).



Und: Beim



Herunterladen von Kunst wird nur eine Datei gelesen.

house = love.filesystem.read("art_house.txt")
bird = love.filesystem.read("art_bird.txt")

Das Haus wird als Hintergrund verwendet, daher habe ich dieses Bild zunächst auf dem „Bildschirm“ gezeichnet. Der Bildschirm ist in diesem Fall home.txt.

love.filesystem.write("home.txt", house)

Ich wollte, dass der Vogel so arbeitet:

local x, y = 20, 40
drawArt(bird, x, y)

x ist die Spaltennummer, y ist die Zeilennummer. Deshalb zerlegte er den Bildschirm und den Vogel in Linienlisten.

-- Get the current canvas
screen = love.filesystem.read("home.txt")

-- Create a table. A table is like an array.
screen_lines = {}

-- The lua pattern (.-)\n says capture everything until the \n (newline).
-- We add an \n to the end of the file so that it captures the last line as well.
for line in (screen .. "\n"):gmatch("(.-)\n") do
    table.insert(screen_lines, line)
end

Mit dem Vogel tat das gleiche. Nun sollte der Code, der den Vogel beschreibt, den Hauscode überlappen. Folgendes brauchte ich:

  1. Finden Sie die Linie, in der der Vogel gezeichnet werden soll.
  2. Drucken Sie die gesamte Zeile auf x.
  3. Drucken Sie den Rest der Zeile aus, beginnend mit x + der Länge der Grafik mit dem Vogel.
  4. Erstellen Sie eine neue Linie mit dem ersten Teil, dem Vogel und dem verbleibenden Teil.
  5. Wiederholen Sie das gleiche für alle anderen Zeilen.

Im Code sieht es so aus:

function drawArt(art, x, y)
    art_lines = getLines(art)

    -- In Lua, you can get the length of a table and string with #
    for i=1, #screen_lines do
        if i == y then
            for j=1 ,#art_lines do
                -- With string:sub(start, end) we can get part of a string
                local first_part = screen_lines[i]:sub(1, x - 1)
                local second_part = screen_lines[i]
                                    :sub(x + #art_lines[j], #screen_lines[i])
                screen_lines[i] = first_part .. art_lines[i] .. second_part
            end
        end
    end
end

Was passiert ist:



Wahrscheinlich haben Sie bemerkt, dass der Vogel ein Rechteck ist - Räume werden in seiner Kunst verwendet. Um Abhilfe zu schaffen, habe ich die Anzahl der Leerzeichen am Anfang jeder Zeile berechnet und diese Anzahl zu den Koordinaten hinzugefügt, sodass nur Kunst gezeichnet wird.

-- (%s) gets all the whitespace characters.
local spaces = art_lines[j]:match("(%s*)")
-- Remove the spaces from the line.
art_lines[i] = art_lines[i]:sub(#spaces + 1, #art_lines[i])
local first_part = screen_lines[i]:sub(1, x + #spaces - 1)
local second_part = screen_lines[i]:sub(x + #spaces + #art_lines[j], #screen_lines[i])
screen_lines[i] = first_part .. art_lines[i] .. second_part

Es ist viel besser geworden:



Animation


Ich habe angefangen, weitere Chips hinzuzufügen, zum Beispiel Animation:



Alle Frames befinden sich in einer Datei und sind durch das Tag {{F}} getrennt. Das Tag wird beim Lesen festgelegt und ermöglicht es Ihnen, die Reihenfolge der Frames festzulegen. Dank dessen erhalten wir eine klassische Animation. Erstellen Sie einen Timer und zeichnen Sie die entsprechenden Frames.

{{F}}
_   _ 
 'v'
{{F}}
      
--v--
{{F}}
      
_/v\_

Ich habe auch die Ausgabe des gedruckten Textes implementiert und einen Bildschirm, ein Inventar und ein Fenster zur Eingabe der Lösung separat angezeigt. Es gab ein Problem. Woher weiß das Spiel, dass eine Datei geöffnet wurde? Dies ist die zweite Funktion, über die ich zuvor gesprochen habe.

Im Quellcode von Notepad2 habe ich vorgeschrieben, dass die Datei sofort nach dem Öffnen gespeichert werden soll. Das Spiel prüft dann, ob sich die letzte Speicherzeit geändert hat. Also findet sie heraus, dass die Datei geöffnet war und kann sie ändern.

// At the end of the FileLoad function.
// If the file is not new, and the file has not been reloaded, save it.
if (!bNew && !bReload) {
    FileSave(TRUE,FALSE,FALSE,FALSE);
}

Als Ergebnis habe ich einen Rahmen bekommen, in dem Sie arbeiten können. Es ist Zeit, ein Spiel zu erstellen.

Neun Tage lang (gemessen am Erstellungsdatum der GIF-Dateien) habe ich Folgendes getan:



Wenn Sie das Spiel ausgeführt haben, wissen Sie, dass es keinen druckbaren Text oder keine druckbare Animation enthält. Dafür gab es mehrere Gründe:

  • , HDD/SSD . . , .
  • . , , . , .
  • — , . . . , , -, . . , , . , , , — .


Ich war wütend, dass der Benutzer die Datei in das Notepad2-Fenster ziehen musste, um das Spiel zu starten. Durch Doppelklick auf die Datei wurde Notepad oder ein anderes Standardprogramm zum Lesen von .txt geöffnet. Es war möglich, einen Befehl zu registrieren, der die Anwendung für solche Dateien auf Notepad2 geändert hat, aber ich persönlich würde es nicht mögen, wenn eine Art Spiel auf meinem Computer eine solche Finte machen würde.

Vielleicht die ursprünglichen Einstellungen zurückgeben, wenn Sie das Spiel schließen? Es ist möglich, aber es wird ein Problem geben, wenn das Spiel abstürzt oder unerwartet geschlossen wird.

Alle Entscheidungen schienen unzureichend begründet zu sein, bis mir klar wurde, dass anstelle der üblichen TXT-Dateien ein anderes „x“ verwendet werden konnte. Um genau zu sein, ist das Unicode-Zeichen U + 0445 (kyrillischer Kleinbuchstabe Ha). Um nicht verwirrt zu werden, habe ich die Datei * .tXt genannt. Infolgedessen hatten alle Spieledateien eine Auflösung von * .tXt und wurden standardmäßig in Notepad2 geöffnet.

assoc .tXt=tXt
ftype tXt=[directory]/.notepad/Notepad2.exe "%1"

Das Standardprogramm kann nur als Administrator zugewiesen werden. Wenn Sie das Spiel unter einem anderen Konto öffnen, werden TXT-Dateien verwendet. Wenn Sie die Datei im normalen Editor öffnen, werden Sie vom Spiel darüber informiert, dass Sie die Datei in das geöffnete Notepad-Fenster ziehen müssen. Oder führen Sie es als Administrator aus, damit es durch Doppelklick geöffnet wird.

Motivation


Tatsächlich wurde alles vor drei Jahren gemacht. Was habe ich den Rest der Zeit gemacht? Ein klassisches Beispiel für mangelnde Motivation.

Anfangs war die Handlung etwas länger als jetzt. Der Drache hat deine Eltern getötet, du musst zum Schmied Ferdan gehen, also hat er ein Schwert geschmiedet. Es wurde angenommen, dass das Schwert aus drei Materialien besteht, die gesammelt werden müssen. Dies erhöhte das Volumen des Spiels erheblich und beschleunigte das Ende der Entwicklung. Das Spiel war nicht sehr unterhaltsam und ich gab das Projekt zwei Monate später auf.

Aber ich habe es die ganze Zeit im Kopf behalten. Ich habe ein ganzes Framework getestet, mit dem ich ein Spiel in Notepad erstellen konnte, und das Projekt wurde nicht umgesetzt. Es war notwendig, es zu beenden. Im Jahr 2019 habe ich fast kein Projekt abgeschlossen. Die Enttäuschung veranlasste mich zu der Entscheidung, das Unvollendete im Jahr 2020 zu beenden.

Und hier ist sie. Ich verkürzte die Handlung, gab mir einen Monat für alles (es stellte sich heraus, dass es eine Woche länger war) und eilte in die Schlacht. Immer noch für A MAZE beantragt. Die Frist für die Vergabe der Preise war jeweils für den 2. Februar festgelegt. Es gab also Motivation.

Fazit


Ich bin froh, dass ich das Spiel beendet habe. Es ist erstaunlich, wie lange das Projekt nur digitalen Staub gesammelt hat, aber am Ende war ein Monat genug. Das Spiel sollte nicht so umfangreich sein, wie ich es zuerst wollte - ein solches nicht standardmäßiges Projekt sollte nur die Funktionen zeigen, die darin implementiert werden können.

Was weiter? Ein Malspiel? Spiel im Taschenrechner? Ich werde sie wahrscheinlich nicht machen. Aber ich denke gerne an Spiele, die nicht traditionelle Plattformen verwenden.

All Articles