Kirjautuminen

Haku

Tehtävät

Opasarkisto: Merkkigrafiikkapelien ohjelmointi QBasicilla: Osa 2 - Alkeellinen pelimaailma

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

Kirjoittaja: hunajavohveli. Vuosi: 2005.

Pelimaailman luominen taulukkoon

Opassarjan ensimmäisessä osassa saimme aikaan toimivan mallin siitä, miten luoda näytölle pelaajan liikuttama @-merkki. Jatkamme siitä, mihin jäimme, ja seuraava vaihe onkin luoda pelimaailma ukon ympärille. Pelimaailma luodaan taulukkoon, jonka mitat ovat 80x25 eli alkioita on yhtä monta kuin merkkejä näytöllä. Kutakin merkkiä vastaavaan alkioon tallennetaan luku, joka kertoo, mitä kyseisessä kohdassa on.

DIM Map(1 TO 80, 1 TO 25) AS INTEGER       ' Luodaan taulukko
Map(30, 10) = 1                            ' Luodaan seinä kohtaan (30, 10)

Kokeillaanpa tällaista koodia. Aluksi luomme taulukon Map, jonka tyyppinä on pienin kokonaislukumuuttuja INTEGER. Jokainen taulukon kohta voi saada kymmeniä tuhansia eri arvoja. Näin ollen on siis kymmeniä tuhansia eri mahdollisuuksia kunkin ruudun sisällölle, mikä on taatusti riittävästi. Taulukotkin voit nimetä, miten itse tahdot. Käytän tässä oppaassa niitä nimiä, joihin olen itse tottunut. Toisella rivillä asetamme alkion (30, 10) arvoksi yksi. Tässä esimerkissä sovimme, että yksi tarkoittaa seinää, ja nolla tyhjää. Pelkkä sopiminen ei tietenkään riitä, vaan se pitää myös koodata niin. :)

Pelimaailman piirtäminen taulukosta

Kas niin. Nyt meillä on kenttää kuvaava taulukko, joten piirrämme seuraavaksi kentän taulukon arvojen mukaan.

DIM i AS INTEGER, i2 AS INTEGER        ' Indeksimuuttujat
CLS                                    ' Tyhjätään näyttö

FOR i2 = 1 TO 25                       ' Käydään silmukoilla...
  FOR i = 1 TO 80                      ' ...läpi jokainen ruutu
    LOCATE i2, i                       ' Asetetaan oikea kohta
    IF Map(i, i2) = 1 THEN PRINT "#";  ' Jos seinää, piirretään #
  NEXT i
NEXT i2

Ensin määritellään indeksimuuttujat i ja i2 silmukoille, joiden avulla käydään läpi jokainen näytön ruutu. Huomaa, että i kuvaa x-akselia, ja i2 y-akselia, joten LOCATElle annamme ensin i2:n ja sitten vasta i:n. Jokaisen ruudun kohdalla tarkistetaan, onko sillä kohtaa taulukossa luku yksi. Ja jos taulukossa on yksi, piirretään seinä (merkki #), koska luku yksi merkitsee seinää. Useimmilla lienee tapana käyttää indeksimuuttujina kirjaimia i, j, k, l jne. Itse olen tottunut mielestäni loogisempaan sarjaan i, i2, i3 jne. Voit jälleen valita sen tavan, mikä itsestäsi tuntuu parhaimmalta.

Piirtäminen aliohjelmaksi

Tässä vaiheessa alamme jakaa koodia aliohjelmiin ja teemme sellaisen myös tälle piirtokokonaisuudelle. Luomme siis aliohjelman (vaikkapa DrawMap-nimisen) ja siirrämme koodin siihen. Tällöin meidän on kuitenkin muutettava taulukko jaetuksi aliohjelmien kesken, mikä tehdään SHAREDilla. Eli muokkaamme aluksi luotua riviä pikkuisen:

DIM SHARED Map(80, 25) AS INTEGER

Sitten yhdistämme kaiken uuden oppaan ensimmäisessä osassa luotuun koodiin. Pääohjelmalistaus näyttää nyt siis tältä: (uudet rivit on merkitty tähdillä)

DECLARE SUB DrawMap ()                            ' Aliohjelman määrittely *
DIM SHARED Map(1 TO 80, 1 TO 25) AS INTEGER       ' Luodaan taulukko *
DIM x AS INTEGER, y AS INTEGER                    ' Pelaajan koordinaatit

x = 40
y = 12

Map(30, 10) = 1                                   ' Luodaan seinä kohtaan (30, 10) *

WIDTH 80, 25
CLS

DrawMap                                           ' Kutsutaan aliohjelmaa *

DO                                                ' Aloitamme pääsilmukan
    ' Ja tästä eteenpäin kaikki onkin jo tuttua

Ja aliohjelma tältä:

SUB DrawMap                              ' Aliohjelma alkaa

  DIM i AS INTEGER, i2 AS INTEGER        ' Indeksimuuttujat
  CLS                                    ' Tyhjätään näyttö

  FOR i2 = 1 TO 25                       ' Käydään silmukoilla...
    FOR i = 1 TO 80                      ' ...läpi jokainen ruutu
      LOCATE i2, i                       ' Asetetaan oikea kohta
      IF Map(i, i2) = 1 THEN PRINT "#";  ' Jos seinää, piirretään #
    NEXT i
  NEXT i2

END SUB                                  ' Aliohjelma loppuu

Törmäystarkistus

Kun nyt kokeilet ajaa ohjelman, näet #-merkin ilmestyvän näytölle @:n seuraksi. Jos kuitenkin kävelet sitä päin, @-merkki vain liikkuu sen yli ja kumittaa sen. Meidän on siis luotava törmäystarkistus, jolla estämme tämän. Tarkistamme ensin, mihin ukko on liikkumassa. Sitten tutkimme, onko sillä kohtaa tyhjää vai kenties jokin este. Jos kohta vapaa, siirrämme ukon siihen. Muussa tapauksessa tietysti emme.

Muokkaamme siis hieman vanhaa koodia. Emme enää muutakaan suoraan ukon koordinaatteja, vaan tallennammekin uudet koordinaatit muuuttujiin ux ja uy (muista määritellä nämä uudet muuttujat koodin alussa samoin kuin x ja y). Muuttujat ux ja uy kertovat siis paikan, johon ukko on aikeissa siirtyä. Huomaa, että nyt täytyy määritellä molemmat koordinaatit, vaikka vain toista muutettaisiin. Jos x-koordinaattia muutetaan, y-koordinaatti pysyy tietysti samana ja päinvastoin. Jos koodasit omin päin myös vinottain liikkumisen ja nuolinäppäimet, muista vaihtaa ux ja uy myös niiden riveille.

ux = x                           ' Siltä varalta, ettei liikutakaan...
uy = y                           ' ...pidetään samat koordinaatit

SELECT CASE a$
  CASE "4": ux = x - 1: uy = y   ' Nyt uudet arvot tulevatkin
  CASE "6": ux = x + 1: uy = y   ' muuttujiin ux ja uy
  CASE "8": uy = y - 1: ux = x
  CASE "5": uy = y + 1: ux = x
  ...

Jos nyt kokeilet ajaa ohjelman, et voi liikuttaa ukkoa, koska jokainen painallus muuttaa vain muuttujia ux ja uy. Seuraavaksi tarkistamme, onko näiden koordinaattien osoittamassa kohdassa estettä. Ja mikäli ei ole, muutamme x:n ja y:n vastaamaan näitä koordinaatteja, jolloin ukko liikkuu normaalisti. Jos kohdassa taas on este, varsinaisia koordinaatteja ei muuteta ja ukko pysyy siten paikallaan.

IF Map(ux, uy) = 0 THEN    ' Jos kohdassa (ux, uy) on tyhjää...
  x = ux                   ' vaihdetaan varsinaiset
  y = uy                   ' koordinaatit
END IF

Voit jälleen kokeilla ajaa koodin, ja jos kaikki toimii, kuten pitää, ukko ei tällä kertaa pääse seinän läpi. Voit testimielessä kokeilla vaikka arpoa seiniä sattumanvaraisesti ruudulle yksittäisen asettamisen sijaan. Kentän arpominen on järkevintä nyt, kun vasta testailemme pelimoottorin toimintaa. Arpomisesta ja satunnaisluvuista löydät lisää tietoa ohjelmointikielihakemistosta. Oppaan tulevissa osissa käsittelemme mahdollisesti kentän luomista loogisemmilla tavoilla ja/tai kentän lataamista tiedostosta. Elikkäs tämmöisen koodin voit pistää yksittäisen seinän luomisen tilalle:

FOR a = 1 TO 100
  Map(INT(RND * 80) + 1, INT(RND * 25) + 1) = 1      ' Arvotaan paikka ja asetetaan kohtaan seinä
NEXT a

Kutakuinkin tältä ohjelman pitäisi nyt näyttää:

Seinien lisäksi on hyvä huomioida myös ruudun reunat. Kenttähän on kokoa 80x25, joten pienin mahdollinen x:n arvo on 1 ja suurin 80. Vastaavasti y:n pienin mahdollinen arvo on 1 ja suurin 25. Meidän täytyy vain varmistaa, että pelaaja pysyy näiden rajojen sisäpuolella. Asia voidaan tarkistaa tällä tavalla:

IF ux < 1 OR ux > 80 OR uy < 1 OR uy > 25 THEN ux = x: uy = y   ' Pidetään nykyiset koordinaatit

Ehtolauseke tarkistaa, ettei pelaaja liiku yhdenkään rajan yli. Eri rajojen tarkistukset erotellaan loogisella OR-operaattorilla. Joten jos yksikin rajoista on ylitetty, koko ehtolauseke on tosi. Tällöin muutetaan uusiksi koordinaateiksi nykyiset koordinaatit, jolloin pelaaja ei liiku mihinkään. Huomaa, että tämä tarkistus on sijoitettava koodiin ennen reunatarkistusta, sillä seinätarkistuksessa luetaan Map-taulukkoa, ja jos ux ja uy ovat jo silloin reunan ulkopuolella, tulee virhe yritettäessä lukea taulukkoa väärillä arvoilla. Jos taas reunatarkistus on ensimmäisenä, vialliset koordinaatit palautetaan edellisiksi, joiden kohdasta taulukkoa voidaan lukea. Lisää tämä tarkistus oikeaan kohtaan juuri ennen seinätarkistusta. Nyt pelaajan ei pitäisi päästä myöskään ruudun reunojen ulkopuolelle.

Huom! Törmäystarkistuksen voi toteuttaa myös niin, että laitetaan ensin muistiin ukon nykyiset koordinaatit, sitten liikutaan, ja jos uudessa paikassa onkin este, palautetaan vanhat koordinaatit takaisin. Periaatteessa tämä on aivan sama tapa kuin äsken esittelemäni, mutta ei välttämättä niin selkeä ymmärtää kuin ensimmäinen. Lisäksi se voi aiheuttaa myöhemmissä vaiheissa joitain ongelmia.

Koodin jakaminen aliohjelmiin

Koodia on nyt kertynyt jo useamman rivin verran. Koska koodin jokaista osa-aluetta tullaan tästä eteenpäin paisuttelemaan, tulee helposti hyvin epäselväksi pitää kaikki samassa pötkössä. Jaamme siis ohjelman pienempiin aliohjelmiin, joita kutsutaan pääohjelmassa vuorotellen siinä järjestyksessä, missä aliohjelmiin laitettavat kooditkin nyt ovat. Kävimme jo läpi aliohjelman luomisen kentän piirtämisen yhteydessä, joten homma sujunee helposti. Lähdetään liikkeelle koodin alusta. Ensimmäinen vastaan tuleva kokonaisuus, jolle kannattaa tehdä aliohjelma, on kentän arpominen. Luomme siis esimerkiksi RandomMap-nimisen aliohjelman ja sijoitamme koodin siihen:

SUB RandomMap

  FOR a = 1 TO 100
    Map(INT(RND * 80) + 1, INT(RND * 25) + 1) = 1      ' Arvotaan paikka ja asetetaan kohtaan seinä
  NEXT a

END SUB

Pääohjelmaan kirjoitamme koodin tilalle aliohjelmakutsun, joka tulee siis heti ennen DrawMap-kutsua.

...
CLS

RandomMap   ' Arvotaan kenttä
DrawMap     ' Piirretään kenttä

DO          ' Pääsilmukka
...

Voit välissä varmistaa, että ohjelma toimii edelleen, kuten pitää. Sitten siirrymme eteenpäin. Ukon piirto ja kumitus hoituvat toistaiseksi melko lyhyesti, mutta näppäimen lukemisen voisimme laittaa aliohjelmaan ja tarkemmin sanottuna funktioon. Luomme funktion (vaikkapa nimellä GetKey$). Nimen perään tulee $, koska funktion tulee palauttaa merkkijono. Sitten siirrämme koodin funktioon.

FUNCTION GetKey$

  DO
    a$ = INKEY$
  LOOP UNTIL a$ <> ""
  GetKey = a$           ' Funktion palautusarvo

END SUB

Funktiota kutsumme tällä tavalla:

a$ = GetKey           ' Painettu näppäin välittyy a$:iin

Katsotaanpa nyt siis, mitä tapahtuu. Funktiota kutsuva rivi saa ohjelman ajamaan GetKey-funktion koodin. GetKey-funktiossa luetaan näppäin aivan normaalisti muuttujaan a$, kuten aikaisemminkin. Huomaa, että tämä ei kuitenkaan enää ole sama a$ kuin pääohjelmassa. Sillä aliohjelmilla ja pääohjelmalla on omat muuttujansa, vaikka muuttujat olisivat samannimiset (paitsi tietysti jos ne jaetaan SHAREDilla, kuten teimme Map-taulukolle). Funktioon laitamme kuitenkin yhden uuden rivin:

GetKey = a$           ' Funktion palautusarvo

Tämä rivi saa aikaan sen, että funktio palauttaa luetun näppäimen. Funktiota kutsuvan rivin kautta näppäin siis välittyy edelleen pääohjelman a$-muuttujaan, jossa sitä voidaan käyttää painetun näppäimen tarkistamiseen.

Teemme vielä yhden aliohjelman, joka on myös funktio. Yhdistämme törmäystarkistukset yhdeksi funktioksi. Annamme funktiolle parametriksi koordinaatit joihin pelaaja on aikeissa siirtyä (ux, uy). Funktion sisällä suoritetaan sekä reuna- että seinätarkistus. Kun tarkistukset on tehty, funktio palauttaa joko 0 tai -1. Jos tarkistuksessa ilmenee, että ruudussa on este, tai että se on näytön ulkopuolella, funktio palauttaa nollan. Muussa tapauksessa -1. Kutsumme funktiota tehtävänsä mukaisesti nimellä CanMove.

FUNCTION CanMove(x AS INTEGER, y AS INTEGER)

  CanMove = -1                                  ' Oletetaan aluksi, että ruutuun voi liikkua

  IF x < 1 OR x > 80 OR y < 1 OR y > 25 THEN    ' Reunatarkistus
    CanMove = 0                                 ' Ei voikaan liikkua
    EXIT FUNCTION                               ' Pois funktiosta
  END IF

  IF Map(x, y) <> 0 THEN                        ' Seinätarkistus
    CanMove = 0
    EXIT FUNCTION
  END IF

END FUNCTION

Ensimmäisellä rivillä tietysti määritellään funktio ja ilmoitetaan sen parametrit, jotka ovat x ja y. Huom! Kyseessä ovat jälleen funktion sisäiset muuttujat, joilla ei ole mitään tekemistä pääohjelmassa esiintyvien pelaajan koordinaattien kanssa. Kun funktiota kutsutaan arvoilla ux ja uy, niiden arvot välittyvät funktion x- ja y-muuttujiin. Näin ollen joudumme vaihtamaan myös törmäystarkistusrivien muuttujat x:ksi ja y:ksi.

Aluksi oletetaan, että ruutuun voidaan liikkua, joten CanMoven palautusarvoksi asetetaan -1. Sitten suoritetaan tarkistukset. Jos tarkistuksissa ilmenee, ettei ruutuun voi liikkua, CanMoven arvoksi muutetaan nolla ja sen jälkeen funktiosta poistutaan EXIT FUNCTION -komennolla. Sillä eihän meidän tarvitse enää tutkia, tapahtuuko seinätörmäystä, jos tiedämme jo, että koordinaatit ovat näytön ulkopuolella. Eli joka tapauksessa kulku siihen suuntaan estetään.

Seinätarkistusriviä joudumme myös hieman muokkaamaan. Aikaisemminhan tarkistimme sen avulla, onko ruutu, johon ollaan liikkumassa, tyhjä. Nyt tarkistammekin, onko ruudussa jokin este. Ja este on, mikäli ruutu ei ole tyhjä. Eli jos ruudun arvo on erisuuri kuin nolla. Tällöin ruudussa on este, ja CanMoven arvoksi asetetaan nolla. Saman tien myös poistutaan funktiosta.

Kun funktion suoritus lopulta päättyy, sen arvo on joko 0 tai -1, sen mukaan, onko sillä tarkistetussa ruudussa estettä vai ei. Sijoitamme funktiokutsun pääohjelmaan tällä tavalla:

IF CanMove(ux, uy) THEN       ' Jos ruutuun voidaan liikkua
  x = ux
  y = uy
END IF

Annamme funktiolle parametreiksi ux:n ja uy:n. Funktio tutkii, voidaanko ruutuun liikkua. Jos ruutuun voidaan liikkua, funktio palauttaa -1. Tällöin tapahtuu sama, kuin jos rivi olisi:

IF -1 THEN

Arvo -1 on ehtolausekkeelle sama kuin tosi, joten ehtolausekkeen koodi suoritetaan ja ux ja uy siirretään varsinaisiksi koordinaateiksi. Nolla taas on sama kuin epätosi, jolloin koodia ei suoriteta.

Yhteenveto

Pääohjelmalistauksen pitäisi näyttää kokonaisuudessaan nyt siis tältä:

' Aliohjelmamäärittelyt
DECLARE SUB DrawMap ()
DECLARE FUNCTION GetKey$ ()
DECLARE SUB RandomMap ()
DECLARE FUNCTION CanMove! (x AS INTEGER, y AS INTEGER)

DIM SHARED Map(1 TO 80, 1 TO 25) AS INTEGER  ' Luodaan taulukko
DIM x AS INTEGER, y AS INTEGER               ' Pelaajan koordinaatit
DIM ux AS INTEGER, uy AS INTEGER             ' Uudet koordinaatit

x = 40
y = 12

WIDTH 80, 25
CLS

RandomMap                                    ' Arvotaan kenttä taulukkoon
DrawMap                                      ' Piirretään kenttä taulukosta

DO                                           ' Pääsilmukka

  LOCATE y, x                                ' Piirretään ukko
  PRINT "@";

  a$ = GetKey                                ' Luetaan näppäin funktiolla

  LOCATE y, x                                ' Kumitetaan ukko
  PRINT " ";

  ux = x                                     ' Pysytään paikalla...
  uy = y

  SELECT CASE a$
    CASE "4": ux = x - 1: uy = y             ' ...ellei liikuta
    CASE "6": ux = x + 1: uy = y
    CASE "8": uy = y - 1: ux = x
    CASE "5": uy = y + 1: ux = x
    CASE CHR$(27): END
  END SELECT

  IF CanMove(ux, uy) THEN                    ' Jos ruutuun voi liikkua
    x = ux                                   ' niin sitten liikutaan
    y = uy
  END IF

LOOP

Kaikki muu on jaettu aliohjelmiin, jolloin koodi näyttää paljon selkeämmältä. Toivon mukaan ohjelma myös yhä toimii, kuten ennen aliohjelmiin jakamista. Jos havaitset virhetoimintaa, tutki ohjeita uudelleen ja yritä selvittää, missä kohtaa sattui virhe.

Tämän oppaan asiat on nyt käsitelty. Toivottavasti onnistut sisäistämään kaiken hyvin. Pelihahmo on tässä vaiheessa saatu liikkumaan ja törmäämään esteisiin. Mahdollisesti tulevissa osissa siirrytäänkin seuraavaksi tietokoneen ohjaamien hahmojen, hirviöiden yms. luomiseen. Jos sinua huvittaa, voit kokeilla omin päin, osaisitko lisäillä pelimoottoriin seuraavanlaisia asioita:

  1. Mikäli ensimmäisen osan jälkeen lisäsit nuolinäppäimet ja vinottain liikkumisen, lisää ne uudelleen mukaan. Paitsi tietysti, jos olet kirjoittanut kaiken oppaassa esitellyn itse, ja ne siten ovat jo mukana. Tällainen tapa onkin suositeltavaa. Kun itse kirjoittaa koodin, ehtii myös paremmin miettiä sen toimintaa.
  2. Lisää sellainen ominaisuus, että seinä tuhoutuu, kun sitä päin kävelee. Mutta niin, että sen pitää kadota ennen kuin sen päälle voi liikkua. Seinä täytyy luonnollisesti poistaa taulukosta. Voit kokeilla kumittaa sen näytöltä samalla tavalla kuin @-merkin.
  3. Kokeile lisätä näkymättömiä seiniä. Eli seiniä, joita ei piirretä näytölle, mutta joiden läpi ei kuitenkaan voi kulkea. Seinien indeksiluvuiksi valitsimme ykkösen. Valitsepa näkymättömällä seinälle joku toinen luku.
  4. Laita uusi seinä ilmestymään satunnaisesti näytölle joka kerta, kun pelaaja liikuttaa ukkoa. Tee laskuri, joka kertoo, kuinka monta kertaa pelaaja pystyi liikkumaan, ennen kuin jäi loukkuun seinien väliin. Älä arvo seiniä siihen kohtaan, missä ukko sillä hetkellä seisoo!

Valmiin koodin ja käännetyn ohjelman voit jälleen ladata tästä.


Kommentit

herkko [08.04.2005 21:21:30]

Lainaa #

Hyvä opas! Onko tietoa, milloin seuraava osa olisi tulossa?

hunajavohveli [09.04.2005 00:27:09]

Lainaa #

En osaa vielä sanoa, mutta jatkoa on lähes varmasti tulossa. Ei välttämättä aivan lähi aikoina, mutta pyrin jo alustavasti miettimään asioita, joita seuraava osa käsittelisi.

Cc [09.04.2005 13:33:41]

Lainaa #

Erittäin hyvä opas! tässä kerrotaan kaikki mitä tarvitsee tietää.

BlueByte [09.04.2005 14:01:02]

Lainaa #

tee sama opas C:lle.

hunajavohveli [09.04.2005 16:00:39]

Lainaa #

C ei ole minulle vielä aivan tarpeeksi tuttu. Pystyisin sillä kyllä periaatteessa samaan, mutta kieli täytyisi saada rutiiniksi, ennen kuin rupeaa opasta tekemään. En ole lisäksi varma, mitä funktioita olisi järkevintä käyttää ei-rakenteellisiin asioihin (lähinnä tekstintulostus). Pienimuotoista pseudo-versiota voisin kyllä harkita jossain välissä.

kaviaari [10.04.2005 09:18:54]

Lainaa #

Itseäni härnäsi tuo ux, uy tapa hoitaa asiat :) Itse kun tile pohjaisia pelejä kirjoittelen määrittelen usein vanhat x ja y koordinaatit. Hoituuhan tuo noinkin, kas kun en itse ole koskaan ajatellut :/

hunajavohveli [10.04.2005 09:42:52]

Lainaa #

Itsekin kieltämättä olen aina käyttänyt tuota mainitsemaasi tapaa, mutta nyt kun kirjoitin asiasta oppaan, niin päätin miettiä uudestaan, miten päin se olisi järkevämpi toteuttaa. Tämä tuntui minusta paremmalta, kun otetaan huomioon, että liikkumisen voi estää moni eri asia. Toki saman voi tehdä myös vanhojen koordinaattien periaatteella, mutta mielestäni hieman purkkamaisemmin.

eraggo [11.04.2005 19:07:08]

Lainaa #

joo... on hyvä opas :) lisää tämmöisiä....
yksi pikku pulma tuli ton "satunnaispaikkojen" kanssa...
koodistasi puuttui nimittäin "RANDOMIZE TIMER"-juttu

muuten koodi oli hyvää ja selityksetkin löytyivät.....

d_((^.^))_b

hunajavohveli [11.04.2005 19:58:08]

Lainaa #

Satunnaisluvuista en viitsinyt selittää tämän enempää ja RANDOMIZE TIMER löytyy kyllä antamastani linkistä. :)

E.K.Virtanen [11.04.2005 23:21:49]

Lainaa #

Varsin selkeää ja mukavaa luettavaa.
Koko ruudun täyttämisen lisäksi voisi olla hyvä ottaa esille miten luoda maailma jota liikutella sellaisessa 25x25 "boksissa" niin että ukko on keskellä boksia ja maailma liikkuu, ei ukko tai boksi.

Itse teen tämän omalla tavallani mutta olisi mukava nähdä miten muut sen tekee :)

Itse laiskuuttani käytän IF tyyliä mutta pakko myöntää että tuo SELECT CASE on nätimpää...taidanpa tehdä "pikku" muutoksen omaan ohjelmaani =)

hunajavohveli [12.04.2005 13:54:07]

Lainaa #

Tuon piirtotavan, että "kamera" seuraa ukkoa, joka näyttää siten pysyvän keskellä, esittelen kyllä myöhemmissä osissa, jos innostun sellaisia kirjoittamaan. IF:ä käytän oikeastaan aika paljon itsekin, mutta oppaaseen päätin laittaa siistimmän tavan. :)

InvalidCo [28.04.2005 15:22:41]

Lainaa #

Eikös QB:ssä ne kaksi viimeistä riviä jää aina tyhjäksi sitä "Press any key to continue"?

eraggo [28.04.2005 23:44:04]

Lainaa #

joo... tahtoo nähä seuraavan osan (mikäli aiot/ehdit tehdä sellaista muista kiireistäsi huolimatta)

hunajavohveli [01.05.2005 15:11:43]

Lainaa #

PC-Master kirjoitti:

Eikös QB:ssä ne kaksi viimeistä riviä jää aina tyhjäksi sitä "Press any key to continue"?

