Kirjautuminen

Haku

Tehtävät

Opasarkisto: Merkkigrafiikkapelien ohjelmointi QBasicilla: Osa 3 - Hirviöiden luominen

  1. Osa 1 - Pelimoottorin alkeet
  2. Osa 2 - Alkeellinen pelimaailma
  3. Osa 3 - Hirviöiden luominen

Kirjoittaja: hunajavohveli. Vuosi: 2005.

Hirviöiden luominen taulukkoon

Kahdessa edellisessä osassa loimme alkeellisen pelimaailman, jossa pelaaja pystyy liikkumaan pääsemättä esteiden läpi. Yksinään kuljeskelu käy kuitenkin helposti tylsäksi, joten on aika luoda pelaajalle seuraa. Siirrymme siis koodamaan toisia itsenäisesti liikkuvia otuksia (hirviöitä). Aloitamme luomalla tietotyypin, jollaiseen hirviöiden tiedot tallennetaan. Jos TYPE-rakenne ei ole vielä tuttu, se kannattaa ensin opetella. En aio selittää sen käyttöä tässä oppaassa.

TYPE Monster
  x AS INTEGER
  y AS INTEGER
END TYPE

TYPE-rakenteet kannattaa kirjoittaa heti DECLARE-rivien jälkeen ennen DIM-lauseita. Tällainen alustava tietotyyppi sisältää kaksi elementtiä, x:n ja y:n eli otuksen koordinaatit. Muita ominaisuuksia ei tarvita vielä, ja ne lisätään vasta myöhemmin.

DIM SHARED Monster(1 TO 10) AS Monster, MonsterAmount AS INTEGER

Seuraavaksi luomme taulukon, jonka tyypiksi määritämme äsken luomamme rakenteen (taulukolla ja rakenteella saa olla sama nimi). Luomme myös muuttujan MonsterAmount. Tämä muuttuja sisältää tiedon siitä, kuinka monta hirviötä kartalla on. Muuttuja kasvaa sitä mukaa, kun uusia hirviöitä tulee, ja vähenee, kun niitä kuolee. Minulla on usein tapana lyhentää tämä muuttuja MA:ksi tiiviimmän koodin vuoksi. Tee itse, miten parhaaksi katsot. Oppaassa käytän joka tapauksessa pitempää nimeä. Taulukko ja muuttuja määritellään jaetuiksi kaikkien aliohjelmien kesken. Kokeillaanpa nyt lisätä yksi hirviö:

MonsterAmount = 1
Monster(1).x = 10
Monster(1).y = 5

Voit kirjoittaa koodin taulukon määrittelyn jälkeen. Hirviö on nyt teoriassa luotu. Mitään ei tietenkään vielä näy, joten siirrymme koodamaan piirtorutiinin.

Hirviöiden piirtäminen

Hirviöiden piirtäminen koodataan heti ukon piirtämisen perään (juuri ennen näppäimen lukemista).

FOR i = 1 TO MonsterAmount
  LOCATE Monster(i).y, Monster(i).x
  PRINT "&";
NEXT i

Tarkastellaanpa, mitä koodi tekee. Silmukassa käydään läpi luvut väliltä 1 - MonsterAmount. Sen sisällä on kaksi tutunnäköistä riviä. Noudatamme samaa periaatetta kuin ukonkin piirtämisessä. Nyt vain vaihdamme ukon koordinaatit hirviön koordinaatteihin ja @-merkin sijaan piirrämme &-merkin. Nämä neljä riviä riittävät piirtämään jokaisen hirviön. Kuten huomaat, muuttuja i on Monster-taulukon indeksinä, joten sen arvo määrää, mikä hirviö piirretään. Ja koska i kasvaa yhdellä joka kerta, kun silmukka aloittaa uuden kierroksen, joka kerralla piirretään eri hirviö. Tässä vaiheessa hirviöitä on tosin vasta yksi, joten silmukka loppuu heti, kun se on piirretty.

Indeksimuuttuja i määritellään koodin alussa:

DIM i AS INTEGER

