Hallo Besucher, der Thread wurde 35k mal aufgerufen und enthält 69 Antworten

letzter Beitrag von RKSoft am

Einfache Spieleentwicklung am Beispiel :-)

  • Punkt 1: der grosse Rotor
    Punkt 2: etwa pixelgenaue Kollisionsabfrage
    Punkt 3: scrollender Screen
    Punkt 4: bunte Grafik
    Punkt 5: Levelmaps
    Punkt 6: lustige Musik

    Punkt 7: Kopierschutz ;)


    Genau! Man fängt niemals nicht mit dem Titelbild an :)


    Genau! Fangen wir erstmal mit dem Kopierschutz an, dann das Titelbild. ;) Punkt 7 hat durchaus seine Daseinsberechtigung. Szene-Leute wollen ja auch ihren Spass haben. Also muss Enthusi sich überlegen, ob sein Spiel am Ende ein cooles Cräg-Intro (etwas Abwechslung in Punkt 6), einen eingebauten Trainer, Extra-Maps (wodurch sich Punkt 5 von selbst erledigt) und ggfs. Bugfixes verpasst bekommen soll. ;) (Und wenns nur ein einfacher Sektor-Defekt ist, der im G64 funktioniert, aber nicht im D64.)

  • Auch wenn es hier weder um Intros, Titelbilder oder dergleichen ging bisher:
    Kuru Kuru XXX hat einen recht ausladenen Vorspann den ich nicht gedenke zu uebernehmen ;-)
    Bis zum Cave-Level etwa sollte alles machbar sein. Ob man sich ueberlegt auch die bewegten Levelelemente zu imitieren sieht man dann. Muss vielleicht gar nicht.
    Es geht ja ohnehin nicht um einen 1:1 Port, sondern um ein einfaches (!) Entwicklungsbeispiel mit typischen Hindernissen und Ansaetzen.


    Ein prima Beispiel hab ich selbst geliefert :-)
    Ich gehe sofort davon aus, dass ssdsa recht hat (vielleicht aber auch nicht), da ich den Sprite-Kollisions-Register nie benutze sonst - bei den bitmap/sprite Prioritaeten ist das so natuerlich und in der Tat beim Kollisionsregister auch.
    Also eine Gute Nachricht!
    Was macht man wenn man sich unsicher ist bei so einfachen Fragestellungen?
    Zwei Loesungen (eigentlich drei):
    1) andere Coder konkret fragen (im IRC oder sonstwo)
    2) einfach in den Raum rufen wieso das alles nicht geht oder dass VICE einen bug hat ;-) (in einem Forum z.B.)
    3) ausprobieren


    Bei manchen Dingen bietet sich 1) an und man laeuft immer wieder Gefahr zu schnell danach zu 'greifen'.
    2) ist eigentlich selten hilfreich
    3) Allemal schneller als 2 und man lernt es oft erst dann wirklich. Zudem bekommt man von 1 und 2 vielleicht unterschiedliche Antworten ;-)


    Hier also ein Beispiel fuer einen schnellen Test:
    - das Programm wurde in den MC charmode versetzt (muessen wir ja ohnehin bald)
    - statt #$51 PETSCII Kugeln definiere ich einen test-charset mit 00, 01, 10, 11 Bitmuster
    - der random plotter setzt diese Muster jetzt eingefaerbt als 3, 4, 5 (cyan, lila, gruen).
    - ein kurzer code um das Kollisionsregister bitweise anzuzeigen (oben links):
    lila = bit geloescht
    cyan = bit gesetzt


    Solche Debug-routinen sind immer sehr hilfreich und in ein paar Zeilen geschrieben.
    Damit kann man ja schonmal rumspielen. Man erkennt schoen die 3 motion-blur sprites die mit dem lila char kollidieren aber nicht mit den cyan char.
    D.h. %00 und %01 (nicht %10) gelten als Background...


    Was die Sinnigkeit des Kollisionsregisters angeht:
    spaeter haben wir Sprungfedern im Level. Also Objekte mit denen wir kollidieren koennen, auf die aber anders reagiert wird als auf Waende.
    Das geht immernoch mit sprites indem man naemlich jeweils die naechste Sprungfeder mit nem dummy sprite ueberlagert (naja, etwas overkill),
    oder man braucht spaetestens dann eine charbasierte Kollisionsabfrage. Das ist aber immernoch praktischer mit Sprites vorweg, denn dann muessen wir die Charpositionen entlang des gesamten Rotors
    NUR DANN bestimmen wenn wir gegen irgendetwas gegengefahren sind. Das passiert ja hoffentlich nicht jeden Frame ;-)
    Also mit 2 Befehlen sehr viel Rasterzeit gespart am Ende denke ich.


    Zu Kopierschutzmechanismen: auch die gehoeren hier zunaechst nicht her.
    Ausserdem ueberfordern diese offenbar ohnehin die meisten :-)
    Ullis indirekten Schutz auf dem Jars' Revenge Modul hat noch immer niemand geknackt und die mir bekannten interessanteren Spiele wurden zuletzt auch stets als RAM-dump gefreezed...
    Dann macht das natuerlich auch eh keinen Spass.
    Aber ich hoffe dieser Thread sortiert sich ein wenig...


    Gruss,
    Martin /enthusi

  • Nee isser nicht :)
    Aber den schleppe ich noch ne Weile mit.
    Womoeglich wuenscht sich am Ende eh ein Grafiker feine overlaysprites fuer den Rotor (MC+Hires oder eben 3x Hires sogar).
    Feintuning folgt viel spaeter. - optisch wie auch code-technisch.

  • Wahrscheinlich ist noch nicht die Zeit für Bug-Reports aber Diagonal-Bewegungen in Kombination mit "links" funktionieren, mit "rechts" aber nicht.


    Darüber hinaus: Ich finde, du hast ein gutes Spiel ausgesucht. Aufgrund des recht abstrakten Originals versucht mein Gehirn automatisch, dass in eine Art Thema/Welt zu transportieren (so wie das bei dem von Green verlinkten "Roundabout" passiert ist: ein sich drehendes Auto – Schwachsinn, aber irgendwie trotzdem gut). Vielleicht heißt der Protagonist hier Milly (von Mill = Mühle) oder man ersetzt die recht statisch wirkenden Linien durch (sich nicht berührende) Kugeln und hat dann eine Szene im atomaren Micro-Kosmos. Rumspinn ....


    Sorry für meinen Ausflug – Coden kann ich nicht – und ich lass die Profis hier zukünftig mal besser ohne meine Zwischenrufe fertig machen. Grafik kommt ja erst später.

  • Mit dabei:
    - einfache, buggy Joysteuerung :)


    Keine Sorge, ist bewusst. Ebenso wie das misachtete MSB bei den Sprites.
    Das passiert bei mir erstmal alles nach "Problem ist loesbar, also naechstes Problem...".
    Dann kommen _relativ_ bald die ersten Aufraeumarbeiten ;-)


    Gute und eher nicht-so-gute Nachrichten ;-)
    Ich hab mal in VBA ein Teil reversed vom Spiel.
    Schlecht1: die Maps sind zu keiner Zeit voll im RAM (war leider zu befuerchten). Es wird immer nur ein Screen angezeigt und der 'reinscrollende' Kontent in Echtzeit entpackt.
    Man muesste sich also genau den (ARM)Code etc ansehen um einen eigenen Entpacker zu schreiben etc. Weiss man nicht ob man das will (siehe Schlecht2).


    Gut1: Mit ein wenig Nachlesen konnte ich den Aufbau analysieren (interessiert das Jemanden? Ist ja GBA spezifisch, obwohl es interessant ist, lasse ich das sonst halbwegs weg hier).
    Mein VBA hat leider keinen super debugger aber IO-Register analysieren reicht hier schon.


    Ein Screen wie in screenshot.png baut sich aus 3 Ebenen auf. Jede besteht aus einer 32x32 tilemap aus 8x8 tiles (der angezeigte screen ist allerdings kleiner als 32x32 tiles).
    Die GBA Grafik (in diesem Mode) ist also im Prinzip wie die charmode gfx am C64.
    Es gibt n Tiles (bis 1024!) und eine map mit Zeigern auf diese Tiles (wie screenram am c64).


    Kuru unterteilt das im gezeigten shot in:
    - bglayer3.png Hintergrund mit Steinen (ganz 'hinten') - das sind C64 Farben ;-) Die Farbpaletten hab ich nicht rausgezogen vorerst
    - bglayer2.png Strecke selbst und Start/End-Felder
    - bglayer1.png Streckenbegrenzung


    Im Prinzip interessiert uns nur bglayer1.
    Gute Nachricht: ich zaehle etwa 128 tiles fuer die Streckenebene.


    Schlecht2: GBA kann jedes Tile horizontal und/oder vertikal spiegeln.
    So sieht die map aus ohne dieses Spiegeln:
    bglayer1_raw.png


    Davon wird also massiv gebrauch gemacht. Mit den 256 chars (NUR fuer die Streckenraender, ohne Grafik drumherum) die man am C64 hat, wird das sehr sehr sehr eng.


    Man kann das nun entweder mal ausprobieren oder man baut direkt eigene Level 'nach'.
    Ein Vorteil eigener Level: damit original leveldaten sinnig sind, sollte der Rotor auch exakt so gross/schnell sein wie im Original.
    Und zumindest mit dem aktuellen Ansatz ist der C64-Rotor schon deutlich kuerzer.


    Mein Favorit:
    schauen ob ich doch noch an ALLE Levelmaps komme und die dann anpassen/vereinfachen damit es C64 freundlich wird ;-)


    Also nicht einfach die Daten der Levelmap (16 -> 8 bit) verwenden mit eigenen C64-chars, sondern selbst basteln und die ein oder andere 'Kurve' vereinfachen.


    Soviel dazu erstmal.
    Gruss,
    Martin /enthusi

  • Klarerweise sind die Maps nicht komplett im RAM (davon hat der GBA einfach nicht genug) aber u.U. sind sie leicht vom ROM abgreifbar.
    Bist du dir sicher das die Maps gepackt im ROM sind? Es ist ein sehr frühes GBA Spiel und damals waren grosse Cartridges noch sehr teuer, daher ist es nur 32MBit gross. Aber das sie die Maps deshalb echt packen mussten? Hast du eine Ahnung welche Dimensionen ein so ein Level hat? 256x256? Oder sowas in der Grössenordnung?

  • Ich meinte damit dass nicht einfach 128x128 tiles oder sowas verwendet werden, sondern 32x32 und dann eben nachgeschaufelt wird.
    Das ROM habe ich insgesamt mal grafisch angeschaut aber noch nicht im Detail :-)
    Das wird schon noch...

  • Nein, der ist nicht 32x32 gross, sondern 240×160 Pixel, also 30x20 (sieht man ja auch an meinen dumps), aber natuerlich weil 32x32 das Kleinstmoegliche ist.
    Aber das wird nun vielleicht etwas zu GBA spezifisch fuer dieses Thread ;-)

  • Nein, der ist nicht 32x32 gross, sondern 240×160 Pixel, also 30x20 (sieht man ja auch an meinen dumps), aber natuerlich weil 32x32 das Kleinstmoegliche ist.
    Aber das wird nun vielleicht etwas zu GBA spezifisch fuer dieses Thread ;-)


    Ja, das stimmt schon, aber im Speicher sind die Screens grösser. Man kann entweder einen 32x32, oder zwei 32x32 screens nebeneinander oder übereinander haben. Im extremsten Fall auch 4 in einer Matrix Anordnung, wenn man genug VRAM frei hat.

    Zitat

    In 'Text Modes', the screen size is organized as follows: The screen consists of one or more 256x256 pixel (32x32 tiles) areas. When Size=0: only 1 area (SC0), when Size=1 or Size=2: two areas (SC0,SC1 either horizontally or vertically arranged next to each other), when Size=3: four areas (SC0,SC1 in upper row, SC2,SC3 in lower row). Whereas SC0 is defined by the normal BG Map base address (Bit 8-12 of BG#CNT), SC1 uses same address +2K, SC2 address +4K, SC3 address +6K. When the screen is scrolled it'll always wraparound.


    D.h. der Bildschirm ist nur ein frei positionierbares 30x20 Fenster in diese tile maps. Bei Scrolling über 32 bzw. 64 tiles, muss man eben wie üblich neue Inhalte reinkopieren.


    (Ich war mal GBA Programmierer, sogar professionell, is aber schon sehr lange her)

  • Schrieb ich doch?
    Man sieht 30x20, aber 32x32 ist die kleinste Tilemap.


    Zitat

    aber natuerlich weil 32x32 das Kleinstmoegliche ist.


    Zitat

    (Ich war mal GBA Programmierer, sogar professionell, is aber schon sehr lange her)


    Kann ja nicht frueher als ~2001 gewesen sein und DAS war doch grade erst!! :-)



    domspitze
    Huhu,
    naja, wie ich schrieb wollte ich eigentlich keine Copy-Paste-Texte liefern.
    Bisher war auch nichts dabei was einen besonders ausgefuchsten Algo erfordert haette.
    Vielleicht hast Du ja Lust das Geschriebene (oder ein eigenes Projekt) nachzuvollziehen und meldest Dich hier wenn konkret Probleme auftauchen die Du nicht geloest bekommst.
    Beim reinen Lesen lernt man leider meist sehr wenig nur.

  • Huhu,
    naja, wie ich schrieb wollte ich eigentlich keine Copy-Paste-Texte liefern.
    Bisher war auch nichts dabei was einen besonders ausgefuchsten Algo erfordert haette.
    Vielleicht hast Du ja Lust das Geschriebene (oder ein eigenes Projekt) nachzuvollziehen und meldest Dich hier wenn konkret Probleme auftauchen die Du nicht geloest bekommst.
    Beim reinen Lesen lernt man leider meist sehr wenig nur.


    Kann ich gut verstehen. Ich fände es trotzdem gut, wenn Du die Quellcodes öffentlich machst. Ich denke, dass Projekt wird dadurch nur gewinnen. Ich hab alleine durch das Lesen von Endurions-Quellcode zu seinem Spieleprojekt so viel gelernt. Und Änfänger müssen einfach manchmal Code sehen, um zu begreifen. Da sind schon der Programmstart, das wählen der Banks oder andere Dinge wie Programmstruktur sehr hilfreich.
    Grundsätzlich finde ich es toll, dass Du das Projekt hier gestartet hast.

  • Hi,
    enthusi, leg doch ein Git-Repository an?


    Gruß öp

  • Es gibt ein wenig Neues im Hintergrund :)
    Der Ehrgeiz die Leveldaten aus dem GBA-Rom zu extrahieren hat mich gepackt. Mit etwas Hilfe von MrSid liessen sich auch alle Previews der Levelmaps auffinden.
    Wen es interessiert:
    Tiles aus 8x8 Pixel. Pro Pixel 4 Bit und die Map besteht dann aus 8x8 Tiles.
    Das Ergebnis sieht man im Anhang.
    Das Preview hat also 64x64 Pixel. Die Levelkarten bestehen aus meist (mindestens) 128x128 Tiles. Pro Previewpixel gibt es also 2x2 Chars am C64.
    Einem Grafiker sollte das schon reichen, um alle schoenen Levels im original Massstab umzusetzen, aber ich versuche weiter auch an die echten Daten zu kommen. Dazu reverse ich Teile des GBA-Codes. Das zieht sich vermutlich ein wenig ;-)
    Aber zum Spielen schonmal ein neues Binary
    Was ist neu?
    - man erkennt wieso ich mich nicht um das MSB der Spritekoordinaten geschert habe: im Spiel bleibt der Rotor eigentlich starr und die Map bewegt sich.
    - eine 128x128 Map die ich aus dem PNG-Bild generiert habe.
    Mit passenden Farb-Index-Tabellen:
    Cyan, Schwarz: keine Kollision
    Gruen: Wand
    Lila: Ziel und im Spiel sind es Federn die bei Beruehrung die Drehrichtung umkehren.
    Das geht aktuell mit dem Feuerknopf.
    Man kann ja mal versuchen mit der richtigen Drehung durch das Level zu kommen, aber VORSICHT: ziemlich chaotisch :)
    Die eckige Grafik ist natuerlich nicht wirklich schoen.
    Zwei Dinge sind jetzt langsam wichtig:
    1) die richtige Rotorgroesse:
    um ohne X,Y-Extended Sprites auszukommen, werde ich wohl ein zusaetzliches Sprite fuer den Rotor verwenden demnaechst damit er noch ein wenig groesser wird.


    2) Schlaue Gedanken zur Kollision:
    ein naiver Ansatz der schon drin steckt: bei Kollision einen Schritt zurueck in die Richtung aus der man kommt. Das ginge prima wenn sich das Teil nicht drehen wuerde :)
    SO gibt es allerlei lustige Effekte ;-)
    Ich denke es laesst sich aber machen. Schliesslich weiss man zu jeder Zeit welche Rotorseite kollidierte und in welche Richtung sie sich grade bewegte. Das duerfte ein wenig kniffelig werden, aber loesbar.
    Fuer Vorschlaege bin ich offen. Eine nette Idee kam schon die das ganze noch einfacher machen wuerde - Test erfolgt :)
    Wieder wurde das Scrolling ersteinmal als Placeholder umgesetzt. Also charweise und kein Softscroll der natuerlich am Ende sein sollte.
    UND keinerlei optimiert. Pro Schritt wird der gesamte Screen mit Offset neu gezeichnet. Zum Testen sehr praktisch, fuer das spaetere Spiel aber untauglich.
    Die 128x128 Map ist uebrigens 16KB gross. Das passt recht gut, aber es koennte ratsam sein, dass am C64 in Tiles zu verschachteln. Also eine Map mit 64x64 aus 2x2 Tiles z.B.
    Sehr viele Spiele mit wiederkehrenden Elementen machen soetwas (GianaSisters, Turrican, ...).
    Manche gehen sogar deutlich weiter und arbeiten mit vielen Schachtel-Maps unterschiedlicher Groesse (schoenstes Beispiel duerfte Times of Lore sein).
    So langsam naehert sich das Proof-of-Concept seinem Ende.
    Was fehlt:
    - Rotorgroesse
    - Rotorspeed
    - Das Federelement benutzen
    - brauchbares Kollisionshandling!


    Der letzte Schritt ist der entscheidenste, bisher aber nur super-simple reingepflanzt, also nicht wundern wenn man aus dem Spielfeld katapultiert wird.
    Danach wuerde ich sagen, dass alles Wesentliche funktioniert und man sich daran machen kann, daraus ein Spiel zu machen ;-)
    (und auch erst dann wird der Code optimiert und Speicherbereiche schlau ausgesucht, etc etc)


    Man kann ein Spiel natuerlich auch zunaechst trocken planen und dann die Bestandteile gleich moeglichst in finaler Form programmieren.
    Das bietet sich an, wenn:
    - man viel Zeit hat :)
    - ein eigenes Spiel 'from scratch' macht
    - keine technischen limits/Probleme zu erwarten sind.


    Dadurch gibt es dann lange Phasen ohne dass man weiss ob es ueberhaupt umsetzbar ist. Nicht dass dann AM ENDE doch der Speicher nicht reicht, oder ein Problem sich als gar nicht loesbar erweist.
    Bei fast allem was ich so programmiere, bleibt von den ersten 100+ Zeilen Code am Ende fast nichts uebrig.
    Diese Tests hier haben ihr Screenram z.B. munter bei $0400 und den charset bei $2000. Das ist nicht unbedingt die schlechteste Variante, aber auch nur aus Bequemlichkeit gewaehlt, nicht weil es fuer dieses Konzept 'optimal' ist.


    Gruss,
    Martin /enthusi


    Edit: maptest2.prg implementiert die noch einfacherer Variante einfach auf die letzte Bekannte Rotorposition UND Stellung die keine Kollision verursachten zurueckzusetzen.
    Damit laesst sich beliebig spielen damit es 'realistischer' wird natuerlich - Danke an einen Groepaz

  • Maptest2.prg verlangt bei mir aber schon Vice x64sc (unter dem man eh nur programmieren sollte), mit der x64 Version gibt´s Garbage.


    Ein wenig Schmuzeln muss ich, wenn ich den Thread-Titel "Einfache Spieleentwicklung..." und dann folgendes lese...

    Dazu reverse ich Teile des GBA-Codes. ... Leveldaten aus dem GBA-Rom zu extrahieren

    :rolleyes: