Tilekartta editori Coolbasicilla

Voit pyytää apua ohjelmointiongelmiin täältä.
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Tilekartta editori Coolbasicilla

Post by MrMonday »

Hei, olisin tekemässä yksinkertaista tilekartta editoria cb:llä lähinnä harjoituksena, ja tarvitsisin viisaampien neuvoja.
esmes. miten koodin rakenne olisi järkevintä/selkeintä toteuttaa, muita huomioitavia asioita, vinkkejä eri osien toteuttamisesta, yms, yms..
ja cb:ssä on aika paljon valmiita komentoja karttoihinkin liittyen, joten en näkisi tätä liian isona palasena minuntasoiselleni koodarille (en siis ole hyvä, mutten ihan huonokaan)
Eli en pyydä valmista koodia, jossa näytetään miten editori tehdään, vaan korkeintaan pieniä pätkiä, mitkä helpottavat asioiden hahmottamista ja ymmärtämistä, mutta yleisesti siis vinkkejä,
joista editorin väkertämisessä saattaisi olla hyötyä. ja toteutus nimenomaan cbllä ja karttakomennoilla..

Toivottavasti tämä ei kuulosta kovin typerältä idealta, mutta rehellisiä kommentteja ko. projektista vastaanotetaan mielellään :)

Kiitos kaikille jo etukäteen ja katsotaan mitä tästäkin tulee :lol:
Nassi_Setä
Advanced Member
Posts: 281
Joined: Sat Jun 28, 2008 5:19 pm
Location: Hämeessä miä

Re: Tilekartta editori Coolbasicilla

Post by Nassi_Setä »

Ainakin jotain tietoa tilekartoista on Tilesterin manuaalissa, eli kannattaa kattoa
\../(-_-)\../ <---klick MyBrute Image
Jotain evilii on tekeillä....
temu92
Web Developer
Web Developer
Posts: 1226
Joined: Mon Aug 27, 2007 9:56 pm
Location: Gamindustri
Contact:

Re: Tilekartta editori Coolbasicilla

Post by temu92 »

Onhan Astigman A Stigmator tehty kokonaan Coolbasicilla :P

Muistaakseni jostakin syystä kuitenkin taisi olla niin että Tilesterin mukana tulevassa tilemappiformaattidokumentoinnissa on jotkin alkutarkistusnumerot väärin merkitty, muista sitten mitä niiden piti olla. Itsekin joskus tehnyt saman tyylistä systeemiä, mutta mitään varsinaista editoria en valmiiks ole saanut :e
User avatar
Misthema
Advanced Member
Posts: 312
Joined: Mon Aug 27, 2007 8:32 pm
Location: Turku, Finland
Contact:

Re: Tilekartta editori Coolbasicilla

Post by Misthema »

Hmm... Tietysti voisit unohtaa kokonaan CB:n karttaformaatin ja ohjelmoida oman sellaisen.

Teet aluksi esimerkiksi yksinkertaisen taulukon tai tyyppi-listan jossa on kaikki tarpeellinen:
- X- ja Y-koordinaatti tilelle. Tämä on laskettava pikseleissä, mutta asiaa helpottaa pikseleiden jakaminen ja kertominen tilen leveydellä/korkeudella, esim:

Code: Select all

tile_x = pixel_x / tile_width
tile_y = pixel_y / tile_height
Esimerkki 32x32 kokoisella tilellä:

Code: Select all

'Annetaan arvot muuttujille:
pixel_x = 32
pixel_y = 64
tile_width = 32
tile_height = 32

'Lasketaan tilen paikka ruudulla:
tile_x = pixel_x / tile_width
tile_y = pixel_y / tile_height
Tuloksina tässä tapauksessa olisi:
tile_x = 1
tile_y = 2

Eli tile piirtyisi ruudulle kohtaan 1,2 kuten kuvassa näkyy:
Image

Piirtäessä tileä oikeaan paikkaan on taas laskettava samalla tavalla, mutta päinvastoin; tällä kertaa haetaan paikka pikseleinä, eli:

Code: Select all

'Jälleen arvoja muuttujille:
tile_x = 1
tile_y = 2
tile_width = 32
tile_height = 32

'Laskutoimitus:
x = tile_x * tile_width //=32 pikseliä
y = tile_y * tile_height //=64 pikseliä

'Piirretään tile:
DrawImage tile, x, y
Tällöin tile tulee täsmälleen samaan kohtaan kuin aikaisemmassa kuvassa näkyi.
Tälle on tietysti järkevä tehdä funktio, joka hoitaa piirtämisen ja laskutoimitukset samassa syssyssä.


- Index-luku tilelle, joka kertoo mitä tileä piirretään. Esimerkki:
Image

Tämä taas auttaa valitsemaan piirtotilen, joten tiedämme mitä ruudulle piirretään.
Tämä toteutuu samanlaisella laskutoimituksella kuin X- ja Y-koordinaateissa,
mutta tällä kertaa tarvitsemme taulukon johon tilet tallennetaan ja josta ne on helppo kaivaa:

Code: Select all

'Luodaan taulukko piirtotileille:
Dim tiles(3) //3 siksi, koska esimerkkikuvassa on vain 4 tileä ja taulukko alkaa nollasta (0->3 = 4).

'Ladataan tilesetti:
tileset = LoadImage("tileset.bmp")

'Luodaan väliaikainen kuvapuskuri tilelle...
temp_tile = MakeImage(tile_width, tile_height)
'...ja haetaan tilet 'tileset' -kuvamuuttujasta taulukkoon:
For i=0 To 3
    For tile_x=0 To ImageWidth(tileset) Step 32
        For tile_y=0 To ImageHeight(tileset) Step 32
            DrawToImage temp_tile 'Määritetään piirtopuskuri 'temp_tile' kuvaan
            //X- ja Y-koordinaatteihin siksi nollat, jotta tile tulee kuvaan oikein
            DrawImageBox tileset, 0, 0, tile_x, tile_y, tile_width, tile_height
            DrawToScreen 'Palataan takaisin oletuspiirtopuskuriin
            tiles(i) = temp_tile 'Heitetään haettu tile oikeaan slottiinsa
        Next tile_y
    Next tile_x