Hirvöiden kumittaminen tehdään samanlaisella silmukalla kuin piirtäminenkin:

FOR i = 1 TO MonsterAmount
  LOCATE Monster(i).y, Monster(i).x
  PRINT " ";
NEXT i

Eli koodi on muuten sama kuin piirrossa, mutta &-merkin tilalle laitetaan välilyönti. Hirviöiden kumitus kirjoitetaan aivan DO-silmukan loppuun eli heti ukon CanMove-tarkistuksen jälkeen.

Hirviöiden liikuttaminen

Etenemme edelleen samassa järjestyksessä kuin ukon kanssa. Liikuttaminen tehdään siis heti kumittamisen jälkeen. Näppäimen lukeminen jää tietysti väliin, ja se korvataan tekoälyllä, koska tietokone liikuttaa hirviöitä itse. Liikkuminen ja yleensäkin hirviöiden koko toiminta jaetaan kahteen osaan. Ensinnäkin tekoälyyn, joka järkeilee, mitä hirviön kannattaa tehdä, ja toiseksi tarkistuksiin, jotka suorittavat tekoälyn antamat ohjeet, mikäli ne ovat sopivia. Tekoäly siis antaa esimerkiksi käskyn liikkua oikealle. Sitten tarkistetaan, onko siinä suunnassa jokin este, ja jos ei ole, niin liikutaan.

FOR i = 1 TO MonsterAmount
  LOCATE Monster(i).y, Monster(i).x
  PRINT " ";

  ux = Monster(i).x + 1      ' Tekoäly
  uy = Monster(i).y + 1

  IF CanMove(ux, uy) THEN    ' Tarkistukset
    Monster(i).x = ux
    Monster(i).y = uy
  END IF
NEXT i

Kumittaminen ja liikuttaminen sopivat hyvin samaan silmukkaan, joten lisäämme liikutuskoodin siihen. Ensimmäiset kaksi riviä kumituksen jälkeen ovat alkeellinen tekoäly, joka komentaa hirviötä liikkumaan aina viistosti alas ja oikealle. Voimme käyttää muuttujia ux ja uy myös hirviöiden tapauksessa, sillä ne ovat väliaikaisia muuttujia, joilla ei tarkistuksen jälkeen ole mitään merkitystä. Seuraavat neljä riviä tarkistavat uudet koordinaatit mahdollisen esteen varalta, ja liikuttavat hirviön siihen, jos estettä ei löydy. Nyt voit kokeilla ajaa ohjelman. Hirviö ilmestyy kartalle ja liikkuu, kunnes törmää mahdolliseen esteeseen.

Tekoäly ja törmäys pelaajaan

Yritetäänpä seuraavaksi saada hirviö seuraamaan pelaajaa. Tätä varten meidän täytyy määritää, missä suunnassa pelaaja on hirviöön nähden. Oletetaanpa, että pelaaja on koordinaateissa (15, 4) ja hirviö (10, 10). Tällöin voidaan laskea oikea suunta vähentämällä pelaajan koordinaateista hirviön koordinaatit:

X-koordinaatit: 15 - 10 = 5
Y-koordinaatit: 4 - 10 = -6

X-koordinaatti on positiivinen eli hirviötä tulee liikuttaa oikealle. Y taas negatiivinen, joten hirviötä pitää liikuttaa myös ylöspäin. Asiaa havainnollistava kuva:

Päinvastoin taas, jos x-koordinaatti olisi negatiivinen, pitäisi hirviötä liikuttaa vasemmalle. Ja jos y posiitivinen, niin alaspäin. Liikutuksen voisi siis tehdä näin:

IF x - Monster(i).x > 0 THEN ux = Monster(i).x + 1
IF x - Monster(i).x < 0 THEN ux = Monster(i).x - 1
IF y - Monster(i).y > 0 THEN uy = Monster(i).y + 1
IF y - Monster(i).y < 0 THEN uy = Monster(i).y - 1

Mutta on olemassa kätevämpikin keino, jonka käytössä ei tarvita ehtolauseita:

