Mein erstes NES Spiel erstellen, Ludum Dare

Leider ein NES-Spiel zu schaffen, hat alles, was in Assembler geschrieben werden. Als ich an der Georgia Tech Arbeit an meiner Informatik Bachelor-Abschluss war, habe ich ein Projekt, wo ich musste Assembler-Code für ein emulierten MIPS-System schreiben. Der Emulator wurde SPIM genannt (MIPS rückwärts buchstabiert), und es sieht aus wie es heute zum Download noch verfügbar ist. Während Montage Schreiben mir nicht ganz fremd ist, ist es auf jeden Fall nicht einer meiner liebsten Dinge zu tun. Allerdings war es meine einzige Option für ein NES-Spiel zu schaffen, und es war eine schöne Auffrischung, da ich keinen Assembler-Code in Jahren geschrieben hatte.







Mein erstes NES Spiel erstellen, Ludum Dare

Laufen NES Assembler zu bekommen einen Sprit auf dem Bildschirm in dem NES-Emulator zu bewegen

Im dritten Tutorial. es geht in die Details des 6502 Assembler-Code, der der Befehlssatz von dem NES-Assembler verwendet wird. Es verfügt über alle Standard-Operatoren, die Sie würden, wie „Last“ und „store“ für das Schreiben auf die Register und Speicher erwarten. Das NES ist ein ziemlich simpel System, das nur drei Register hat, die die Accumulator, Register X und Y. Register Der Befehlssatz hat auch einfache mathematische Funktionen wie „add“ und „subtrahiert“ und Steuer Operatoren wie „springen“ und "Ast". Das Beispiel dieser Lektion gab genug, um loszulegen die Farbe des Bildschirms auf der ausgewählten Palette Wert basiert zu ändern. Getestet habe ich durch die Bildschirmfarbe auf verschiedene Kombinationen von Rot zu ändern, Grün und Blau durch den Binärcode des Bytes zu modifizieren, die die Bildschirmfarbe steuert.

Um das Sprites für mein Spiel zu machen, habe ich ein Programm namens YY-CHR. Es ist eine andere ausführbare Windows-Datei, aber es läuft auch gut unter Ubuntu mit Wine. Das einzige Problem, das ich gestoßen war, dass ich nicht in der Lage war, eine Bitmap in Gimp, zu erstellen und dann kopieren und in YY-CHR einfügen. Deshalb habe ich meine eigene „Hand gezeichnet“ Smiley Sprite, die aus vier 8 × 8-Pixel-Kacheln hergestellt wird.

Dies ist jedoch nicht sehr interessant, da es immer nur in das gleiche Spiel kompiliert. Als Ausgangspunkt, habe ich eine Datei game.xml und definiert vier Farben, die die vier Farben der aktuellen Palette definieren. In der mitgelieferten nes_palette.rb Datei, begann ich Farben basierend auf der Tutorial-Tabelle und gespeichert, diese Farbkonstanten und die entsprechenden Hex-Werte in ein Hash zu definieren. Dann wird in einem anderen Skript, das die game.xml Datei mit REXML und XPath liest, ich die definierte Palettenfarben des Benutzers gespeichert in Array. Dann wird die Palette Code sieht nur diese Werte in der Hash bis die richtigen Hex-Werte zu erhalten, um Palettendaten mit der Db-Richtlinie zu schreiben. Schließlich fügte ich ein Tag enthalten diese Elemente.

Mein erstes NES Spiel erstellen, Ludum Dare

Ändern der Palettenfarben eines Sprites Benutzer definierten Werte in einer XML-Datei mit

Mein erstes NES Spiel erstellen, Ludum Dare

Erstellen einer einfachen Sprite in YY-CHR

Mein erstes NES Spiel erstellen, Ludum Dare

game.xml, die verschiedene Eigenschaften des NES-Spiel definiert

Leider erreicht, wenn die Kugel den rechten Rand des Bildschirms, es Schleife zurück zu der linken Seite befindet. Auch wird, wenn die A-Taste gedrückt, die eine Kugel wird an die Stelle des Raumschiffes zurückgesetzt. Ich habe eine Variable in dem Assembler-Code die „lebendig“ Flagge zu halten. Wenn die A-Taste gedrückt wird, lade ich ein 1 (LDA # $ 01) und speichere sie in der lebendigen Flagge. Im UpdateBullets Abschnitt, lade ich die Kugel am Leben Flagge und vergleichen Sie es mit 1 (CMP # 01 $) und bis zum Ende des Abschnitts springen, wenn es nicht gleich (BNE) ist. Dadurch wird die Kugel Stopp machen, wenn sie nicht am Leben ist. Mit dieser Referenz ich gelernt, wie man überprüfen, ob ein Wert größer oder kleiner als eine Anzahl von dem BCC mit und BCS ( „Zweig trägt klar“ und „Zweig carry-Set“) Anweisungen. Mit BCC, wenn die x-Position der Kugel ist weniger als 240 (# $ F0), dann wird es bis zum Ende des Abschnitts springen, sonst wird es die lebendige Flagge auf Null gesetzt. I 240 verwenden anstelle von 255 aufgrund der Werte zurück um auf Null Looping, wenn der Wert die 255-Byte-Grenze für einen überschreitet. Solange die Kugel Geschwindigkeit kleiner als 15 sollte es keine Probleme geben. Es gibt Techniken zum Prüfen, ob der summierte Wert 255 überschreitet, die für 16-Bit-Zahlen verwendet wird, so werde ich das später untersuchen. Um dies zu beheben, das andere Reset-Problem Einschussposition, wenn A wiederholen gedrückt wird, nachdem die A-Taste las ich einfach die Kugel am Leben Flagge geladen, verglichen mit einer und bis zum Ende gesprungen, wenn er gleich ist.







Mein erstes NES Spiel erstellen, Ludum Dare

Anzeige der Spielerschiff, Rakete, feindliche Schiff und Partitur auf dem Spielbildschirm.

Der nächste Schritt war einen Feind auf dem Bildschirm zu bekommen. Ich benutzte YY-CHR einen neuen Feind Schiff Sprite auf meine spritesheet zu schaffen, die weitere vier Kachel Sprite ist. Ich habe eine neue Tag meiner XML-Datei, die alle Eigenschaften des Feindes enthält. In dem Code Rubin, fügte ich ein Array alle Gegner zu halten, und ein feindliches Klasse, die die Speicherplätze der X und Y-Position des Gegners enthält. I definierte auch einen „lebendig“ Flagvariable für den Feind, so dass ich es tot setzen, wenn er zerstört wird. In Zukunft könnte ich auch hinzufügen, ein Leben Wert, wenn der Feind mehr Hits nimmt, getötet zu werden. Um den Feind in Fahrt, halte ich einfach nur Subtraktion der Geschwindigkeitswert des Schiffes auf die x-Position variabel, so wird der Feind ständig halten in Richtung der linken Seite des Bildschirms zu bewegen. Das ist nicht wirklich beeindruckend, aber zumindest ist es bewegt was dem Spiel ein bisschen eine Herausforderung. Wenn das Schiff „lebendig“ Flagge auf Null (# $ 00) gesetzt ist, dann stoppt das feindliche Schiff zu bewegen.

Ich trennte alle den Objektcode in seinen eigenen Ruby-Skript, das die Speicherplatz all Kacheln für jedes der Objekte statt. Der Update-Code für jedes der Objekte wurde auch an ein anderes Skript enthält Update Subroutinen bewegt. Im Update-Skript werden die Orte der Fliesen auf der Grundlage der Lage des Objekts sowie ein Offset, die auf der Fliese der Zeile und Spalte in den Spriten-basierte hinzugefügt wird.

Als nächstes fügte ich Kollisionserkennung zwischen der Kugel und dem feindlichen Schiff. Dies wurde durch eine Reihe von CMP erreicht, BCS und BCC-Anweisungen, die prüfen, ob die x Kugel und y-Position innerhalb des Gegners Sprites ist. I subtrahiert 4 von den linken und oberen Grenzen des feindlichen Schiffes, so dass eine Kollision erkannt wird, wenn die x Kugel oder Y an die feindlichen Schiffs x oder y gleich ist, da es keine „größer oder gleich“ ist Operator. Wenn die Kugel mit dem feindlichen Schiff kollidiert, wird die Kugel am Leben Variable auf # 00 $. Dann wird JSR aufgerufen um den Code auszuführen, um die Punktzahl des Spielers zu erhöhen. Diese Kollision Code überprüft, um zu sehen, ob die Kugel der x, y-Position innerhalb des feindlichen Schiffs Rechteck ist, die Dinge einfach zu machen. den Code modifizieren tun Rechteck / Rechteck Dinge zu viel für dieses einfache Spiel erschweren würde.

Der nächste Schritt war einen einfachen Sound zu bekommen zu spielen, wenn eine Kugel geschossen, die ich bekam Arbeit durch dieses Tutorial folgen. Dies spielt nur einen einfachen Piepton, und ich geändert, so dass es nicht ständig durch spielt den Längenzähler ermöglicht und es auf 0001 einstellen.

Mein erstes NES Spiel erstellen, Ludum Dare

Zwei Feinde auf dem Bildschirm mit sechsstelligen Score

Ich habe einen zweiten Feind im Objektskript definiert, um den Feind Array zugibt und legen Sie die entsprechenden Adressenwerte für die X-, Y- und tile Indexwerte. Denn jetzt habe ich alle von der Kugel Kollision und Feind Bewegungscode für den zweiten Feind nur dupliziert. Ich habe einen neuen „Gametime“ varaible, die auf jeder NMI Interrupt-Pause erhöht werden. Wenn die Gametime Variable # $ FF gleich ist, dann sind beide Feinde lebendig und ihre y-Position auf eine Position auf dem Bildschirm zurückgesetzt sind. Dies gibt das Auftreten neuer feindliche Schiffe Laichen.

Um ein Spiel über Zustand zu haben, habe ich eine neue Variable des Spielers Leben zu verfolgen. Jedes Mal, wenn das Schiff des Spielers mit einem feindlichen Schiff kollidiert, wird ein neues Unterprogramm aufgerufen, die man aus dem Leben des Spielers subtrahiert, und stellen Sie den Spielzustand auf „GAME OVER“, wenn die Anzahl des Lebens gleich Null ist.

Mit meinem Sprite-Editor, habe ich eine Titelgrafik für das Spiel. Allerdings fand ich schnell, dass es nicht so einfach ist, alle Hintergründe Fliese auf dem Bildschirm auf einmal zu ändern. Ich habe versucht, ein paar Dinge, aber ich hatte wenig Glück. Nachdem auf einigen Foren Gruben um, fand ich, dass es wirklich nicht möglich ist, den gesamten Hintergrund in einem Update zu aktualisieren, wie der Bildschirm in der modernen Spiel Programmierumgebungen zu aktualisieren. Ein Plakat sagte, dass es nur möglich ist, drei Zeilen oder Spalten in einem Update zu aktualisieren, oder das Spiel beginnt sich zu verlangsamen. Denn jetzt verlasse ich den Titel-Bildschirm aus, aber ich hoffe, es schließlich in das Spiel zum Laufen zu bringen.

Mein erstes NES Spiel erstellen, Ludum Dare

Titelbildschirm ... hinzugefügt werden ... hoffentlich.







In Verbindung stehende Artikel