Next i

'Piirretään tilet rivikkäin:
For i=0 To 3
    DrawImage tiles(i), i*tile_width, 0
Next i
Näinkin yksinkertaista. =)
(En kyllä kokeillut kirjoittamiani koodinpätkiä, vaan kirjoitin ne suoraan tähän, jotenka toimivuudesta en takaa mitään)

Toivottavasti näistä oli jotain apua alkuun! Kysy toki lisää jos jokin jäi askarruttamaan.
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Re: Tilekartta editori Coolbasicilla

Post by MrMonday »

Misthema wrote: ..tekstiä..
Jups, kiitos paljon avusta, täytyy vielä hieman harjoitella enemmän tyyppejä ja taulukoita, mutta kyllä se tästä vielä lähtee ;)
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Re: Tilekartta editori Coolbasicilla

Post by MrMonday »

Aloitin tuota tilekartta editoria väsäämään, ja sen väsääminen oli yhtä tuskaa, jonka jälkeen koko projekti sitten jäikin..
Mutta muutama päivä sitten päätin aloittaa alusta, ja nyt olenkin jo jotain pientä saanutkin aikaan :)

Eli editorissa pystyy nyt valitsemaan tilen ja asettamaan sen kartalle ja myös "maalaamaan" valitulla tilellä, kun hiireä pidetään pohjassa.
Myöskin (lähes) toimivan hakemiston olen saanut väsättyä, jossa hiirellä haetaan haluttu tilesetti.
Tuetut kuvat värjääntyy, mikä helpottaa niiden hakemista, kuten myös kansiot värjäytyvät omalla värillään tiedostojen etsimisen helpottamiseksi.
Kaikki on toteutettu ERITTÄIN karusti, eli mitään valikoita tai käyttöliittymää ei vielä ole ollenkaan.
Nyt työn alla onkin kartan latauksen ja tallennuksen tekeminen, ja voi prkl miten olenkaan tämän projektin kanssa tuskaillut ja kärsinyt, mutta toivottavasti saan tämän vielä päätökseen :)

Lisäksi olen luopunut CB:n sisäänrakennetusta karttaformaatista täysin, ja yritän tehdä hieman paremman systeemin, mutta nähtäväksi jää..

Ja jos joku olisi kiinnostunut lähtemään mukaan, niin apua otan enemmän kuin mielelläni vastaan :D

Yritän saada edes jonkinlaisen alkeellisen viritelmän aikaiseksi, jotta voin sen sitten täällä jakaa kaikkien ihmeteltäväksi.
User avatar
Jonez
Devoted Member
Posts: 575
Joined: Mon Aug 27, 2007 8:37 pm

Re: Tilekartta editori Coolbasicilla

Post by Jonez »

MrMonday wrote:Lisäksi olen luopunut CB:n sisäänrakennetusta karttaformaatista täysin, ja yritän tehdä hieman paremman systeemin, mutta nähtäväksi jää..
Tämä ei välttämättä ole järkevää, koska cb:llä tuskin saat koodattua nopeampaa systeemiä kuin se sisäänrakennettu. Ideaalitapaushan olisi, jos antaisit käyttäjälle mahdollisuuden tallentaa kartat omaan formaattiin. Näin editorilla pystyisi teoriassa luoda tilekarttoja kaikkiin maailman peleihin jotka tilekarttoja käyttävät, kuten esim. Tapan Kaikki-peliin, mihin vain cb:n tilemoottoria käyttävään peliin, tai sitten johonkin omatekemääsi.

Tietääkseni esim. Tilesterillä tämä on mahdollista.
-Vuoden 2008 aloittelijan ystävä -palkinnon voittaja-
Image <- protestipelikilpailun voittaja.
Space War
User avatar
skinkken
Advanced Member
Posts: 453
Joined: Sat Sep 01, 2007 4:00 pm
Location: Helsinki

Re: Tilekartta editori Coolbasicilla

Post by skinkken »

Tein joskus johonkin projuun (joka on jäätynyt) puoliksi oman karttaformaatin (jotta voisi tehdä oma editorin). Omalla editorilla tallensin vain x:n y:n ja tiletyypin. karttaa ladatessa avataan joku tyhjä kartta,johon sitten editmapilla laitetaan tilet tiedostosta. Sitäpaitsi näyttää paljon hienommalta kun on oma formaatti :)
Valmiit pelit: House of Horrors , Battle Zone , Über Ball , Itdoti , Space Chaos , Bloxxplosives
Projekti jota teen ehkä joskus vielä: viewtopic.php?f=11&t=2636 <-- Tämä rivi päivitetty 14.1.2013
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Re: Tilekartta editori Coolbasicilla

Post by MrMonday »

Huh, yritin tätäkin projektia tässä sulatella, mutta muutoinkin jäänyt koodailu vähemmälle, niin en päässyt alkua pidemmälle :roll:
Eli pitäisi saada tuo kartan tallennus/lataus systeemi väsättyä, ja jotain pientä räpellystä olen taulukoiden kanssa saanut aikaan,
mutta mitään toimivaa ja järkevää ratkaisua en ole löytänyt. Jotenkin kai ongelmia hahmottaa systeemin rakenne, koska päässä se tuntuu olevan ihan selvää,
mutta kun pääsee editoriin, niin eipä enää olekkaan. Joten voisiko joku tehdä pienen esimerkin, miten tallennetaan esim 10*10 ruudukko (tilekartta)
tiedostoon, jossa jokaisella tilellä on oma X- ja Y-koordinaatti, sekä vaikka kaksi "kerrosta" esim. 0 ja 1 eli siis tiedostoon pitäisi saada joka tilelle oma X,Y ja Kerros.