ux = Monster(i).x + SGN(x - Monster(i).x)
uy = Monster(i).y + SGN(y - Monster(i).y)

SGN-funktio palauttaa lukuarvon etumerkin. Jos luku on positiivinen, funktio palauttaa 1, jos negatiivinen, funktio palauttaa -1 ja nolla, jos luku on nolla. Esimerkkilukuarvot 15 - 10 = 5 ja 4 - 10 = -6 palauttavat siis 1 ja -1, jotka lisätään hirviön alkuperäisiin koordinaatteihin. Tällöin hirviö liikkuu viistosti ylös ja oikealle. Oikea suunta määräytyy kaikissa muissakin tilanteissa. Voit nyt kokeilla ajaa ohjelman, jolloin hirviö seuraa pelaajaa. Hirviö pääsee kuitenkin liikkumaan samaan kohtaan pelaajan kanssa. Meidän on siis kehitettävä hirviön törmäystarkistusta.

FUNCTION Reserved (px AS INTEGER, py AS INTEGER)
  Reserved = 0                     ' Funktio palauttaa nollan, jos tarkistukset eivät havaitse estettä

  IF px = x AND py = y THEN       ' Jos pelaaja on ruudussa,
    Reserved = -1                  ' ruutu on varattu
    EXIT FUNCTION
  END IF

END FUNCTION

Luodaan Reserved-niminen funktio. Funktion sisälle tehdään ehtolause, jossa verrataan parametreiksi annettuja koordinaatteja pelaajan koordinaatteihin. Jos ne täsmäävät, funktio palauttaa -1 (tosi). Jotta pelaajan koordinaatteja voitaisiin verrata funktion sisällä, ne on muutettava jaetuiksi. Lisäämme pelaajan koordinaattien määrittelyyn siis SHAREDin.

DIM SHARED x AS INTEGER, y AS INTEGER

Olemme aikaisemmin käyttäneet muuttujia x ja y myös CanMove-funktiossa. Nyt kun pelaajan koordinaatit muutetaan jaetuiksi, ei kannata enää käyttää CanMovessa saman nimisiä parametrejä. Muutetaan siis kaikki CanMove-funktion muuttujat x ja y muuttujiksi px ja py. Muista vaihtaa muuttujat myös funktion DECLARE-rivillä.

Nyt kun meillä on Reserved-funktio, lisäämme sen hirviön tarkistuksiin:

IF CanMove(ux, uy) AND NOT Reserved(ux, uy) THEN    ' Tarkistukset
  Monster(i).x = ux
  Monster(i).y = uy
END IF

Jos CanMove palauttaa -1 (eli ruudussa ei ole estettä) ja jos Reserved EI palauta -1 (eli ruutu EI ole varattu), niin silloin ruutuun voidaan liikkua. Nyt hirviö ei siis enää voi liikkua samaan ruutuun pelaajan kanssa. Pelaaja kylläkin voi vielä liikkua hirviön päälle, mikä korjataan hetken kuluttua.

Useampi hirviö

Yksi hirviö toimii jo ihan mukavasti. Nytpä kokeillaan, miten onnistuu useamman hirviön lisääminen yhtä aikaa. Toinen hirviö luodaan, kuten ensimmäinenkin. Samalla kasvatetaan MonsterAmount-muuttujaa.

MonsterAmount = 2
Monster(1).x = 10
Monster(1).y = 5
Monster(2).x = 60    ' Uuden hirviön
Monster(2).y = 20    ' tiedot

Kokeilepa nyt ajaa ohjelma. Jos kaikki toimii, kuten pitää, kumpikaan hirviöistä ei pääse pelaajan läpi. Saatat huomata, että hirviöt pääsevät kuitenkin samoihin ruutuihin toistensa kanssa. Muokkaamme siis Reserved-funktiota niin, että se ottaa huomioon myös ruudussa mahdollisesti olevat hirviöt.