Ne rivit lisää ainoastaan QB:n tulkki, kun ohjelman suoritus on loppunut. Ne eivät kuulu itse ohjelmaan, eivätkä näy käännetyssä exe:ssä.

Megant92 [10.05.2005 17:44:54]

Lainaa #

Hieno opas.Olisin tosin tarvinnut tuota vuosi sitten.

darkest [13.05.2005 21:25:15]

Lainaa #

kympin opas ;P

Khaoralius [27.05.2005 13:32:54]

Lainaa #

Milloins se seuraava osa tulee? Ei sillä sinänsä ole minulle enään mitään käyttöä, muutakun tarkistus mielessä. Kun jo netistä löytyi ihan hyvä englannin kielinen opas ^^

SuperNörtti [24.07.2005 17:38:42]

Lainaa #

Kiitokset hunajavohveli! Tuli tarpeeseen.

CyantLeap [08.12.2005 20:54:22]

Lainaa #

Opin tuosta ainakin jotain.. Hieno opas!

Mobel [03.05.2006 14:22:13]

Lainaa #

Erittäin hyvä opas!
Pääsee aloittelijakin käsiksi peliohjelmointiin
Khaoralius, laitatko linkin eng-kiel oppaaseen

Juhko [17.07.2006 22:07:16]

Lainaa #

Miten ton saa käännetyks exelle?

Juhko [17.07.2006 22:30:48]

Lainaa #

Miks toi sanoo koko ajan että "Argumen-count mismatch"

Dude [17.03.2007 16:22:34]

Lainaa #

Mä tein tuosta semmoosen version johona on 80x50 tekstitila

MikaBug [09.08.2007 21:09:52]

Lainaa #

Todella mainio opas! Mielenkiintoista luettavaa itsellekin. Ohjelmoin tuossa taannoin matopelin JavaScriptillä (testimielessä ja huvinvuoksi). Tuli ihan toimiva, vaikka en varmasti parhaita ratkaisuja osannutkaan käyttää kaikissa tilanteissa. Ehkä tämän opassarjan lukemisen jälkeen osaan koodailla paremman matopelin ja kenties jotain muutakin! :) Jatkoakin tälle opassarjalle olisi kiva saada.

Dain [24.09.2007 19:06:26]

Lainaa #

saisk tätä mitenkään javalle???

sammakkomies [30.11.2009 23:24:02]

Lainaa #

toivottavasti seuraavissa oppaissa kerrotaan miten saa ns. cheat jutut toimimaan.

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