Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6: Liikkuminen ruudukossa

Sivun loppuun

kayttaja-3842 [15.04.2006 19:05:35]

#

Voiko joku kertoa miten onnistuisi tehdä sellanen, että kun painaa hiirtä niin ukko kävelee sinne mihin hiirellä painettiin. Nyt kyllä alkoi nolottaa, mutta jotta te ymmärtäisitte minun täytyy käyttää esimerkkinä habbo hotellia. Eli siis siinä se ukko kävelee aina 32x32 palikan verran. Eli siis ukon joka "askel" on 32x32 kuution kokoinen ja se ukko ei voi kävellä hiiren asettamaan koordinaatiin sivuttain, vaan sen pitää kävellä isometrisiä 32x32 palikoita pitkin. Toivottavasti älysitte. Lyhyesti ja ytimekkäästi sen voi sanoa, että miten voi ntehä sellaseen hiiri ukko kävely järjeltemän kuten habbo hotellissa on...

Nyt kyllä nolottaa, kun puhun täällä Habbo hotellista omg omg lololol...

Antti Laaksonen [16.04.2006 01:54:55]

#

Tiedossa täytyy olla ukon senhetkinen paikka ja määränpää. Voidaan ajatella, että ukko liikkuu ruudukossa. Nyt yhden animaation vaiheen aikana ukko voi liikkua pysty- tai vaakasuuntaisesti yhden ruudun sopivaan suuntaan. Tämä tarkoittaa sitä, että ukon x- tai y-koordinaatti voi muuttua ruudukon ruudun sivunpituuden verran.

Liikkumisen voi tehdä niin, että tietyin väliajoin (esim. viisi kertaa sekunnissa) tarkistetaan ukon nykyisen paikan ja uuden paikan koordinaatit. Jos x- tai y-koordinaatit poikkeavat toisistaan, niitä pitää muuttaa. Muutoksen voi tehdä vaikka niin, että sitä koordinaattia muutetaan, jonka poikkeama on kulloinkin suurempi. Silloin molemmat koordinaatit muuttuvat vuorotellen tasaisesti.

Teinpä vielä iltapuhteiksi pienen esimerkin. Formilla täytyy olla Timer1-niminen ajastin, mutta muuten koodi toimii suoraan.

Option Explicit

Dim x As Integer, y As Integer
Dim ux As Integer, uy As Integer

Private Sub Form_Load()
    ' muutetaan ikkunan koko sopivaksi
    Width = 5000
    Height = 5000
    ' muutetaan piirtoasteikko sopivaksi
    ScaleLeft = -1
    ScaleTop = -1
    ScaleHeight = 12
    ScaleWidth = 12
    ' automaattinen kuvan päivitys
    AutoRedraw = True
    ' piirretään ruudukko
    Dim i As Integer, j As Integer
    For i = 0 To 10
        Line (0, i)-(10, i)
        Line (i, 0)-(i, 10)
    Next
    ' piirretään ympyrä
    x = 0
    y = 0
    Circle (x + 0.5, y + 0.5), 0.4
    ' käynnistetään ajastin
    Timer1.Interval = 200
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    ' määritetään ympyrän uusi paikka
    ux = Int(x)
    uy = Int(y)
End Sub

Private Sub Timer1_Timer()
    ' jos uusi paikka poikkeaa nykyisestä...
    If ux <> x Or uy <> y Then
        ' poistetaan vanha ympyrä
        Circle (x + 0.5, y + 0.5), 0.4, BackColor
        ' jos x-koordinaatti poikkeaa enemmän...
        If Abs(x - ux) > Abs(y - uy) Then
            ' ...muutetaan sitä oikeaan suuntaan
            If ux > x Then x = x + 1
            If ux < x Then x = x - 1
        ' jos y-koordinaatti poikkeaa enemmän...
        Else
            ' ...muutetaan sitä oikeaan suuntaan
            If uy > y Then y = y + 1
            If uy < y Then y = y - 1
        End If
        ' piirretään uusi ympyrä
        Circle (x + 0.5, y + 0.5), 0.4
    End If
End Sub