FUNCTION Reserved (px AS INTEGER, py AS INTEGER)
  Reserved = 0       ' Funktio palauttaa nollan, jos tarkistukset eivät havaitse estettä

  DIM i AS INTEGER   ' Indeksimuuttuja

  IF px = x AND py = y THEN                          ' Jos pelaaja on ruudussa,
    Reserved = -1                                     ' ruutu on varattu
    EXIT FUNCTION
  END IF

  FOR i = 1 TO MonsterAmount                          ' Verrataan jokaisen hirviön koordinaatteja
    IF px = Monster(i).x AND py = Monster(i).y THEN   ' Jos ruudussa on hirviö
      Reserved = -1                                   ' ruutu on varattu
      EXIT FUNCTION
    END IF
  NEXT i

END FUNCTION

Nyt Reserved-funktiossa käydään silmukalla läpi jokainen hirviö ja verrataan niiden koordinaatteja parametreiksi annettuihin koordinaatteihin. Jos ne täsmäävät, ruutu on varattu, ja Reserved palauttaa -1. Enää hirviöt eivät pääse samoihin ruutuihin toistensa kanssa, mutta pelaaja voi yhä liikkua niiden päälle. Tästä selvitään yksinkertaisesti tekemällä myös pelaajalle Reserved-tarkistus. Lisäämme sen samalle riville aiemmin luodun CanMove-tarkistuksen kanssa:

IF CanMove(ux, uy) AND NOT Reserved(ux, uy) THEN
  x = ux
  y = uy
END IF

Nyt törmäystarkistukset ovat täydellisiä, eivätkä pelaaja ja hirviöt pääse enää samoihin ruutuihin.

Erilaisia hirviöitä

Nyt kun hirviöiden perusasiat on koodattu, voimme luoda erilaisia hirviöitä. Ensin luomme tietorakenteeseen uuden elementin:

TYPE Monster
  Race AS INTEGER       ' Uusi elementti
  x AS INTEGER
  y AS INTEGER
END TYPE

Race (eli laji/rotu) määrittelee, minkälaisesta hirviöstä on kyse. Luomme myös toisen tietorakenteen, johon tallennetaan lajien ominaisuudet.

TYPE Race
  Char AS STRING * 1      ' Merkki
  Col AS INTEGER          ' Väri
END TYPE

Tämä tietorakenne pitää sisällään tiedot ominaisuuksia, jotka ovat yhteisiä kaikille samaa lajia edustaville hirviöille (esim. voima, kesto, nopeus). Tässä vaiheessa tarvitsemme vain kahta elementtiä: Char sisältää yhden merkin pituisen merkkijonon, jonka arvo kertoo, minkälaisena merkkinä lajin hirviöt näkyvät kartalla. Col-elementissä taas on muistissa merkin väri. Luodaan myös taulukko, jolle Race-tietotyyppi määritetään:

DIM SHARED Race(1 TO 10) AS Race

Nyt voimme luoda taulukkoon tietoja erilaisille lajeille. Tehdäänpä esim. näin:

' Lajien määrittely
Race(1).Char = "b"
Race(1).Col = 6
Race(2).Char = "D"
Race(2).Col = 2

' Hirviöiden määrittely
MonsterAmount = 2
Monster(1).Race = 1    ' 1. hirviön laji
Monster(1).x = 10
Monster(1).y = 5
Monster(2).Race = 2    ' 2. hirviön laji
Monster(2).x = 60
Monster(2).y = 20

Lajin numero yksi merkiksi määritetään ruskea b-kirjain ja lajille kaksi vihreä D. Leikitään vaikka, että nämä tarkoittavat lepakkoa ja lohikäärmettä. Nämä rivit tulevat juuri ennen aiemmin koodattua hirviöiden määrittelyä, johon lisäämme nyt Race-ominaisuuden. Ensimmäisen hirviön lajiksi pistetään 1 ja toisen lajiksi 2. Nyt hirviöillä on teoriassa omat lajinsa. Mitään ei tietysti vielä näy, joten muokataanpa piirtokoodia.

FOR i = 1 TO MonsterAmount
  LOCATE Monster(i).y, Monster(i).x
  COLOR Race(1).Col
  PRINT Race(1).Char;
NEXT i

