Gå til innhold

Anbefalte innlegg

Dette prosjektet går i korte trekk ut på å lage en versjon av Atari Lynx/DOS/Windows 3.1-klassikeren Chip's Challenge til NES (Nintendo Entertainment System.) Spillet skal basere seg på Windows-versjonen når det gjelder grafikk, men med animasjoner og glattere bevegelse.

 

Hvis du har noe å si kan du poste her.

 

Spillet programmeres i asssemblyspråk for 6502-prosessoren i NES. Grafikken tegnes i programmet Tilemolester. Kildekoden er nå lagt ut her

 

Foreløpig fungerer følgende:

  • Lasting og dekoding av levels
  • Scrolling og et slags "kamera" på Chip slik at han alltid er i sentrum av skjermbildet. Han beveger seg kun på skjermen når han befinner seg langs kantene.
  • Sprite/objekt-håndtering (tegning, flytting, kollisjon)
  • Et system for interaksjon mellom sprite-objekter og bakgrunnsobjekter
  • Et simpelt system for å plukke opp objekter (nøkler, chipper, items)

Slik ser det ut:

 

chip.png

 

Det jeg har fått til frem til nå kan du laste ned her.

 

Mye gjenstår:

  • Et dynamisk objektsystem hvor objekter lett kan fjernes og legges til.
  • Et grundig og mer dynamisk kollisjonssystem. Ser for meg et signalbasert opplegg mellom objektene
  • Få til en statusbar (dette er vanskeligere enn det høres ut...)
  • Animasjoner
  • Monstrene
  • Et system for 'hybride' objekter som kan opptre både i form av sprites (når de beveger seg) og bakgrunnsobjekter (når de er i ro). Dette er nødvendig for å bruke så få av de 64 hardware-spritene som mulig.
  • Linker mellom objekter, f.eks. teleporter, mellom knapper og tanks, etc.
  • Et map-format som er kompatibelt med Windows-versjonens map-format slik at nye brett enkelt kan legges inn.
  • LYD

Diverse detaljer som kan være av interesse: :p

 

Brett-format

Et brett / level i Chip's Challenge består av et rutenett på 32 x 32 blokker. Disse blokkene er den grunnleggende størrelsen i spillet. Et brett består dermed av 1024 bytes. Dette er dog ganske mye plass for et NES-spill. Derfor har jeg implementert en simpel RLE-dekoder som tolker en byte-triplett på formen $FF,X,Y som en repetisjon av elementet X Y ganger. Så f.eks. $FF,2,6 blir dekodet til 2,2,2,2,2,2 i runtime når brettet lastes. Mer avansert komprimering har jeg ikke sett på ennå.

 

Objekter

Det er i grunn tre "typer" objekter: bakgrunnsobjekter (som egentlig ikke er objekter), sprite-objekter og hybrider. Førstnevnte er stort sett ting som ikke beveger seg og som ikke trenger ekstra farger utover paletten til blokken de befinner seg på. Dette er f.eks. chip-ene som Chip kan plukke opp.

 

Sprite-objektene er alle objektene som beveger seg eller objekter som trenger flere farger enn de tre predefinerte fargene i en av de 4 velgbare palettene. Nøklene og diverse items som skøytene og svømmeføttene er sprite-objekter. Det vil også monstrene være når de en gang blir laget...

 

Hybridobjekter er ennå ikke implementert, men disse vil være objekter som beveger seg, men som ikke trenger ekstra farger. Et eksempel på dette vil være de skyvbare blokkene. Disse vil være bakgrunnsobjekter når de er i ro, og akkurat når de skubbes på av Chip, vil de fjernes og erstattes av et sprite-objekt som beveger seg til neste posisjon for så å bli slettet og erstattes med en ny bakgrunnsblokk på den nye posisjonen. Dette er for å spare så mange sprites som mulig. Ett objekt tar opp 4 av de 64 spritene, så det sier seg selv at man må være sparsommelig.

 

Sprite-objektene er lagret i en 256 bytes datastruktur i RAM med 8 bytes per objekt: x-posisjon, y-posisjon, type, finposisjon, fart, tidligere fart, og to ubrukte bytes. x- og y-posisjonen til objektet er tall fra 0 til 31 som angir blokknummer langs aksene. I og med at blokkene er de minste elementene i spillet, skjer all forflytning egentlig blokk for blokk. Men for å glattere forflytninger, har hvert objekt også en finposisjonering som angir antall piksler det skal forflyttes i tillegg til posisjonen. Dette er en 4-bits verdi. Den femte biten angir hvilken retning finposisjonen gjelder. Dette vil altså si at et objekt aldri kan befinne seg diagonalt mellom blokker. Det vil alltid være parallellt med enten en rad eller kolonne. Objektets fart fungerer på nesten samme måte. Her er de fire lave bitene en to-komplementsverdi, slik at den fjerde biten angir positiv eller negativ fart. Den femte biten angir retning.

 

Hver frame går en loop gjennom objektlisten. Alle objekter som befinner seg innenfor det synlige området blir kopiert over i SPR-RAM (sprite-minnet til NES.)

 

Objektinteraksjon

Objektene reagerer på forskjellige typer "underlag". Et objekt vil eksempelvis beholde uforandret fart på is, akselerere på et kraftfelt, osv. Dette blir håndtert ved at hvert bakgrunnselementnummer er indeks i en tabell hvor det ligger addresser til funksjoner som skal kalles når et objekt befinner seg oppå elementet. Disse funksjonene har som oppgave å oppdatere objektets tilstand (f.eks. fart).

Endret av Jaffe
  • Liker 2
Lenke til kommentar
  • 3 uker senere...
Videoannonse
Annonse

En liten oppdatering her. Egentlig ganske stor; har restrukturert store deler av objektkoden og map-formatet. Nå er map-formatet i stor grad kompatibelt med Windows-versjonens. Når jeg gidder skal jeg skrive et program som kan hente ut baner fra CHIPS.DAT og konvertere dem til et kompatibelt format.

 

Av mer synlige forandringer er det nå støtte for flyttbare blokker som kan skubbes rundt. Disse reagerer på underlaget akkurat som andre objekter. Dvs. at man kan skubbe de ut på isen og så videre. Når de er i ro blir de omgjort til bakgrunns-tiles slik at de ikke stjeler verdifulle sprites.

 

Last ned en testkompilering her. Merk at det er en haug med feil. Bl.a. oppdateres ikke fargen til blokker som oppdateres mens spillet kjører. Jeg jobber med en løsning på dette. Jeg skal legge ut kildekoden til nyeste versjon når jeg har ryddet en del i den.

  • Liker 2
Lenke til kommentar
  • 2 uker senere...

Ny oppdatering igjen nå. Fargeproblemet er fikset, og blokkene vil nå bare flytte seg dersom de ikke blir blokkert i den retningen de skyves. Objekter som beveger seg på is og treffer et solid objekt vil snu seg og gli i motsatt retning.

 

Testkompilering finner du her.

  • Liker 2
Lenke til kommentar
  • 10 måneder senere...

Har tatt opp dette prosjektet igjen. Ser dessverre ut som jeg bare får tid til å jobbe med det i feriene. Nå i juleferien har jeg fått jobbet litt videre på det. Nå fungerer det f.eks. å plukke opp nøkler og løse opp dører med dem. Man kan også fullføre brettene ved å samle alle chipene (når man går på exit-blokken lastes neste brett.) Objekter som beveger seg vil også forandre utseende etter hvilken retning de beveger seg i.

 

Jeg føler nå at selve motoren i spillet begynner å ta skikkelig form. Det var forbausende lett å implementere f.eks. det froskelignende monsteret. Det er ikke helt oppegående ennå, men det er i grunn bare latskap som hindrer meg fra å kode 'AI'-en 100% ferdig.

 

Dere kan laste ned en demo med fire brett her.

 

Noen screenshots:

post-40145-0-37122600-1293732274_thumb.png

post-40145-0-29711800-1293732280_thumb.png

post-40145-0-33485200-1293732291_thumb.png

post-40145-0-31674600-1293732298_thumb.png

  • Liker 3
Lenke til kommentar
  • 3 måneder senere...

Kommer med en liten oppdatering igjen. Det er ikke så mange nye features denne gangen, men det har skjedd en del under overflaten.

 

De mest synlige oppdateringen er kanskje at alle monstrene er implementert, og at alle tanksene nå fungerer. Tråkker man på en blå knapp så bytter de retning og beveger seg langs den retningen helt til de når en ny hindring.

 

Som sagt er alle monstrene implementert. De fleste, utenom "froskmonsteret" (som ble omtalt i forrige post) har veldig enkle regler for hvordan de skal oppføre seg. Disse er såpass like at alle behandles som et objekt av samme type (Generic_Monster.) Alle fungerer ved at de har en oppsatt prioritet for hvordan de skal oppføre seg. Det eneste som skiller eksempelvis "billene" fra "gliderene" er i hvilken retning de prioriterer å bevege seg. Når en bille møter på en hindring vil den f.eks. først prøve å gå til venstre, hvis det ikke går prøver den å gå rett frem, så mot høyre og så videre.

 

Posjektet er nå portet til assembleren CA65 i stedet for NESASM. NESASM har vist seg å være ganske mangelfull. Jeg oppdaget f.eks. tilfeldigvis at den assembler zero page-instruksjoner til vanlige absolutt-instruksjoner. Det tar opp unødvendig plass, og prosessoren bruker unødvendig lang tid på å kjøre de instruksjonene (hele poenget med zero page er å unngå dette.) CA65 har i tillegg en del nyttige funksjoner og makroer som kan være til god hjelp.

 

Jeg har også satt i gang å rydde i koden. Det har vært en del gammelt rusk og rask liggende igjen i koden som nå er ryddet opp. Har også satt i gang den relativt lange prosessen det er å kommentere koden... For interesserte er kildekoden og nyeste versjon så langt å finne her: http://home.no/johan-af/chip. Koden må som sagt assembles med CA65 (og linkes med LD65.)

 

Siden forrige post har jeg testet ut en del teknikker for det som blir det neste å implementere: Bundede knapper, toggle-blokker og klonemaskiner. Knapper er i og for seg ikke noe problem, men problemet er at brune knapper skal kobles til en tilhørende felle. Det må i såfall lages et lurt system for å få til det. Toggle-blokker er testet én og én, men problemet med disse er at hvis det er for mange slike i et brett, vil det bli problemer å få tid til å oppdatere skjermbildet siden alle oppdateres når man tråkker på en grønn knapp. Slik det er nå støtter heller ikke grafikkmotoren å oppdatere mer enn én blokk per frame. Jeg skal utarbeide et nytt system for dette, men det er ganske utfordrende, for grafikkmotoren må også oppdatere bakgrunnsdata etter hvert som spillet scroller. Jeg ser for meg et slags køsystem eller noe slikt, men det kan heller ikke være for avansert, for man har ganske begrenset med CPU-tid å gjøre grafikkoppdateringer på.

  • Liker 1
Lenke til kommentar

Jeg har i løpet av helgen fått skrevet en level-editor til spillet. Da slipper jeg å kode brettene for hånd og RLE-encode dem i hodet ... :p

 

mapedit.png

 

(Editoren er skrevet i Common Lisp og kildekode finnes her for interesserte: http://home.no/johan-af/chip/mapeditor.)

 

Nå nærmer påskeferien seg, og da skal jeg nok få programmert en del videre på selve spillet!

Endret av Jaffe
  • Liker 3
Lenke til kommentar
  • 3 uker senere...

Ok, så nå er påskeferien over, og jeg fikk jobbet en god del med spillet. Følgende ble implementert:

 

- Blokker som sperrer deg fra kun visse retninger

- Feller (traps) med mapping til tilhørende grå knapper

- Grønne "toggle blocks" og tilhørende grønne knapper

- Teleporter

- Tyver som tar alle skoene fra Chip

 

Det er en del bugs enda, men disse skal jeg begynne å ordne på ved neste anledning. En spillbar demo er lagt ut her: http://home.no/johan-af/chip/chip.nes. Denne inneholder nå de 8 første brettene i spillet. I samme katalog ligger også kildekoden. Noen nye skjermbilder viser henholdsvis level 5 (med klonemaskin og feller), 6 (med blå vegger som enten omgjøres til vegg eller gulv når de berøres av Chip) og 7 (med teleporter og tyver) som nå er fullt spillbare.

post-40145-0-75555300-1304262925_thumb.png

post-40145-0-14529800-1304262934_thumb.png

post-40145-0-55402100-1304262941_thumb.png

Endret av Jaffe
  • Liker 1
Lenke til kommentar
  • 2 år senere...

Takker :). Har dessverre gjort lite på det siden sist. Fikset noen bugs i fjor en gang, men ellers ikke mye. Det eneste jeg har gjort som er litt relatert er å begynne på en port av mapeditoren, fra Common Lisp til Clojure. Men det er egentlig mest for å ha et prosjekt å lære Clojure med. :p

 

Grunnen til at jeg har gjort lite på selve spillet er først og fremst at jeg ikke har hatt tid pga. studier osv., men også fordi jeg rett og slett har mistet litt av motivasjonen. Grunnene til det er først og fremst at spillet aldri vil kunne oppnå samme funksjonalitet som originalversjonen, rett og slett fordi NES-en er for treg (baner som denne har f.eks. alt for mange bevegelige objekter). I tillegg er det noen stygge bugs i den delen av koden som oppdaterer bakgrunnsblokkene når man scroller som er veldig vanskelige å fikse. Det vil nesten garantert kreve å redesigne store deler av koden (burde ha vært mye flinkere til å dele ting opp i moduler).

 

Det jeg har tenkt litt på er å kanskje droppe å prøve å implementere hele (så mye som mulig av) Chip's Challenge, og i stedet gjøre dette til et eget spill der jeg kan introdusere nye fiender, blokker, endre en del på gameplayet osv. Har også tenkt litt på å eksperimentere med å skrive noe av koden i C i stedet for assembly for å se om det kan gi en nettogevinst (lettere å uttrykke seg i C, og kompilatoren kan gjøre en del optimaliseringer jeg kanskje ikke hadde tenkt på selv).

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...