Tässä koodissa formin koordinaatisto on valittu ovelasti niin, että yhden yksikön liikkuminen vastaa yhden ruudun mittaista liikkumista. Jos mittayksikkönä on pikseli ja ruudun koko on 32 pikseliä, pelihahmo liikkuu tietenkin aina 32 pikseliä kerrallaan. Kahden paikan pitää sijaita aina niin, että niiden molempien koordinaattien ero on jaollinen askeleen suuruudella.

kayttaja-3842 [16.04.2006 13:45:15]

#

Juuri tuollaista tarkoitin, mutta en oikein päässyt jyvälle tuosta sinun kirjoituksestasi. Olen valitettaavasti aivan pihalla. Pystytkö jotenkin kertomaan sen yksinkertaisemmin? Itse tein tälläseen testin,jonka avulla laattaa voi liikuttaa nuolilla. Eikö toi ole aivan oikein, että laatan pitää liikkua aina 32 ja 16 jos lattian laatta on 32x32? Itselläni sen liikutettavan laatan linja alkaa heitämään. Kuten tässä.

http://pelivartti.com/Peli2.rar

Kuteinkin päätarkoituksena nyt olisi, että oppisin ymmärtämään tuota sinun tekemääsi liikkumis järjestelmää.

Edit1:

Minkä takia tässä X ja Y:sä pitää olla vielä +0.5? Jos muokkaan sitä vaikka + 0.4 niin ympyrä kopioi itsensä kun liikkuu.

Circle (x + 0.5, y + 0.5), 0.4, BackColor

Antti Laaksonen [16.04.2006 15:02:54]

#

Esimerkki:
Ympyrän nykyinen kohta on (3, 3) ja uusi kohta on (5, 7). Nyt havaitaan, että koordinaatit poikkeavat toisistaan, joten ympyrän pitää siirtyä johonkin suuntaan. Lasketaan x-koordinaatin ero: Abs(3 - 5) = 2. Lasketaan y-koordinaatin ero: Abs(3 - 7) = 4. Tässä Abs on itseisarvo, jonka avulla saa kahden koordinaatin etäisyyden toisistaan.

Koska y-koordinaatin ero on suurempi, muutetaan y-koordinaattia. Nykyinen y-koordinaatti on 3, ja uusi y-koordinaatti on 7. Selvästi 7 > 3, eli y-koordinaattia pitää suurentaa. Niinpä seuraavaksi paikaksi tulee (3, 3 + 1) eli (3, 4). Nyt ympyrä on hieman lähempänä määränpäätään. Tämä sama kuvio toistuu (esim. ajastimen avulla) niin kauan kuin koordinaateissa on eroa.

Minun koodissani formin piirtoasteikkoa on muutettu niin, että ruudun reuna on aina kokonaisluvun kohdalla. Esim. yhden ruudun vasen yläkulma on kohdassa (3, 3) ja oikea alakulma on kohdassa (4, 4). Kun tällaisen ruudun sisään piirretään ympyrä, keskipiste pitää tietysti olla ruudun keskikohdassa. Siksi lisätään 0,5 koordinaatteihin. Ympyrän säteenä on 0,4, jotta ympyrä mahtuu ruudun sisään.

Isometrisessä pelissä pelihahmon x- ja y-koordinaatteja olisi ehkä paras käsitellä kokonaislukuina. Asteikon voi valita vaikkapa niin, että yhden yksikön muutos vastaa yhden askeleen muutosta. Vasta piirtovaiheessa koordinaatit muutetaan todellisuutta vastaaviksi. Tämän ansiosta pelihahmon liikutus on helppoa ja pyöristysvirheistä ei ole pelkoa. Tarvittava muutoskaava ei ole kovin monimutkainen, sen pystyt selvittämään kynällä ja paperilla.

kayttaja-3842 [16.04.2006 15:29:16]

#

Noh voitko sanoa miksi tämä ei toimi oikein?

http://pelivartti.com/Peli3.rar

Gaxx [16.04.2006 21:38:09]

#

Liikkumiset ja muut sijainnit kannattaa melkein aina — ainakin tässä tapauksessa — käsitellä "suoraan ylhäältäpäin kuvatussa ruudukossa". Liikutat ukkoa mainitussa ruudukossa suoraan ylös tai sivulle. Vasta piirtovaiheessa projisoit ruudukon tuollaiseksi vinosti kuvatuksi.

Kannattaa käydä ihan paperilla läpi, miten piirrät(tai asetat objectit) ylhäältäpäin kuvatun ruudukon vinosti kuvatuksi ruudukoksi. Tällöin muukin ohjelmointi helpottuu huomattavasti.

Antti Laaksonen [16.04.2006 21:42:42]

#

Isometrinen (tai sen tapainen) kuvakulma monimutkaistaa hieman koodia. Nyt pelihahmolla on tavallaan kahdet koordinaatit: sijainti ruudukossa ja sijainti näytöllä. Ruudukon sijainti muuttuu samaan tapaan kuin ennenkin: kerrallaan muuttuu joko x- tai y-koordinaatti. Mutta näytöllä pelihahmo liikkuu sekä x- että y-suunnassa, koska se on kuvattu vinosti.

Tämän takia koordinaatteja voi käsitellä muuten samalla tavalla kuin aikaisemmin, mutta kun pelihahmo piirretään tai luetaan näytöltä hiiren paikka, pitää käyttää muuntokaavoja.

xnäyttö = k * xruudukko + k * yruudukko
ynäyttö = yruudukko
xruudukko = (k * yruudukko - xnäyttö) / -k

Tässä k on sopiva kerroin, joka vaikuttaa ruudukon suuntaan ja kallistukseen. Nämä kaavat on helppo johtaa piirtämällä ruutupaperille vinosti kuvattu ruudukko ja tarkastelemalla sen ruutujen päätepisteiden koordinaatteja. Juuri näin sain selville äskeiset kaavat.

Tässä on muutettu esimerkkiohjelma:

Option Explicit

Dim x As Integer, y As Integer
Dim ux As Integer, uy As Integer

Private Sub Form_Load()
    ' muutetaan ikkunan koko sopivaksi
    Width = 5000
    Height = 3000
    ' muutetaan piirtoasteikko sopivaksi
    ScaleLeft = -41
    ScaleTop = -1
    ScaleHeight = 12
    ScaleWidth = 42
    ' automaattinen kuvan päivitys
    AutoRedraw = True
    ' piirretään ruudukko
    Dim i As Integer, j As Integer
    For i = 0 To 10
        Line (-2 * i, i)-(-2 * (i + 10), i)
        Line (-2 * i, 0)-(-2 * (i + 10), 10)
    Next
    ' piirretään ympyrä
    x = 0
    y = 0
    Circle (-2 * (x + 0.5) + -2 * (y + 0.5), y + 0.5), 0.4
    ' käynnistetään ajastin
    Timer1.Interval = 200
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    ' määritetään ympyrän uusi paikka
    ux = Int((-2 * y - x) / 2)
    uy = Int(y)
End Sub

Private Sub Timer1_Timer()
    ' jos uusi paikka poikkeaa nykyisestä...
    If ux <> x Or uy <> y Then
        ' poistetaan vanha ympyrä
        Circle (-2 * (x + 0.5) + -2 * (y + 0.5), y + 0.5), 0.4, BackColor
        ' jos x-koordinaatti poikkeaa enemmän...
        If Abs(x - ux) > Abs(y - uy) Then
            ' ...muutetaan sitä oikeaan suuntaan
            If ux > x Then x = x + 1
            If ux < x Then x = x - 1
        ' jos y-koordinaatti poikkeaa enemmän...
        Else
            ' ...muutetaan sitä oikeaan suuntaan
            If uy > y Then y = y + 1
            If uy < y Then y = y - 1
        End If
        ' piirretään uusi ympyrä
        Circle (-2 * (x + 0.5) + -2 * (y + 0.5), y + 0.5), 0.4
    End If
End Sub

Tämä asia on siksi mutkikas, että asian ymmärtämiseksi on pakko piirrellä kaikenlaisia kuvia paperille ja tutkia koordinaattien muutoksia. Pelkkä valmiin koodin kopiointi ja yhdistely saattaa toimia hyvällä onnella, mutta ennen pitkää tällä menetelmällä tulee seinä vastaan.

kayttaja-3842 [17.04.2006 10:54:04]

#

Kiitos paljon....


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta