Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Map editor

Sivun loppuun

mika132 [11.01.2011 06:26:08]

#

Olen tässä suunnitellut map editoria, mutta tulipa yhtäkkiä mieleen, että miten saan ne pelissä auki?

Eli olen tehnyt omallaista editoria jossa tietty layeri on seinä niin miten se pitäisi tallentaa ja miten sen voisi avata pelissäni? Onko esim

track_1.dat tekstitiedosto hyvä, johon sitten tallennetaan mitä ja miten?

vehkis91 [11.01.2011 06:50:51]

#

Suunnitelet sopivan formaatin kartallesi, tallennat tässä formaatissa tekstitiedostoon kartan ja lataat pelissäsi, tai vaihtoehtoisesti tallennat binaarina ja luet pelissäsi binaarina.

Metabolix [11.01.2011 07:00:48]

#

Taasko on pakko yrittää perä edellä puuhun? Tee ensin pelisi niin, että se osaa ladata edes jotain. Ensimmäisen kartan voit luoda käsin. Tarkista, että lataus toimii kunnolla, ja tee vasta sitten karttaeditori, joka osaa tallentaa samassa muodossa.

mika132 [11.01.2011 16:19:29]

#

No mitenkäs mahtaa sitten onnistua väriintörmäys?

ja toimiiko väriintörmäys esim jos piirto tehdään tässä järjestyksessä:

Tormays_kartta (Eli alueet joihin ei pääse seinät yms värjätty)
Rata (Rata itse)

eli siis silloinhan Tormays_kartta jäsii piiloon, mutta toimiiko se silti taustalla? Ja miten se tarkistus oikein tehdään, että onko x,y akselit tietyssä värissä.

Lebe80 [11.01.2011 18:46:07]

#

huh huh taas mitä suunnittelua.

Hieman kannattaa opetella etukäteen, ennen kuin edes rupeat koko karttaeditoria tekemään.

Eli tee ihan pieniä testejä aluks, jossa testailet eri tekniikoita. Eli teet vaan pienen pieniä ohjelmia, jotka vaikka tulostavat ruudulle, kun kokeilet "törmäyskarttoja" ja tiedostoon tallennusta. Kun perusasiat ovat kunnossa, rupeat vasta vääntämään mitään oikeaa juttua.

Sikäli mikäli olen yhtään kartalla (heh! kartalla! tajusitko) niin koko törmäyskarttaa ei ole edes pakko piirtää mihinkään, vaan voit säilyttää sitä ihan "piilossa" muistissa. Kartan tekniikkakin riippuu hyvinkin paljon siitä, millaista peliä olet tekemässä, elikkäs yksinkertaisimpia karttaformaatteja on "ruutupohjaiset" (tilebased maps) kartat, joita voisi verrata ruutupaperiin. Jokaiseen ruutupaperin ruutuun voi piirtää yhdenlaisen määreen, esim. seinä, lattia, kivi, nurmi, vettä yms.

Esimerkin näet tässä:
http://www.youtube.com/watch?v=QvOoULhh5o0#t­=2m0s

Vaikka ruutupohjainen muoto onkin yksinkertainen toteuttaa, sillä voi toteuttaa upeitakin karttoja kuten Bitmap Brotherssin luomassa God -pelissä (luomassa! jumala luo! hehehe)
http://www.stickhead.pwp.blueyonder.co.uk/top50/gods2.png

Ruutupohjaisuus ei tietenkään tarkoita, että ruutujen pitää olla juuri neliöitä, vaan "ruutu" voi olla myös vaikkapa hexagonin muotoinen tai vaikkapa 3d-kuutio.


Tietenkin, kun osaamisesi edistyy, voit luoda karttoja, joissa on useita ruutupohjaisia karttoja päällekkäin, tai karttoja, jotka tukevat eri kokoisia ruutuja tai jopa asioita, joita ruutupohjaisuus ei koske.

mika132 [11.01.2011 19:26:43]

#

Juu tuota olen käyttänyt tilemappi systeemiä aikoinaan RPG MAkerin sekä CoolBasicin kanssa.

Mutta jo en käytä mitään tilemap juttua vaan piirrän vaikka paintilla suoraan kaksi kuvaa joista toisee on värjätty seinä kohdat ja toiseen rata, niin miten voin tarkistaa koska auto on törmäys alueella? Siis esim värin avulla.

Metabolix [11.01.2011 19:30:28]

#

Lue se väri auton kohdalta (sopiva funktio on jo joskus annettu) ja tarkista, mitä tuli. Jos luet ratakuvasta, tarkista, että ei tullut seinäväriä, ja jos luet seinäkuvasta, tarkista, että tuli rataväriä.

Helpompi ja tehokkaampi ratkaisu olisi piirtää yksi kuva, jossa on ruudulle tuleva kuva, ja toinen, jossa on täysin mustalla seinät ja täysin valkoisella rata. Jos olet tosi fiksu, arvaat itsekin, kummasta kuvasta ja millaisella if-lauseella se törmääminen tarkistetaan.

Bonusvinkki: Kannattaa tarkistaa se seinä jo ennen liikutusta ja törmäystilanteessa jättää liikkumatta. Muuten auto joutuu seinän sisään eikä välttämättä voi edes pakittaa sieltä pois.

jalski [11.01.2011 20:30:44]

#

Metabolix kirjoitti:

Bonusvinkki: Kannattaa tarkistaa se seinä jo ennen liikutusta ja törmäystilanteessa jättää liikkumatta. Muuten auto joutuu seinän sisään eikä välttämättä voi edes pakittaa sieltä pois.

Tuon bonusvinkin huono puoli on se, että auton liikkuessa lujaa se todennäköisesti liikkuu ruudulla useamman pikselin kerrallansa. Jos törmäystesti tehdään tässä tapauksessa ennen liikutusta, niin auto luulee törmänneensä esteeseen liian aikaisin.

Perinteinen tapa taitaa olla se, että liikutaan ja sitten tarkistetaan objektin törmäyspisteiden avulla ollaanko osuttu ja tarvittaessa peruutetaan esim. puoli pikseliä kerrallansa pois esteen sisältä, kunnes ei enää osuta esteeseen.

Metabolix [11.01.2011 20:45:52]

#

jalski: Ajatuksenani oli vain antaa helpoin mahdollinen vastaus kysymykseen, joka hyvin todennäköisesti tulee heti, kun tuo törmäystarkistus toimii. Kysyjän koodaustaidot huomioon ottaen kannattanee toistaiseksi jättää käsittelemättä sellaiset vaikeat asiat kuin "silmukka" ja "laskeminen". Kunhan nyt saisi edes luettua oikeasta kuvasta oikean pikselin ja verrattua sitä oikeaan arvoon; edellinen yritys ei mennyt ihan nappiin.

jalski [11.01.2011 22:07:23]

#

Metabolix kirjoitti:

jalski: Ajatuksenani oli vain antaa helpoin mahdollinen vastaus kysymykseen, joka hyvin todennäköisesti tulee heti, kun tuo törmäystarkistus toimii.

Ymmärrän tuon kyllä. Omana ajatuksenani oli vain saada kysyjä itse hiukan pohtimaan asioita ja antaa miettimisen aihetta.

Alla Hollywood esimerkki simppelistä tasohyppelyn "mario-luokasta". Autopelissä törmäyspisteiden hallinta on hiukan monimutkaisempaa rotaatioiden takia, mutta idea ehkä selvinnee kuitenkin.

