Kirjoittaja: TsaTsaTsaa
Kirjoitettu: 17.05.2007 – 28.10.2012
Tagit: grafiikka, ohjelmointitavat, pelinteko, koodi näytille, peli, vinkki
Teinpä tässä tämmöisen hyppelypelin tutustuessani FreeBASIC:iin, en nyt tiedä onko tätä järkeä edes laittaa tänne, mutta kai tästä joku voi jotakin oppia.
Pelin tarkoitus on kerätä kaikki "kolikot" ja sen jälkeen mennä maaliin (symboli G). Kaiken kukkuraksi tiellä on vaarallisia hirviöitä (symboli @), joita pitää varoa. Ukkelia ohjataan nuolilla, hyppää välilyönnillä ja pelistä pääsee pois ESCillä. Ainoa tapa kuolla on mennä itse päin hirviötä. Liikkuminen vähän ankeaa.
Ja testaamiseen tarvitaan kenttätiedosto "1.lvl", esimerkkitiedosto alla. (Kenttä kannattaa ympäröidä seinillä, muuten käy huonosti.)
Testattu Linuxilla FreeBASICin versiolla 0.16b.
' ASCII-tasoloikka ' """""""""""""""" ' Ensimmäinen FreeBASIC-kokeilu. Saa lyödä. ' Sankari liikkuu nuolista, hyppää välilyönnillä, ESC:llä poistuu ' ' Koodilla saa tehdä mitä lystää ' ' TODO: AMPUMINEN Option Explicit ' ******** FUNKTIOIDEN ESITTELYT **************** Declare Function LataaTaso (ladattava As String) As Integer Declare Sub piirraKehys Declare Sub piirraTaso Declare Sub piirraMerkki (nro As Integer) Declare Sub asetaPiirtoReunat Declare Sub lueNapit Declare Sub liikutaOlioita Declare Sub liikutaSankaria (x As Integer, y As Integer) Declare Sub tulostaTilastot ' Numeroidaan mahdolliset karttaobjektit Const TYHJA = 0 Const PELAAJA = 1 Const ESTE = 2 Const MORKO = 3 Const KOLIKKO = 4 Const MAALI = 5 ' Alustetaan pelitaso maksimikokoonsa (200*100) Dim Shared ptaso(199, 99) As Integer Dim Shared leveys As Integer Dim Shared korkeus As Integer ' Katsomissuunta (ampumissuunta) enum Suunta VASEN = 1 OIKEA End enum ' Otustyyppi (vihollinen/pelaaja) Type olio x As Integer y As Integer z As Suunta End Type ' Vihollisista dynaaminen taulukko Dim Shared viholliset() As olio Dim Shared sankari As olio ' pelaaja Dim Shared kolikkoja As Integer ' kolikkojen lkm kolikkoja = 0 ' aluksi 0 ' Kenttätiedosto Dim taso As String taso = "1.lvl" ' Ladataan pelitaso If LataaTaso(taso) = -1 Then Print "Tasoa ei saatu ladattua." Print "Paina jotakin nappia." While INKEY$ = "": WEND End if ' Piirrettävän tasoalueen reunakoordinaatit ja muutakin Dim Shared alkuX As Integer, alkuY As Integer Dim Shared Kaynnissa As Integer Dim Shared Ilmassa As Integer, hyppyvoima As Integer Const HYPPYTEHO = 5 ' Tätä säätämällä vaihtuu hypyn korkeus Ilmassa = 0 Kaynnissa = 1 ' Näytön asetus SCREEN 13 ' *** Pääsilmukka *** Do tulostaTilastot piirraKehys piirraTaso lueNapit liikutaOlioita Sleep 50 Loop until Kaynnissa = 0 CLS Locate 13, 16 Color 15, 0 Print "Game Over" While INKEY$ = "": Wend SCREEN 0 CLS END ' ********* FUNKTIOIDEN MÄÄRITTELYT ************* ' *** Tasonlatausfunktio Function LataaTaso(ladattava As String) As Integer ' Yritetään avata tiedosto If Open(ladattava For Input As #1) Then LataaTaso = -1 ' Virhepaluuarvo Exit Function End if Dim silmukkaX As Integer, silmukkaY As Integer Dim rivi As String, merkit As String ' merkit-muuttujaan mahdolliset karttamerkit samassa järjestyksessä, kun ne on numeroitu ylhäällä merkit = " X#@oG" ' Tyhjätään pelitaso For silmukkaX = 0 To 199 For silmukkaY = 0 To 99 ptaso(silmukkaX, silmukkaY) = TYHJA Next silmukkaY Next silmukkaX ' Luetaan tiedostosta tason koko Input #1, leveys, korkeus ' Käydään lopputiedosto läpi rivi kerrallaan For silmukkaY = 0 To (korkeus - 1) Line Input #1, rivi ' Tarkistetaan, että rivillä oikea määrä merkkejä If Len(rivi) <> leveys Then LataaTaso = -1 Exit Function End If For silmukkaX = 0 To (leveys - 1) ptaso(silmukkaX, silmukkaY) = InStr(merkit, Mid(rivi, silmukkaX+1, 1)) - 1 ' Onko vihollinen/pelaaja/kolikko If ptaso(silmukkaX, silmukkaY) = MORKO Then ' Kasvatetaan vihollistaulukkoa yhdellä ja asetetaan koordinaatit Redim Preserve viholliset(1 To (Ubound(viholliset, 1) + 1)) viholliset(Ubound(viholliset, 1)).x = silmukkaX viholliset(Ubound(viholliset, 1)).y = silmukkaY viholliset(Ubound(viholliset, 1)).z = VASEN Elseif ptaso(silmukkaX, silmukkaY) = PELAAJA Then sankari.x = silmukkaX sankari.y = silmukkaY sankari.z = VASEN ' Tason piirtoreunat kuntoon asetaPiirtoreunat Elseif ptaso(silmukkaX, silmukkaY) = KOLIKKO Then kolikkoja = kolikkoja + 1 End If Next silmukkaX Next silmukkaY ' Suljetaan tiedosto Close #1 ' Kaikki sujui, palautetaan 0 LataaTaso = 0 End Function ' *** Kentän reunojen piirto Sub piirraKehys Dim i As Integer, j As Integer ' Värin vaihto Color 8, 0 ' Ylä- ja alareunat For i = 3 To 24 Step 21 For j = 2 To 39 Locate i, j Print CHR$(219) Next j Next i ' Sivut For i = 2 To 39 Step 37 For j = 3 To 24 Locate j, i Print CHR$(219) Next j Next i End Sub ' *** Tason piirto Sub piirraTaso Dim i As Integer, j As Integer ' Ruutuun mahtuu tasosta 36x20 kokoinen pala ' joten pitää tehdä pieniä tarkasteluita If leveys > 36 Then For i = 0 To 35 If korkeus > 20 Then For j = 0 To 19 Locate 4+j, 3+i piirraMerkki( ptaso(alkuX+i, alkuY+j) ) Next j Else For j = 0 To korkeus - 1 Locate 4+j, 3+i piirraMerkki( ptaso(alkuX+i, j) ) Next j End If Next i Else For i = 0 To leveys - 1 If korkeus > 20 Then For j = 0 To 19 Locate 4+j, 3+i piirraMerkki( ptaso(i, alkuY+j) ) Next j Else For j = 0 To korkeus - 1 Locate 4+j, 3+i piirraMerkki( ptaso(i, j) ) Next j End If Next i End If End Sub ' *** Apualiohjelma tason piirron selkeyttämiseksi Sub piirraMerkki(nro As Integer) Select Case nro Case TYHJA Print " " Case PELAAJA Color 12, 0 Print "X" Case ESTE Color 6, 0 Print "#" Case MORKO Color 13, 0 Print "@" Case KOLIKKO Color 14, 0 Print "o" Case MAALI Color 11, 0 Print "G" End Select End Sub ' *** Piirtoalueen reunojen asetus Sub asetaPiirtoReunat ' Ensin piirtoalueen vasen raja If leveys > 36 And sankari.x > 17 Then If (leveys - sankari.x) > 18 Then alkuX = sankari.x - 17 Else alkuX = leveys - 36 End If Else alkuX = 0 End If ' Sitten yläraja If korkeus > 20 And sankari.y > 18 Then If (korkeus - sankari.y) > 3 Then alkuY = sankari.y - 17 Else alkuY = korkeus - 20 End If Else alkuY = 0 End If End Sub ' *** Näppiksen käsittely Sub lueNapit Dim uusiX As Integer, uusiY As Integer uusiX = sankari.x: uusiY = sankari.y Select Case INKEY$ Case CHR$(255) + "K" ' Vasen uusiX = sankari.x - 1 Case CHR$(255) + "M" ' Oikea uusiX = sankari.x + 1 Case CHR$(32) ' Välilyönti If Ilmassa = 0 Then hyppyvoima = HYPPYTEHO Ilmassa = 1 End If Case CHR$(27) ' ESC Kaynnissa = 0 End Select liikutaSankaria(uusiX, uusiY) End Sub ' *** Hirviöiden liikuttelu Sub liikutaOlioita ' Käydään hirviötaulukko läpi Dim i As Integer For i = LBound(viholliset,1) To UBound(viholliset,1) ' Mihin suuntaan menossa Select Case viholliset(i).z Case VASEN ' Voiko liikkua vasemmalle (eli onko edessä seinä tai joutuuko ilman päälle) If ptaso(viholliset(i).x-1, viholliset(i).y) = TYHJA And ptaso(viholliset(i).x-1, viholliset(i).y+1) = ESTE Then ptaso(viholliset(i).x, viholliset(i).y) = TYHJA viholliset(i).x = viholliset(i).x - 1 ptaso(viholliset(i).x, viholliset(i).y) = MORKO Else ' Jos ei voi, vaihdetaan suuntaa viholliset(i).z = OIKEA End If Case OIKEA ' Voiko liikkua oikealle (eli onko edessä seinä tai joutuuko ilman päälle) If ptaso(viholliset(i).x+1, viholliset(i).y) = TYHJA And ptaso(viholliset(i).x+1, viholliset(i).y+1) = ESTE Then ptaso(viholliset(i).x, viholliset(i).y) = TYHJA viholliset(i).x = viholliset(i).x + 1 ptaso(viholliset(i).x, viholliset(i).y) = MORKO Else ' Jos ei voi, vaihdetaan suuntaa viholliset(i).z = VASEN End If End Select Next i End Sub ' *** Sankarin liikuttelu tiettyyn kohtaan Sub liikutaSankaria(x As Integer, y As Integer) ' Jos ollaan ilmassa, tehdään temppuja If Ilmassa = 1 Then If hyppyvoima > 0 Then y = y - 1 hyppyvoima = hyppyvoima - 1 Else y = y + 1 End If End If ' Katsotaan, onko tyhjä tai kolikollinen ruutu If ptaso(x, y) = TYHJA Or ptaso(x, y) = KOLIKKO Then ' Kolikko pois If ptaso(x, y) = KOLIKKO Then kolikkoja = kolikkoja - 1 End If ' Vanhasta kohtaa sankari pois ptaso(sankari.x, sankari.y) = TYHJA ' Uudet koordinaatit ja sankari paikoilleen sankari.x = x sankari.y = y ptaso(x, y) = PELAAJA ' Uudet piirtoreunat asetaPiirtoReunat ' Tarkistetaan, ollaanko ilman päällä If ptaso(x, y+1) = TYHJA Then Ilmassa = 1 Else Ilmassa = 0 End If ' Katsotaan, onko ruudussa mörkö Elseif ptaso(x, y) = MORKO Then ' Peli loppuu :( Kaynnissa = 0 ' Onko maali? Elseif ptaso(x, y) = MAALI Then ' Onko kolikot kerätty If kolikkoja = 0 Then Kaynnissa = 0 End If End If End Sub ' *** Tilastojen tulostusta Sub tulostaTilastot Locate 1, 2: CLS Color 15, 0 Print "Kolikkoja:"; Print kolikkoja End Sub
kenttätiedosto 1.lvl
40 30 ######################################## # # # #G # o o o # ###### ######### #### #### # # # # @ # # ############# #### ## o # # ## ### # # ### #### # # o # # #### ##### # ####### ####### ##### ###### # # # # o @ # ####### ################ ########## # o # # # @ o # # ################# # ############# # # # o # # # o # ################### # ####### # # o # # # @ # # o ############################## ##### #o # #o # # # # @ # # ####### ############## # # # # # o # X # ########################################
Mitenköhän tuon liikkumisen saisi vähän sujuvammaksi? Nimittäin muuten koossa on varsin hyvä pelin runko.
Mä koitin kääntää windows versiolla niin jos muutti hypyn tehoa seiskaan niin kääntäjä valitti jotain. Oli kyllä ihan hyvä ja se liikkuminen tosiaan toimii huonosti. Liian nopea jopa tällä 366mhz koneella.
Kääntyisköhän tuo KuikPeisikillä?
Ei todellakaan.
Kääntyisköhän toi GCC:llä?!?
Ei, koska GCC ei sisällä FreeBASIC-kääntäjää.
Työkoneella ei ole FB kääntäjää mutta mitä sorsaa tässä katselin niin...
Sleep 50 voisi vaihtaa Sleep 100, 1 niin peli ei olisi niin nopea.
, 1 perässä muuttaa niin että peli odottaa aina sen 100ms välittämättä siitä painaako pelaaja nappulaa vai ei.
Normaalistihan Sleep odottaa annetun ajan tai kunnes nappulaa painetaan.
INKEY$ lukeminen suoraan voi joskus kököttää joten...
Sub lueNapit Dim uusiX As Integer, uusiY As Integer Dim Namiska AS String uusiX = sankari.x: uusiY = sankari.y Namiska = INKEY$ Select Case Namiska
Lisäksi, jos näytöllä oleva taso ei vaihdu niin kannattaisi piirtää uudelleen vain ne asiat jotka liikkuvat. Eli normaalisti vain sankari ja möröt.
Pitääpä kopioida tuo usb:lle kun kotona vieläkään netti auki ja kokeilla. Ihan kivalta pikku peliltä vaikuttaa.
Todella uskomaton homma!
Offtopic-kysymys: mikä on FreeBASIC ?
öö?? miten tuosta oiken tehdään pelattava? voisko joku lattaa neuvot?
@Are0100: Lataa fb kääntäjä osoitteesta www.freebasic.net
Tallenna ylläolevat filut ja kirjoita fbc filenimi.bas ja käynnistä.
oikein mukava, vaikka ei tule freebasicia käytettyä pahemmin. :)
mä voisin muokata sitä mun qb kenttäeditoria niin että toimis tuolla.
Käänsin tuon pelin qbeelle.
Hienolta vaikuttaa mutta mihin toi kenttä olis tarkotus laittaa?
Ainiin Option Explicit aiheuttaa errorin.