Tämä voi olla aluksi vaikea ymmärtää, joten lue seuraava läpi huolella. Aiemmasta piirtokoodista on nyt poistettu rivi, joka piirsi &-merkin. Tilalle on tullut kaksi uutta riviä. Ensimmäinen riveistä määrää tekstin värin ja toinen tulostaa merkin. Arvoina ovat nyt Race(1).Col ja Race(1).Char. Tämä tarkoittaa sitä, että jokaiselle hirviölle tulostetaan ensimmäisen lajin merkki ensimmäisen lajin värillä. Eli jokaisen hirviön tilalle tulostuu ruskea b. Jotta saisimme tulostettua jokaiselle hirviölle sen omaa lajia vastaavan merkin, meidän täytyy antaa Race-taulukolle indeksiksi ykkösen sijaan hirviön lajia vastaava numero. Laji on tallennettuna Monster-taulukon Race-elemettiin, joten ykkösen tilalle laitetaan Monster(i).Race.

FOR i = 1 TO MonsterAmount
  LOCATE Monster(i).y, Monster(i).x
  COLOR Race(Monster(i).Race).Col          ' Vaihdetaan väri
  PRINT Race(Monster(i).Race).Char;        ' Tulostetaan merkki
NEXT i

Nyt koodissa on kaksi taulukkoa sisäkkäin. Ensin annetaan sisimmäiselle (Monster) indeksiksi i, jolloin se palauttaa hirviön lajin. Tämän jälkeen laji annetaan indeksiksi Race-taulukkolle, jolloin se palauttaa kyseisen lajin värin ja merkin. Kokeile ajaa ohjelmaa. Ruudulla pitäisi nyt liikkua kaksi erilaista hirviötä. Jottei pelaajan väri muuttuisi COLOR-käskyn vuoksi, se täytyy palauttaa takaisin harmaaksi. Tai jos haluat, voit saman tien määrittää pelaajallekin jonkin eri värin.

LOCATE y, x
COLOR 7         ' Lisätään värinpalautus
PRINT "@";

Mitä jatkossa?

Tässä olivat tämän oppaan asiat. Seuraavaan vaiheeseen kuuluu niin paljon asioita, että jätän ne suosista seuraavaan oppaaseen. Mutta nytpä on kuitenkin valmiina pohja hirviöiden ohjelmointiin. Tästä eteenpäin jatkamme luomalla pelaajalle ja hirviöille uusia ominaisuuksia ja mahdollistamalla niiden välisen taistelun. Tulemme kehittelemään myös hirviöiden tekoälyä.

Jottei aika tule heti pitkäksi, voisit kokeilla ominpäin ainakin seuraavia asioita:

  1. Luo lisää hirviölajeja ja kokeile laittaa niitä ilmestymään kartalle säännöllisin väliajoin, kunnes koko kartta on täynnä.
  2. Yritä saada aikaan esteitä, joista hirviöt pääsevät läpi, mutta pelaaja ei, ja päinvastoin. Voit kerrata esteiden luomista edellisestä oppaasta.
  3. Pistä osa hirviöistä liikkumaan pelaajaa päin ja osa satunnaisesti minne sattuu.

Jos teet lisäyksiä, muista kuitenkin aina säilyttää alkuperäinen koodi, koska seuraavassa osassa jatketaan siitä, mihin jäätiin ilman näitä lisätehtäviä.

Valmis koodi ja käännetty ohjelma ovat saatavilla tästä.


Kommentit

tgunner [29.05.2005 09:20:14]

Lainaa #

Ihan kiinnostava tyyli tuo TYPE, täytynee käyttää sitä.
Ja taas! \o/ Ensimmäinen kommentti.

Wlan [29.05.2005 11:27:46]

Lainaa #

Hyvää työtä :-)

petrinm [29.05.2005 18:34:48]

Lainaa #

Korjaa Reserved funtion teksti

IF px = x AND py = py THEN

tälläiseksi

IF px = x AND py = y THEN

Koodi esimerkissäsi(se tiedosto) se on oikein, mutta tossa sivulla on virhe

hunajavohveli [29.05.2005 19:10:38]