mario = {}
mario.x =  32 	; aloitus x - koordinaatti
mario.y = 400 + 32 	; aloitus y - koordinaatti
mario.xs = 0 	; speed
mario.vy = 0 	; velocity
mario.frame = 0 	; animaatio frame
mario.flipx = 0 	; onko sprite flipattu x-suunnassa.
mario.jumping = False 	; Hyppääkö mario?
mario.scrollx = 0		; missä mennään kartalla?
mario.scrolling = False 	; liikutetaanko mariota, vai scrollataanko karttaa?
; Seuraavana marion törmäyspisteet: cpx = x - pisteet ja cpy = y - pisteet
; Nämä löytyvät tietysti ylä-osalle, ala-osalle, vasemmalle puolelle ja oikealle puolelle.
; Ensimmäinen arvo aina normaalitila ja toinen, jos sprite on flipattu x-suunnassa.
; Arvot ovat siis siirroksia pelaajan x -ja y-koordinaatteihin (spriten keskipiste).
mario.cpx = { bottom = { -11, 9 }, top = { 21, 41}, right = { 26, 30 }, left = { -30, -28 } }
mario.cpy = { bottom = { 32, 32 }, top = { 0, 0 }, right = { -10, -17}, left = {-17, -10} }


Function mario:move()
   ; liikutetaanko mariota, vai scrollataanko karttaa?
    If mario.scrolling = False Then self.x = self.x + self.xs

    If self.x < 32 Then self.x = 32
    If self.x > 640 - 32 Then self.x = 640 - 32

    ; Kuten yleensä elämässä, niin normaali suunta on aina alaspäin...
    self.vy = self.vy + #GRAVITY
    If self.vy <> 0 Then mario.jumping = True

    self.y = self.y + self.vy

    ; Kun on liikuttu, tarkastetaan ja käsitellään törmäykset pelikentän kanssa.
    self:CheckLevelCollision()
EndFunction


; Arvaat ehkä, mitä tämä funktio tekee?
Function mario:animate()
    Local time = GetTimer(3)
    If time > 1000/6
        If self.jumping
            self.frame = 2
        ElseIf self.xs <> 0 Or mario.scrolling = True
            self.frame = self.frame + 1
            self.frame = Wrap(self.frame, 0, 2)
        Else
            self.frame = 0
        EndIf
        ResetTimer(3)
    EndIf
EndFunction


; Piirtää marion
Function mario:draw()
    Local framesy = { 0, 65, 129 } 	; animaatio framet allekkain samassa kuvassa, tässä niiden y-offsetit.
    DisplayBrushPart(9, 0, framesy[self.frame], self.x, self.y, 64, 64, {AnchorX = 0.5, AnchorY = 0.5})
EndFunction


; Tarkastaa törmäykset pelikentän kanssa
Function mario:CheckLevelCollision()
    Local col

    SelectBrush(15) 	; Törmäyskartta on brush 15, tästä luetaan pikseleitä nyt.

    ; Jos ollaan maan sisällä, niin pakitetaan.
    col = ReadPixel(self.scrollx + self.x + self.cpx.bottom[self.flipx], self.y + self.cpy.bottom[self.flipx])
    While col = #RED
        self.y = self.y - 0.5
        col = ReadPixel(self.scrollx + self.x + self.cpx.bottom[self.flipx], self.y + self.cpy.bottom[self.flipx])
    Wend

    ; Jaahas, onkohan suoraan jalkojen alapuolella maata
    col = ReadPixel(self.scrollx + self.x + self.cpx.bottom[self.flipx], self.y + self.cpy.bottom[self.flipx] + 1)
    If col = #RED
        self.vy = 0
        self.jumping = False
    EndIf

    ; Platformien läpi voi hypätä alapuolelta ylöspäin, mutta niiden läpi ei voi pudota
    If self.vy > 0
        col = ReadPixel(self.scrollx + self.x + self.cpx.bottom[self.flipx], self.y + self.cpy.bottom[self.flipx])
        While col = $26FF
            self.y = self.y - 0.5
            col = ReadPixel(self.scrollx + self.x + self.cpx.bottom[self.flipx], self.y + self.cpy.bottom[self.flipx])
        Wend

	; Näyttääkös tutulta aiemmasta kohtaa?
        col = ReadPixel(self.scrollx + self.x + self.cpx.bottom[self.flipx], self.y + self.cpy.bottom[self.flipx] + 1)
        If col = $26FF
            self.vy = 0
            self.jumping = False
        EndIf
    EndIf

    ; Pitäisiköhän vielä tarkastaa oikea puoli?
    col = ReadPixel(self.scrollx + self.x + self.cpx.right[self.flipx], self.y + self.cpy.right[self.flipx])

    While col = #RED
        self.x = self.x - 1
        col = ReadPixel(self.scrollx + self.x + self.cpx.right[self.flipx], self.y + self.cpy.right[self.flipx])
    Wend

    ; Ja vasenkin puoli voisi ehkä olla fiksua vielä tsekata?
    col = ReadPixel(self.scrollx + self.x + self.cpx.left[self.flipx], self.y + self.cpy.left[self.flipx])

    While col = #RED
        self.x = self.x + 1
        col = ReadPixel(self.scrollx + self.x + self.cpx.left[self.flipx], self.y + self.cpy.left[self.flipx])
    Wend

    EndSelect 	; Brush 15 valinta ohi, käsitellään normaalisti näyttöä tämän jälkeen.
EndFunction

mika132 [14.01.2011 15:52:50]

#

Noniiin. Tein jotain systeemiä tuohon törmäämiseen. Tallennan vectoriin törmäys neliöitä (40x40) ja tarkistan että jos niihin törmätään muutetaan auton asentoa ja liikutetaan eri suuntaan, mutta eipäs ollutkaan niin helppo juttu. Sitten otin kulman muuttamisen kokonaan pois ja yritän saada auton liikkumaan eri suuntaan törmäyksestä.

Eli jos auto törmää oikealla etukulmallaan se kääntyy enemmän vasemmalle ja taas toisin päin. Viritin tälläistä systeemiä:

while(seinaa != Game::Seinat.end()){
    if (x_oma >= seinaa->seinan_x && x_oma <= seinaa->seinan_x + seinaa->seinan_leveys) {
        if (y_oma >= seinaa->seinan_y && y_oma <= seinaa->seinan_y + seinaa->seinan_korkeus) {
            tormaa=true;
        } else {
            tormaa=false;
        }
    }
    seinaa++;
}

SDL_FreeSurface(Tekstit::text_19);
Tekstit::text_19 = Tekstit::LoadText(" ", true, nopeus_oma, Fontit::font2, 255, 0, 0);
if (!tormaa) {
    x_oma+=std::cos(kulma_oma) * nopeus_oma;
    y_oma+=std::sin(kulma_oma) * nopeus_oma;
} else {
    x_oma-=std::sin(kulma_oma) * nopeus_oma;
    y_oma+=std::cos(kulma_oma) * nopeus_oma;
}

Tuo systeemi toimii niin kauan kuin auto törmää vasemmalla etukulmallaan. Jos oikea etukulma osuu seinään menee auto seinästä läpi lujaa.

Olisikos mitään pikku vinkkejä?

jimi-kimi [14.01.2011 18:15:31]

#

Mikä tässä mun koodissa on vikana?

if (this->var_X > this->varY != this->varX < this->varY)
  varX = 1;
else
  varY = 0;


var_X++;
..... --> lisää random koodia

EDIT: http://lmgtfy.com/?q=polygon collision detection


Toinen EDIT:
Jos viitsisit edes yrittää keksiä mielekkäitä kysymyksiä. Omat yrityksesi ovat niin alkeellisia, että rupesin miettimään ymmärrätkö alkuunkaan koodiasi? Lainaa huvikseen jostain Päivi Hietasen C++ olio-ohjelmointi tai vastaava ja sisäistä kirja.

Metabolix [14.01.2011 18:34:07]

#

Yritäpä nyt ensin tehdä niin, että auto edes pysähtyy seinään.


Sivun alkuun

Vastaus

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

Tietoa sivustosta