Käsittääkseni ne olisi helpointa ajon aikana, karttaa rakentaessa/muokatessa tallentaa taulukkoon, josta sitten tiedostoon,
mutta näinkin selvän asian toteuttamisessa minulla menee aivot ihan solmuun. Lyhyt esimerkki tallennuksesta ja latauksesta selvittäisi varmasti systeemin rakenteen minullekkin :)

Kiitos jo etukäteen, toivattavasti jollain on pieni koodaus-nälkä, jotta saisin apua ongelmaani :D
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Re: Tilekartta editori Coolbasicilla

Post by JATothrim »

15min ajassa räpelletty vastaus:
Ja ne joka epäilevät että CB:llä ei ole mahdollista tehdä nopeaa tilekartta moottoria menkööt optimoimaan koodiaan. (etsikää esimerkeistä BigImagelib tai vain click)
Sinun täytyy kasata kartta formaattisi määritykset ja tiedot, eli kuinka kartta tallennetaan tiedostoon. Ota huomioon seuraavat seikat:
-Kuinka luen tiedostosta karttadatan nopeasti?
-Missä järjestyksessä data on kirjoitettava?
-Onko karttatiedosto ns. selkokielinen? (vs. raakadata tiedosto)
-Mitä oikeastaan karttatiedoston täytyy pitää sisällään? Jaottele tallennettavaa dataa tyyliin: asetukset, data, data. asetukset, data. Esim. kartan leveys ja korkeus kuuluvat asetuksiin, mutta taas yhden tilen indeksi numero kuuluu dataan. Tiedostoissa on yleensä ns. header joka kertoo/johdattelee mitä tiedosto sisältää: Esim. "kerroksia on 2", "kartan korkeus on 100", "kerroksen x data alkaa kohdasta y"
(time's up, meen tunnille) :P
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Re: Tilekartta editori Coolbasicilla

Post by MrMonday »

Kiitos JATothrim, mutta tuo ei ollut ihan se mitä hain, joten tarkennan hieman edellistä viestiäni, kun sen voi näköjään käsittää useammalla tavalla :lol:

Eli tarkoitin tilannetta, jossa hiirellä asetetaan valittua tileä karttaan (se siis on jo valmiina)
ja siitä saadaan välitettyä tiedot taulukkoon, että mistä kohtaa tilesettiä on tuotu palikka mihinkin kohtaan karttaa.

Alla selvennys-kuva.
10 X 10.png
Eli oletetaan että otan tilen tilesetistä (tile)koordinaateista X 5 ja Y 9, ja asetan ne karttaan (Yllä olevaan kuvaan) koordinaatteihin X 2 ja Y 8 (Ja kartta on siis taulukossa)
Niin miten saan taulukon Tile_X() sijaintiin X 2 sijoitettua tilen ottokoordinaatin (X 5) ja taulukon Tile_Y() sijaintiin Y 8 sijoitettua tilen ottokoordinaatin (Y 9), josta voin ne sitten tallentaa tiedostoon.

Oliko tarpeeksi epäselvää :P

Ja nuo kerrokset voi vielä toistaiseksi jättää pois, koska jos tämän systeemin saan väsättyä, niin on kerrosten lisääminen silloin ihan yhtä helppoa.

Niin ja kannattaisiko taulukot tile_x() ja tile_y() sulattaa yhdeksi taulukoksi?

Ensi kerralla taidan pistää koodinpätkää tulemaan jos kukaan ei muuten saa selityksistäni selvää :lol:
SPuntte
Tech Developer
Tech Developer
Posts: 650
Joined: Mon Aug 27, 2007 9:51 pm
Location: Helsinki, Finland
Contact:

Re: Tilekartta editori Coolbasicilla

Post by SPuntte »

Ei ole järkeä tallentaa kahta erillistä "tileset-koordinaattia" karttatileä kohti, kun asia hoituu yksikäsitteisesti yhdelläkin luvulla. Kutsukaamme tätä lukua vaikkapa tileindeksiksi. Tileindeksi lasketaan x-ja y-koordinaateista seuraavasti seuraavasti: i = x + sarakemäärä*(y-1), kun tilesetin ylin rivi vastaa y-koordinaattia 1.

Vastaavasti indeksin "purku" x- ja y-tilesetkoordinaateiksi tapahtuu seuraavasti:
x = i Mod sarakemäärä
y = RoundUp(i/sarakemäärä)
TAI
y = (i - x)/sarakemärä

Edellä kuvatuilla kaavoilla indeksi saa arvoja ykkösestä eteenpäin arvoon rivimäärä*sarakemäärä asti. Mikäli halutaan, että ensimmäinen indeksi on 0, täytyy x- ja y-koordinaatteja i:ksi muunnetaessa lausekkeesta vielä vähentää luku 1 ja palautuskaavoissa vastaavasti korvata i lausekkeella (i + 1).

Idea siis on, että tilesetin ruudut numeroidaan riveittäin vasemmalta oikealle. Esimerkkinä 4*5-tilesetin indeksointi:

Code: Select all

-------------
| 1| 2| 3| 4|
-------------
| 5| 6| 7| 8|
-------------
| 9|10|11|12|
-------------
|13|14|15|16|
-------------
|17|18|19|20|
-------------
P.S. En takaa että yllä mainitsemani laskukaavat ovat täysin oikein, sillä muodostin ne lähinnä päässä ilman sen suurempaa testaamista. Periaate niistä kuitenkin selvinnee.
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES

CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Re: Tilekartta editori Coolbasicilla

Post by MrMonday »

Nyt ollaan tultu siihen pisteeseen, että minulla ei enää järki riitä, joten pyydän teiltä mitä nöyrimmin apua tämän onnettoman projektini kanssa..
Alla on siis oleellinen osa koko systeemistä, josta olen karsinut tilesetin latauksen ja kartan määrittelyn ajossa, ym. ei niin tärkeän, silti koodi on aika hirveän näköistä,
eikä kommentointia ole, mutta kannattaa ajaa tämä pätkä editorissa, niin hahmottaa varmasti paremmin koodin toiminnan, eikä koodia kovin montaa riviä edes ole.

Näppäimet ovat seuraavat:

Hiiren vasen - Poimii sekä asettaa tilen
Hiiren oikea - Vaihdetaan tilenpoiminta tilasta tilenasetus tilaan ja toisinpäin

Space - Tallentaa kartan
Enter - Lataa kartan

Ongelma on seuraava:

Kun kartan tallentaa ja sen jälkeen lataa sen takaisin, on tilet ihan sekaisin.
Eli ongelma aiheutuu mitä luultavammin siitä, että tiedot kirjoitetaan tai ne luetaan tiedostoon/tiedostosta väärin,
tai sitten ne merkitään jo tileä asetettaessa väärin taulukkoon, tai sitten kaikki näistä on päin...

Joten jos joku osaavampi voisi näyttää että miten homma hoituisi oikeaoppisesti, niin olisin erittäin kiitollinen :D

ps. älkääkä sitten naureskelko koodilleni, en vain ole vielä mikään mestari tässä lajissa :lol:

Ja sitten itse koodi..

Code: Select all

Vanhaa  koodia..
Last edited by MrMonday on Mon Mar 26, 2012 12:11 am, edited 1 time in total.
User avatar
MetalRain
Active Member
Posts: 188
Joined: Sun Mar 21, 2010 11:17 am
Location: Espoo

Re: Tilekartta editori Coolbasicilla

Post by MetalRain »

Jotain vinkkejä kartan lataamiseen oikein voitte saada Valtzun multimap systeemistä:

Code: Select all

//----------------------------------------//
//  MultiMapSystem by Valtzu (9.7.2007)  //
//----------------------------------------//


//Esimerkki

SCREEN 800,600

// Ladataan kartat muistiin
map1 = LoadMapToMem("Media\cdm2.til","Media\tileset.bmp")
map2 = LoadMapToMem("Media\testmap.til","Media\tileset.bmp")

// Ladataan ukko
ukko = LoadObject ("Media\guy.bmp",72)

AddText "Arrows to move, space to change map"


Repeat
    If KeyHit(cbkeyspace) Or kartta=0 Then
        kumpiKartta = Not kumpiKartta // 0=>1,1=>0

        // Vaihdetaan karttaa
        If kumpiKartta Then kartta=UseMap(map1,kartta) Else kartta=UseMap(map2,kartta)

        // Kartta sisältää animoituja tilejä, joten karttaobjekti pitää animoida
        PlayObject kartta,0,0,1

        // Jokaisen kartan vaihdon jälkeen pitää asettaa törmäykset uudestaan
        SetupCollision ukko, kartta, 1, 4, 2
    EndIf

    // Ukon ohjaus
    If LeftKey() Then TurnObject ukko,5
    If RightKey() Then TurnObject ukko,-5
    If UpKey() Then MoveObject ukko,2
    If DownKey() Then MoveObject ukko,-2

    UpdateGame

    CloneCameraPosition ukko

    DrawScreen

Forever


// ---- Funktiot ---- //

// Tämä funktio lataa kartan muistiin. Parametreina tilemapin tiedostopolku
// ja tilesetin tiedostopolku tai valmiiksi LoadImagella ladattu kuva
Function LoadMapToMem(_tilemap$,_tileset$)
    If Int(_tileset)=0 Then tileset=LoadImage(_tileset) Else tileset=Int(_tileset)
    f=OpenToRead(_tilemap)
        tmpMem=MakeMEMBlock(8)
        PokeByte tmpMem,0, 23
        PokeByte tmpMem,1, 40
        PokeByte tmpMem,2, 179
        PokeByte tmpMem,3,192
        PokeByte tmpMem,4,243
        PokeByte tmpMem,5,13
        PokeByte tmpMem,6,56
        PokeByte tmpMem,7,139
        For i = 0 To 3
            a=ReadByte(f)
            If a <> PeekByte(tmpMem,i*2) And a <> PeekByte(tmpMem,i*2+1) Then virhe=1:Exit
        Next i
        versio# = ReadFloat(f)
        If virhe Or versio <= 0.0 Or versio > 2.0 Then MakeError("Error! Invalid tilemap.")
        For i=1 To 128
            a=ReadInt(f)
        Next i
        maskr=ReadByte(f):maskg=ReadByte(f):maskb=ReadByte(f)
        For i=1 To 297
            a=ReadByte(f)
        Next i
        tileja=ReadInt(f)
        tileleveys=ReadInt(f)
        tilekorkeus=ReadInt(f)
        mapleveys=ReadInt(f)
        mapkorkeus=ReadInt(f)
        mapMem=MakeMEMBlock(27+(mapleveys*mapkorkeus*2*4)+(tileja*8))
        PokeInt mapMem,0, tileja
        PokeInt mapMem,4, tileleveys
        PokeInt mapMem,8, tilekorkeus
        PokeInt mapMem,12,mapleveys
        PokeInt mapMem,16,mapkorkeus
        PokeInt mapMem,20,tileset
        PokeByte tmpMem,0, 254
        PokeByte tmpMem,1, 45
        PokeByte tmpMem,2, 12
        PokeByte tmpMem,3,166
        offset=24
        For kerros=0 To 3
            If ReadByte(f) <> PeekByte(tmpMem,0) Or ReadByte(f) <> PeekByte(tmpMem,1) Or ReadByte(f) <> PeekByte(tmpMem,2) Or ReadByte(f) <> PeekByte(tmpMem,3) Then MakeError("Error! Invalid tilemap.")
            For y=1 To mapkorkeus
              For x=1 To mapleveys
                  PokeShort mapMem,offset,ReadInt(f):offset+2
              Next x
            Next y
            For i=0 To 3
                PokeByte tmpMem,i,PeekByte(tmpMem,i)-1
            Next i
        Next kerros
        If ReadByte(f) <> PeekByte(tmpMem,0) Or ReadByte(f) <> PeekByte(tmpMem,1) Or ReadByte(f) <> PeekByte(tmpMem,2) Or ReadByte(f) <> PeekByte(tmpMem,3) Then MakeError("Error! Invalid tilemap.")
        For tile=1 To tileja
            PokeInt mapMem,offset,ReadInt(f):offset+4
            PokeInt mapMem,offset,ReadInt(f):offset+4
        Next tile
        PokeByte mapMem,offset,maskr:offset+1
        PokeByte mapMem,offset,maskg:offset+1
        PokeByte mapMem,offset,maskb:offset+1
    CloseFile f
    DeleteMEMBlock tmpMem
    Return mapMem
End Function


// UseMap()-funktio asettaa LoadMapToMem()-funktiolla ladatun kartan käyttöön.
// Toiseksi parametriksi syötetään viimeksi käytetty karttaobjekti
Function UseMap(mapMem,oldMap=0)
    If oldMap Then DeleteObject oldMap
    tileja=PeekInt(mapMem,0)
    tileleveys=PeekInt(mapMem,4)
    tilekorkeus=PeekInt(mapMem,8)
    mapleveys=PeekInt(mapMem,12)
    mapkorkeus=PeekInt(mapMem,16)
    tileset=PeekInt(mapMem,20)
    objMap=MakeMap(mapleveys,mapkorkeus,tileleveys,tilekorkeus)
    offset=24
    For kerros=0 To 3
        kerros2=kerros
        If kerros = 1 Then kerros2 = 2
        If kerros = 2 Then kerros2 = 1
        For y=1 To mapkorkeus
          For x=1 To mapleveys
              EditMap objMap,kerros2,x,y,Int(PeekShort(mapMem,offset)):offset+2
          Next x
        Next y
    Next kerros
    For tile=1 To tileja
        pituus=PeekInt(mapMem,offset):offset+4
        hitaus=PeekInt(mapMem,offset):offset+4
        SetTile tile,pituus,hitaus
    Next tile
    PaintObject objMap,tileset
    r=PeekByte(mapMem,offset):offset+1
    g=PeekByte(mapMem,offset):offset+1
    b=PeekByte(mapMem,offset):offset+1
    MaskObject objMap,r,g,b
    ObjectOrder objMap,-1
    Return objMap
End Function

// Poistaa LoadMapToMem()-funktiolla ladatun kartan muistista.
// Tämän käyttö ei ole välttämätöntä
Function DeleteMapFromMem(mapMem)
    DeleteMEMBlock mapMem
End Function
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Re: Tilekartta editori Coolbasicilla

Post by MrMonday »

Hei taas, aloitin illalla jatkamaan tätä projektia, mikä on ollut jo ikuisuuden syväjäässä, eli käytännössä aloitin täysin puhtaalta pöydältä koodaamaan. Tällä kertaa projekti on lähtenyt kohtalaisen kivuttomasti käyntiin, mutta yksi ongelma ei lukuisista erilaisista yrityksistä huolimatta katoa. Eli kartan tallennus sujuu aivan kuten kuuluukin, mutta lataus, tai oikeammin kartan piirto taulukkoon ladatuista tiedoista ei ota onnistuakseen. Koodi selventänee asiaa;

Code: Select all


    SCREEN 320,320

    tile_width  = 32
    tile_height = 32

    map_width   = 10
    map_height  = 10

    map_size    = map_width*map_height

    tileset     = LoadImage("tileset.png")
    map_image   = MakeImage(map_width*tile_width,map_height*tile_height)

    Dim TILEMAP(map_size-1)

    DropTile_mode:
        
        ClearMouse
        
    Repeat
    
        DrawImage map_image,0,0
        
        DrawGame
    
        If g < 1    Then gp = 1
        If g > 254  Then gp = 0

            Color 255,g,0
    
        If gp = 1   Then g = g + 1
        If gp = 0   Then g = g - 1
        
        Box tile_width*(MouseX()/tile_width),tile_height*(MouseY()/tile_height),tile_width,tile_height,0
            
            If KeyHit(59) Then Goto Load_Map
            If KeyHit(60) Then Gosub Save_Map
        
        If MouseDown(1)
            
            drop_x = (MouseX()/tile_width)
            drop_y = (MouseY()/tile_height)
                        
            drop_slot = ((map_width*drop_y)+drop_x)
                        
            TILEMAP(drop_slot) = pick_slot
                        
            DrawToImage map_image
                CopyBox pick_x*tile_width, pick_y*tile_height, tile_width, tile_height, drop_x*tile_width, drop_y*tile_height, Image(tileset), Image(map_image)
            DrawToScreen   
            
        ElseIf MouseHit(2)
            Goto PickTile_mode
        EndIf
        
        DrawScreen
        
    Until KeyHit(1)
    
    End

    PickTile_mode:
        
        ClearMouse
    
    Repeat
    
        DrawImage tileset,0,0
    
        DrawGame

        If g < 1    Then gp = 1
        If g > 254  Then gp = 0

            Color 255,g,0
    
        If gp = 1   Then g = g + 1
        If gp = 0   Then g = g - 1
        
        Box tile_width*(MouseX()/tile_width),tile_height*(MouseY()/tile_height),tile_width,tile_height,0
        
            If KeyHit(59) Then Goto Load_Map
            If KeyHit(60) Then Gosub Save_Map
        
        If MouseHit(1) Then
        
            pick_x = ((tile_width*(MouseX()/tile_width))/tile_width)
            pick_y = ((tile_height*(MouseY()/tile_height))/tile_height)
            
            pick_slot = (((ImageWidth(tileset)/tile_width)*pick_y)+pick_x)+1
            
        ElseIf MouseHit(2) Then
            Goto DropTile_mode
        EndIf
        
        DrawScreen
        
    Until KeyHit(1)
    
    End
    
    Save_Map:
    
            Color 255,0,0    
        
            AddText "Saving map..."
            DrawScreen
        
        map_file = OpenToWrite("map.dat")

            WriteLine map_file, map_size
    
            WriteLine map_file, tile_width
            WriteLine map_file, tile_height
            
            WriteLine map_file, map_width
            WriteLine map_file, map_height
            
            For i = 0 To map_size-1
                WriteLine map_file, TILEMAP(i)
            Next i

        CloseFile map_file
        
            ClearText
        
    Return
    
    Load_Map:
        
            Color 255,0,0
            
            AddText "loading map..."
            DrawScreen
    
        map_file = OpenToRead("map.dat")
    
            map_size    = ReadLine(map_file)
    
            tile_width  = ReadLine(map_file)
            tile_height = ReadLine(map_file)
            
            map_width   = ReadLine(map_file)
            map_height  = ReadLine(map_file)

            ReDim TILEMAP(map_size-1)

            For i = 0 To map_size-1
                TILEMAP(i) = ReadLine(map_file)
            Next i
            
        CloseFile map_file
        
            ClearText
        
    Goto DrawMap
    
    DrawMap:
        
        DrawToImage map_image
            
            For i = 0 To map_size-1
            
                Pick_x  = TILEMAP(i) Mod map_height
                Pick_y  = RoundUp(TILEMAP(i)/map_height)

                CopyBox pick_x*tile_width, pick_y*tile_height, tile_width, tile_height, drop_x*tile_width, drop_y*tile_height, Image(tileset), Image(map_image)

            Next i

        DrawToScreen
        
    Goto DropTile_mode
    
Eli ongelma löytyy lopusta, riviltä 160 alaspäin. Kartta tallennetaan selkokielisenä, jotta voitte tutkia myös sitä. Kiitos kaikille avusta jo etukäteen :)

Ja jos ette jaksa koodin seasta kaivella, niin:
Hiiren vasen - Valitsee/asettaa tilen.
Hiiren oikea - Vaihtaa tilen valinta/asetus ikkunoiden välillä.
F1 - Lataa kartan.
F2 - Tallentaa kartan.

Ja tileset vielä mukaan.
testi-tileset
testi-tileset
tileset.png (477 Bytes) Viewed 16084 times
User avatar
Konstaduck
Advanced Member
Posts: 267
Joined: Sat Dec 17, 2011 3:09 pm
Location: Nurmijärvi, Finland
Contact:

Re: Tilekartta editori Coolbasicilla

Post by Konstaduck »

Hienoltahan tuo näytti, ei vain pitäisi mennä painamaan sitä F1:köstä ennen kuin on tallentanut :lol:

En itse tuota ongelmaa osaa ratkaista :(

Vielä kun saisit tallenettua nuo kartat vaikka .til muotoon, niin niitä voisi käyttää jo peleissä.

Tuostahan saisi jo hyän editorin TileGen:nin, A Stigmator:in ja Tilester:in rinnalle.
EDIT:

Oho o_O Se lataus olikin tuo ongelma :D

Konstaduck.net
<Ize> Pitäs tehä allekirjotus..
<Ize> Vois keksiä jonkin nasahtavan sanonnan..
<Ize> Siitä tulis upea legenda ja kaikki vaihtaisivat allekirjoituksensa siihen.
<Ize> Ehkä ei kuitenkaa...
User avatar
Jonez
Devoted Member
Posts: 575
Joined: Mon Aug 27, 2007 8:37 pm

Re: Tilekartta editori Coolbasicilla

Post by Jonez »

DrawMap-aliohjelmasi oli täysin vaillinainen. Eli ei ihme ettei toiminut. Muuttujia drop_x ja -y ei edes määritelty. :o

Tässä versio jonka pitäisi toimia vähän paremmin, joskaan ei välttämättä täydellisesti :).

Code: Select all

    
    DrawMap:
        
        DrawToImage map_image
            
            For i = 0 To map_size-1
            
                Pick_x  = TILEMAP(i) Mod (ImageHeight(tileset) / tile_height)
                Pick_y  = RoundUp(TILEMAP(i)/(ImageHeight(tileset) / tile_height))
            
                drop_x = i Mod map_height
                drop_y = RoundUp(i / map_height)
                CopyBox pick_x*tile_width, pick_y*tile_height, tile_width, tile_height, drop_x*tile_width, drop_y*tile_height, Image(tileset), Image(map_image)

            Next i

        DrawToScreen
        
    Goto DropTile_mode
Kysymys: Miksi ihmeessä tilekarttasi on yksiulotteinen taulukko? Miksei kaksiulotteinen? Kaksiulotteinen taulukko on sata kertaa intuitiivisempi tällaisissa tapauksissa, eikä sillä tarvitse säätää niin paljon matematiikan kanssa.
-Vuoden 2008 aloittelijan ystävä -palkinnon voittaja-
Image <- protestipelikilpailun voittaja.
Space War
MrMonday
Advanced Member
Posts: 378
Joined: Fri Oct 10, 2008 2:35 pm

Re: Tilekartta editori Coolbasicilla

Post by MrMonday »

Jonez wrote:DrawMap-aliohjelmasi oli täysin vaillinainen. Eli ei ihme ettei toiminut. Muuttujia drop_x ja -y ei edes määritelty. :o

Tässä versio jonka pitäisi toimia vähän paremmin, joskaan ei välttämättä täydellisesti :).

Code: Select all

    
    DrawMap:
        
        DrawToImage map_image
            
            For i = 0 To map_size-1
            
                Pick_x  = TILEMAP(i) Mod (ImageHeight(tileset) / tile_height)
                Pick_y  = RoundUp(TILEMAP(i)/(ImageHeight(tileset) / tile_height))
            
                drop_x = i Mod map_height
                drop_y = RoundUp(i / map_height)
                CopyBox pick_x*tile_width, pick_y*tile_height, tile_width, tile_height, drop_x*tile_width, drop_y*tile_height, Image(tileset), Image(map_image)

            Next i

        DrawToScreen
        
    Goto DropTile_mode
Kysymys: Miksi ihmeessä tilekarttasi on yksiulotteinen taulukko? Miksei kaksiulotteinen? Kaksiulotteinen taulukko on sata kertaa intuitiivisempi tällaisissa tapauksissa, eikä sillä tarvitse säätää niin paljon matematiikan kanssa.
Tuhannet kiitokset, ei tosiaan vielä toimi täydellisesti, mutta apu oli silti suuri, ja tarkempaa korjailua joudan nyt tehdä itsekkin :) Jäin itsekkin nyt ihmettelemään, että mitä ihmettä sitä on päässä liikkunut, mutta ehkä se ei vain ole tuottoisinta aikaa koodailla yö-aikaan :D Niin siis tarkoititko, että kaksiulotteiseen taulukkoon tallentaisin X:n ja Y:n erikseen? Tämä vaatii kyllä muutoinkin vielä jonkin verran suunnittelua, ennen kuin työstän tätä enempää.
Konstaduck wrote:Vielä kun saisit tallenettua nuo kartat vaikka .til muotoon, niin niitä voisi käyttää jo peleissä.


Näillä näkymin nykyisen CoolBasic:in käyttämää karttaformaattia en tule tähän viritelmään lisäämään, paitsi korkeintaan ylempänä mainitulla tavalla, missä karttaa ladatessa EditMap:illa lätkitään tilet tiedostosta tyhjän kartan päälle. Tämä siitä syystä, että tämä projekti tuskin valmistuu ennen CoolBasic classic:ia, joka mahdollisesti käyttää toista, tai päivitettyä tilekartta-formaattia, jolloin en viitsi uhrata aikaa sen väkertämiseen.
User avatar
Jonez
Devoted Member
Posts: 575
Joined: Mon Aug 27, 2007 8:37 pm

Re: Tilekartta editori Coolbasicilla

Post by Jonez »

Jos käytät yksiulotteista taulukkoa, on kaikista loogisinta myös tehdä funktiot jotka löytävät taulukosta oikean x- ja y-kohdan yksinkertaisilla arvoilla.

Esim. 2x2-kokoinen mappi, taulukon koko on 4. Dim taulu(3) : arvo = palautaArvo(taulu, 2, 2)
palauttaa taulukon neljännen kohdan arvon. PalautaArvo(taulu, 1, 1) palauttaa ensimmäisen arvon.

Eli voit hyvin käyttää myös yksiulotteista taulukkoa. Mutta onko siinä lopulta mitään järkeä, kun cb:hen on suoraan sisäänrakennettu moniulotteisten taulukoiden tuki. Ja "funktiot" näiden arvojen saamiseen: Dim taulu(1, 1) : ekaArvo = taulu(0, 0). Eli teet vain turhaa työtä. Voi olla että yksiulotteisilla taulukoilla olisi jotain etujakin tällaisessa tilanteessa, mutta itselle ei tule yhtäkään mieleen.

Siis jotenkin näin tekisin itse:

Code: Select all

Dim mapdata(_mapWidth, _mapHeight, layerAmount)

Tallennus:
    f = OpenToWrite("tallenne.txt")
        
        WriteInt f, _mapWidth
        WriteInt f, _mapHeight
        WriteInt f, layerAmount
        
        For a = 0 To layerAmount
            For y = 0 To _mapHeight
                For x = 0 To _mapWidth
                    WriteInt f, mapdata(x, y, a)
                Next x
            Next y
        Next a
    
    CloseFile f
Return

Lataus:
    f = OpenToRead("tallenne.txt")
        
        _mapWidth = ReadInt(f)
        _mapHeight = ReadInt(f)
        layerAmount = ReadInt(f)
        
        ReDim mapdata(_mapWidth, _mapHeight, layerAmount)
        
        For a = 0 To layerAmount
            For y = 0 To _mapHeight
                For x = 0 To _mapWidth
                    mapdata(x, y, a) = ReadInt(f)
                Next x
            Next y
        Next a
    
    CloseFile f

    Gosub redrawMap
Return

redrawMap:
    
    For a = 0 To drawableLayerAmount
        For y = 0 To _mapHeight
            For x = 0 To _mapWidth
                tileId = mapdata(x, y, a)
                copyX = getXById(tileId)
                copyY = getYById(tileId)
                
                CopyBox copyX, copyY, TILE_WIDTH, TILE_HEIGHT, x * TILE_WIDTH, y * TILE_HEIGHT, Image(tileset), Image(imgCurrentLayer)

            Next x
        Next y
    Next a
Return
-Vuoden 2008 aloittelijan ystävä -palkinnon voittaja-
Image <- protestipelikilpailun voittaja.
Space War
User avatar
axu
Devoted Member
Posts: 854
Joined: Tue Sep 18, 2007 6:50 pm

Re: Tilekartta editori Coolbasicilla

Post by axu »

MrMonday wrote:Näillä näkymin nykyisen CoolBasic:in käyttämää karttaformaattia en tule tähän viritelmään lisäämään, paitsi korkeintaan ylempänä mainitulla tavalla, missä karttaa ladatessa EditMap:illa lätkitään tilet tiedostosta tyhjän kartan päälle. Tämä siitä syystä, että tämä projekti tuskin valmistuu ennen CoolBasic classic:ia, joka mahdollisesti käyttää toista, tai päivitettyä tilekartta-formaattia, jolloin en viitsi uhrata aikaa sen väkertämiseen.
Kuka puhui ajan käyttämisestä? Puf!

Code: Select all

//CBMapIO
Dim TileAnim(1,1)   //TileAnim -taulukko sisältää tilejen animoinnin(koska coolbasicissa ei voi tarkistaa sitä jälkikäteen), TileAnim(TILE, ANIMAATION_PITUUS = 0/ANIMAATION_HITAUS = 1
Function OpenMap(FileName$, Tileset$="", PrintHeader = 0)
    f = OpenToEdit(FileName)
    '    If Not(ReadByte(f) = 40 And ReadByte(f) = 192 And ReadByte(f) = 13 And ReadByte(f) =  139) Then MakeError "Can't load map "+FileName+". Map is not valid Tilester 1.3 file"
        If PrintHeader Then
            Print ReadByte(f) + " " + ReadByte(f) + " " + ReadByte(f) + " " + ReadByte(f)
            WaitKey
        EndIf
        If Tileset = "" Then
            SeekFile f, 564
            For i = 0 To 255
                b = ReadByte(f)
                If b = 0 Then Exit Else Tileset = Tileset + Chr(b)
            Next i
        EndIf
        SeekFile f, 820
        TileCount   = ReadInt(f)
        TileWidth   = ReadInt(f)
        TileHeight  = ReadInt(f)
        Map = MakeMap(ReadInt(f), ReadInt(f), TileWidth, TileHeight)
        TilesetImg  = LoadImage(Tileset)
        PaintObject Map, TilesetImg
        For i = 0 To 3
            If Not(ReadByte(f) = 254-i And ReadByte(f) = 45-i And ReadByte(f) = 12-i And ReadByte(f) = 166-i) Then MakeError "Can't load map "+FileName+". Map layer "+i+" was corrupted"
            For Y = 1 To MapHeight()
                For X = 1 To MapWidth()
                    EditMap Map, i + (i = 1) - (i = 2), X, Y, ReadInt(f)
                Next X
            Next Y
        Next i
        If Not(ReadByte(f) = 250 And ReadByte(f) = 41 And ReadByte(f) = 8 And ReadByte(f) =  162) Then MakeError "Can't load map "+FileName+". Tile animation was corrupted"
        ReDim TileAnim(TileCount-1, 1)
        For i = 0 To TileCount-1
            TileAnim(i, 0) = ReadInt(f)
            TileAnim(i, 1) = ReadInt(f)
            SetTile i, TileAnim(i, 0), TileAnim(i, 1)
        Next i
        SeekFile f, 520
        MaskObject Map, ReadByte(f), ReadByte(f), ReadByte(f)
    CloseFile f
    
    Return Map
End Function

Function SaveMap(Map, FileName$, TilesetImg, Tileset$ = "", MaskRED = 0, MaskGREEN = 0, MaskBLUE = 0, Comment$ = "")
    f = OpenToWrite(FileName)
        WriteByte f, 40 : WriteByte f, 192 : WriteByte f, 13 : WriteByte f, 139
        WriteFloat f, 1.3
        For i = 1 To 512
            If i < Len(Comment) And i < 256 Then
                WriteByte f, Asc(Mid(Comment, i, 1))
            Else
                WriteByte f, 0
            EndIf
        Next i
        WriteByte f, MaskRED : WriteByte f, MaskGREEN : WriteByte f, MaskBLUE : WriteByte f, 0
        For i = 1 To 40
            WriteByte f, 0
        Next i
        For i = 1 To 256
            If i < Len(Tileset) Then
                WriteByte f, Asc(Mid(Tileset, i, 1))
            Else
                WriteByte f, 0
            EndIf
        Next i
        TileCount = (ImageWidth(TilesetImg)/(ObjectSizeX(Map) / MapWidth())) * (ImageHeight(TilesetImg)/(ObjectSizeY(Map) / MapHeight()))
        WriteInt f, TileCount
        WriteInt f, ObjectSizeX(Map) / MapWidth()
        WriteInt f, ObjectSizeY(Map) / MapHeight()
        WriteInt f, MapWidth()
        WriteInt f, MapHeight()
        For i = 0 To 3
            WriteByte f, 254-i : WriteByte f, 45-i : WriteByte f, 12-i : WriteByte f, 166-i
            For Y = 1 To MapHeight()
                For X = 1 To MapWidth()
                    WriteInt f, GetMap2(i + (i = 1) - (i = 2), X, Y)
                Next X
            Next Y
        Next i
        WriteByte f, 250 : WriteByte f, 41 : WriteByte f, 8 : WriteByte f, 162
        For i = 0 To TileCount-1
            WriteInt f, TileAnim(i, 0)
            WriteInt f, TileAnim(i, 1)
        Next i
    CloseFile f
EndFunction
Muistaakseni toimii täysin, ja tuo TileAnim-taulukko sisältää sitten tilejen animointitiedon, muistaakseni näin: TileAnim(tile#, PITUUS=0/HITAUS=1). Tuon taulukon venyttämisestä oikean kokoiseksi täytyy itse vastata tai muuten voi vuotaa yli. Kartan avausfunktio ei muuten eroa cb:n omasta paitsi se täyttää ko. taulukon, jotta ohjelma pystyy muokkaamaan animaatiodataa.
Saat käyttää ihan vapaasti :)
EDIT:

Jonez wrote:Eli voit hyvin käyttää myös yksiulotteista taulukkoa. Mutta onko siinä lopulta mitään järkeä, kun cb:hen on suoraan sisäänrakennettu moniulotteisten taulukoiden tuki. Ja "funktiot" näiden arvojen saamiseen: Dim taulu(1, 1) : ekaArvo = taulu(0, 0). Eli teet vain turhaa työtä. Voi olla että yksiulotteisilla taulukoilla olisi jotain etujakin tällaisessa tilanteessa, mutta itselle ei tule yhtäkään mieleen.
Minäkään en näe hyötyä yksiulotteisen taulukon käyttämisestä, mutta siitä on pieni askel muistipalojen käyttöön. Nyt alkaakin löytymään jo käyttötarkoituksia, mm. useamman kartan yhtäaikainen muokkaus (taulukollinen muistipaloja tai tyypeillä), nopea kopiointi tai vaikka tallentaminen kryptattuna tiedostoon![/edit]
Jos tämä viesti on kirjoitettu alle 5 min. sitten, päivitä sivu. Se on saattanut jo muuttua :roll:
Image
Post Reply