Lainaa #

Korjattu on.

herkko [02.06.2005 21:43:09]

Lainaa #

Wau! En vielä ehtinyt koodaamaan, mutta oppaan sain luettua ja vaikutti hyvältä!

Tumpelo [07.06.2005 11:52:36]

Lainaa #

AARGH!!! Ei vieläkään kerrota sitä kartan latausta!!! :'(

eraggo [08.06.2005 01:01:14]

Lainaa #

tumpelo... mitä oikein meinaat tolla kartan latauksella?

Tumpelo [08.06.2005 10:09:56]

Lainaa #

öö sitä et miten sen kentän saa ladattua oikeaoppisesti eikä niin että map(1,1) = 3 jne... Vähän hiasta tolla tavalla...

hunajavohveli [09.06.2005 09:42:49]

Lainaa #

Kartan lataaminen onnistuu kyllä erittäin helposti, mutta sen karttatiedoston luominen on paljon mutkikkaampaa ilman sitä varten tehtyä editoria. Joudun luultavasti käsittelemään tätä asiaa kokonaan omassa oppaassaan.

Tumpelo [09.06.2005 18:22:25]

Lainaa #

kannattais tehä se opas seuraavaksi, kun se on ainut este jonka takia en pääse koodaamaan erästä peliä :(

Rikesakko [02.07.2005 16:19:14]

Lainaa #

Juuh, mahtava opas.

Anteeksi jos joku on jo maininnut, mutta eikös tuonne RandomMap aliohjelmaan kannattaisi laittaa Randomize Timer käsky?

baabloo [28.07.2005 22:25:56]

Lainaa #

Tuleeko sitten, että kartat on cryptattuja ja ne encryptataan omalla ohjelmalla ja luetaan.

hunajavohveli [02.08.2005 22:58:56]

Lainaa #

Saatan kirjoittaa jotain kryptauksestakin, mutta senhän voi toki opetella erikseenkin.

Rikesakko: Juu, voihan tuonne laittaa Randomize Timerin, jos haluaa, muttei sillä tämän oppaan kannalta ole mitään merkitystä, koska loppujen lopuksi koko aliohjelmaa ei edes tarvita.

Flash [01.11.2005 19:08:31]

Lainaa #

Joo seuraavaks karttatiedoston luomisesta. Tai vois vaikka ees kertoo minkä nimisen editorin tarvii..

Huuhkain [07.11.2005 13:49:26]

Lainaa #

Onks sen uuden oppaan kirjottaminen yhtää missää vaiheessa?

Flash [07.11.2005 15:26:50]

Lainaa #

Mä mietin ihan samaa.

hunajavohveli [04.12.2005 16:27:00]

Lainaa #

Editori on oikeastaan hyvä koodata kokonaan itse, joten saatan siitäkin joskus oppaan tehdä. Kirjoittelu on jäänyt tässä nyt hieman vähemmälle, mutta voisin alkaa jossain välissä taas paneutua hommaan.

wumpus [23.12.2005 00:16:03]

Lainaa #

Hyvä opas vaikken Basiccia osaakaan. Pienellä päättelyllä käänsin tuon c++:lle ja hyvältä näyttää. Uutta osaa odotetaan vähintäänkin ideoiden vuoksi.

Nitros [01.01.2006 21:13:48]

Lainaa #

Milloinka seuraava osa ilmestyy?

Juhko [01.10.2006 11:29:30]

Lainaa #

COOOO­OO­O­OO­O­OO­O­OO­O­OO­O­OO­O­OO­O­OO­O­OO­OL!!!!!!!!!!!!!!!!!!!!!

Juhko [09.10.2006 20:30:50]

Lainaa #

Itse oikeastaan laitan hieman eri järjestykseen nuo rivit ja ne ovat vähän erilaisia. Tuon kun voi toteuttaa usealla eri tavalla.

Minun koneessani muuten luvut 80 ja 25 menevät sekaisin. Näyttö suttaantuu, jos Y menee 25 ja X 80.

Lisäksi laitan SCREEN 13-komennon yleensä alkuun ja vähennän hiukan X:n maksimiarvoa, koska muuten kirjain on leveyssuunnassa pienempi kuin pituussuunnassa.

Juhko [30.10.2006 16:14:07]

Lainaa #

Tumpelo kirjoitti:

AARGH!!! Ei vieläkään kerrota sitä kartan latausta!!! :'(

Laita alkuun vaikka DIM MapDrawVar(25) AS STRING
Laita sitten RandomMap-juttuun näin:

MapDrawVar(1) = "################################################################################"
MapDrawVar(2) = "#                          #                                                   #"
MapDrawVar(3) = "#                           #                                                  #"
MapDrawVar(4) = "#                            #                                                 #"
MapDrawVar(5) = "#                             #####                                            #"
MapDrawVar(6) = "#                                                                              #"
MapDrawVar(7) = "#                                       #                                      #"
MapDrawVar(8) = "#                                                                              #"
MapDrawVar(9) = "#                                                                              #"
MapDrawVar(10) = "#                                                                              #"
MapDrawVar(11) = "#                                                                              #"
MapDrawVar(12) = "#                                                                              #"
MapDrawVar(13) = "#                           ############                                       #"
MapDrawVar(14) = "#                                                                              #"
MapDrawVar(15) = "#                                                                              #"
MapDrawVar(16) = "#                                                                              #"
MapDrawVar(17) = "#                                                                              #"
MapDrawVar(18) = "#                                                                              #"
MapDrawVar(19) = "#                                                                              #"
MapDrawVar(20) = "#                                                                              #"
MapDrawVar(21) = "#                                                                              #"
MapDrawVar(22) = "#                                                                              #"
MapDrawVar(23) = "#                                                                              #"
MapDrawVar(24) = "#                                                                              #"
MapDrawVar(25) = "################################################################################"
FOR GetMapX = 1 TO 80
  FOR GetMapY = 1 TO 25
    Map(GetMapX, GetMapY) = 0
    IF MID$(MapDrawVar(GetMapY), GetMapX) = "#" THEN Map(GetMapX, GetMapY) = 1
  NEXT GetMapY
NEXT GetMapX

EDIT::::

Dude kirjoitti:

tuon vois teherä FOR jutulla

tarkoitin että tuonne väliin saa sitten #-merkeillä seinät minne haluaa.

Dude [17.03.2007 17:04:47]

Lainaa #

Juhko kirjoitti:

Laita alkuun vaikka DIM MapDrawVar(25) AS STRING
Laita sitten RandomMap-juttuun näin:...

tuon vois teherä FOR jutulla

Herrasir [18.03.2007 14:10:21]

Lainaa #

Ois jo korkea aika saada se neljäs osa tänne. Kohta 2 vuotta jo menny.

Juhko [01.05.2007 19:23:50]

Lainaa #

Niinpä. Ettei hunajavohveli olisi unohtanut?

TuhoojaBotti [12.06.2007 16:36:03]

Lainaa #

mulla ei toimi numpadilla mulla toimii vaan numeronäppäimillä!:(

Herrasir [13.07.2007 12:01:53]

Lainaa #

^ Ehkä tyhmä kysymys, mutta oliks sulla Num Locki päällä?

jesse123 [22.04.2008 20:35:45]

Lainaa #

jaa koskakohan tähän tulee uus osa vai onko enää ees tulossa? oli aika hyödyllinen itselleni ainakin, vaikka käytin FreeBasicia.

sammakkomies [30.11.2009 23:33:35]

Lainaa #

onko mahdollista tehdä ns nazi-tagia?

black cat [01.12.2009 12:45:15]

Lainaa #

hunajavohveli vois kyl kirjottaa sen loppuu ku muuten en ikinä opi tekee merkkigrafiikkapelejä

ErroR++ [11.04.2011 17:20:36]

Lainaa #

iha hyvä

Hengilö [01.04.2013 22:18:05]

Lainaa #

Pikkasen kestää seuraava osa... Eihän seuraavan osan lupa amisesta ole kuin vasta 8 vuotta.

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta