Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java: Sprite-arkin (Spritesheet) hallinta

Sivun loppuun

Jere Sumell [28.01.2021 20:47:19]

#

Aloin ajan kuluksi miettimään Javalla peliohjelmointia, jossa hyödynnetään monisäikeisyyttä, jokainen pelin objekti toimisi omana säikeenään.

Ajattelin, jos pelin grafiikan ja animaatioiden ruudut niin pelaajan hahmon, kuin vihollistenkin ja muiden itemien osalta piirtäisi yhteen Sprite-arkkiin, niin miten käytännössä voisi hallita Spritestä piirtoa, esimerkiksi jos pelaajan hahmon liikeanimaatio eteenpäin mennessä on piirrettynä yhteen arkkiin?

Onko tähän olemassa jotain apuohjelmia?

Noita spritesheettejä on saatavilla useaan jo olemassa-olevaan peliinkin, niin jos kiinnostaa remakea tehdä esimerkiksi Mariosta testatakseen Spritesheettien käsittelyä, niin voisi hyödyntää Mario Spriteä Google kuvahaulla löytää.

carabia [15.02.2021 18:01:33]

#

Tarviit sen sheetin lisäksi metadatana:
- Mistä mikäkin animaatio löytyy siitä sheetistä (periaatteessa "tekstuuriatlas"), elikkä koordinaatit ja koot.
- Kuinka monta framea kussakin animaatiossa on

Mikäli spritejä ei ole kauhean montaa, niin voit toki koodata kaikki suoraan peliin sisälle, mutta jos kerran kirjotat systeemin millä voit helposti kirjottaa/lukea tuon metadatan, niin nopeuttaa devaamista myöhemmin.

Sen jälkeen kun data on jollain keinolla sisässä, niin piirto on melko simppeliä laskurin (pitää kirjaa nykyisestä framesta) avulla:

1. Piirrä frame x
2. x = (x+1) % animaation_framemäärä

Riippuen kuinka paljon frameja sulla on spriteissä, voit myös koittaa vaikka lerpata niitä, jolloin laskurina kokonaisluvun sijasta olisi liukuluku, jota korotat delta t:llä. Esimerkiksi laskurin arvolla x = 1.25, suorittaisit lineaari-interpolaation framen 1 ja 2 välillä, ja t:n arvolla t=0.25.

EDIT: Näiden lisäksi kumpaakin on hyvä lisätä toistonopeus (FPS), joka on joko sama kaikille animaation frameille tai sitten jokaiselle erikseen omansa.

The Alchemist [16.02.2021 07:25:24]

#

Tuollainen säikeistyslogiikka on aika katastrofaalinen. Säikeet eivät ole ilmaisia vaan ne kuluttavat muistia, minkä lisäksi säikeiden synkronointi on vaikeaa ja huonosti toteutettuna itse asiassa erittäin hidasta.

jalski [16.02.2021 08:08:57]

#

The Alchemist kirjoitti:

Tuollainen säikeistyslogiikka on aika katastrofaalinen. Säikeet eivät ole ilmaisia vaan ne kuluttavat muistia, minkä lisäksi säikeiden synkronointi on vaikeaa ja huonosti toteutettuna itse asiassa erittäin hidasta.

Vastasitkohan vahingossa väärään viestiketjuun? Tässähän puhe on käytännössä vain kaikkien spriten kuvien tallentamisesta yhteen kuvaan ja piirtämällä siitä oikea osa kuva...

Grez [16.02.2021 08:19:14]

#

jalski kirjoitti:

Vastasitkohan vahingossa väärään viestiketjuun?

Jos aloitusviestin lukee alusta asti, niin kyllä tuo kommentti on relevantti.

Jere Sumell kirjoitti:

Aloin ajan kuluksi miettimään Javalla peliohjelmointia, jossa hyödynnetään monisäikeisyyttä, jokainen pelin objekti toimisi omana säikeenään.

jalski [16.02.2021 08:59:28]

#

Grez kirjoitti:

(16.02.2021 08:19:14): ”– –” Jos aloi­tus­viestin lukee alusta asti, niin...

Oops.. Minun moka! ;)

Okei, tuo kyllä tekisi asioista turhan vaikeata! Joutuisi kuitenkin synkronoimaan perusasioita kuten liikkuminen...

carabia [16.02.2021 14:51:56]

#

Joo'o, itsellä luetun ymmärtäminen ei ilmeisesti ole vahvuuksien joukossa, kun tuo threadaus meni multa ihan ohi. Tuossa threadi-per-objekti ideassa ei ole oikeastaan mitään järkeä, koska prosessori kykenee suorittamaan hyvin rajallista määrää threadeja samaan aikaan (SMT ei varsinaisesti meinaa 2/useamman threadin samanaikaista ajoa yhdellä ytimellä).

Mitä enemmän objekteja pelissä olisi, sitä enemmän niiden threadit joutuisi odottamaan ajoaikaa muiden objektien threadeilta (+ toki kaikilta muilta mitä ajetaan pelin ulkopuolella), noh oikeammin schedulerilta, ja suorituskyvyn kannalta tämänlaisessa säikeistyksessä häviät paljon enemmän kuin voitat.

Niin tai näin, jos meinaat säikeistää itse pelilogiikan suorituskyvyn takia, joudut joko käyttämään x määrän lukkoja (=synkkausprimitiivejä), jolloin suorituskyky ei välttämättä juurikaan parane, tai sitten joudut suunnittelemaan datan mahdollisimman pitkälle lukottomaksi, ja tuo onkin sitten helpommin sanottu kuin tehty.

Jere Sumell [25.03.2021 14:20:56]

#

Joo no viimeistään nyt tämän viestin vastaukset luettuani äkkäsin tuon, että ehkä eniten ongelmia aiheuttaisi tuo säikeiden synkronointi. Helposti tosiaan peli, jos se sisältäisi verrattain vähänkin objekteja ruudulla, vaatisi koneelta paljon tehoja, ja vaikka objektien väripaletti olisikaan, kuin vaikka 8 - bittinen.

Ohjelmoinnissa on kiehtovuus osittain siinä, että pitäisi noiden resurssien osalta pyrkiä luomaan koodia, että ajan, tilan, Cpu:n käyttoasteen yms. suhteen otettaisiin mahdollisimman paljon irti mahdollisimman vähin kustannuksin. Less is more.

Tuo säikeiden synkronointiongelma taitaa liittyä 1960-luvulla esitettyyn rinnakkaisuusohjelmointi -ongelmaan, josta lienee tunnetuin esimerkki tuo "Aterioivat filosofit". Siinähän voi tapahtua nälkiintyminen (deadlock), jos ongelman ratkaisualgoritmi on virheellinen.

Joskus olen tuota Java Thread Deadlock katsonut Googlella, niin siihenkin on olemassa tunnettuja ratkaisuja, jotka voisi toimia implementoituna Java-koodiksi, mutta lienee kokonaan oman tutkimuksensa, tai opinnäytetyon aiheensa tuo rinnakkaisuus-ongelma lukkiutumisen välttäminen.

Lienee pare unohtaa säie per peliobjekti, ja lukea jokin Java peliohjelmointikirja, jos saisi jotain vinkkiä, miten kannattaisi toteuttaa tuo vihollisten, muiden objektien ja pelihahmon liikkeet mahdollisimman vähin kustannuksin.

Tuo Spreadsheetin luonti tai valmiin spreadsheetin käytto on ihan käyttokelpoinen ajatus, pitäisi varmaan lähteä liikkeelle sellaisen apuohjelman valmistuksesta, joka pysyy luomaan tuosta grafiikka-arkista ja lukemaan tietokoneen muistiin tarvittavat koordinaatit, joita sitten varsinainen pelin sisältämä tietotyyppi, joka piirtää ne ruudulle miten sitten piirtääkin, niin saa syoteparametreina ne.

Katsoin äsken uudelleen Google -hakutermistolla "Thread deadlock prevention", niin Wikipediasta tuli tuo "Deadlock prevention algorithms (Suora linkkilähde - Wikipedia)", jossa esitetty tuo Banker's Algorithm, ja sitten estoalgoritmi rekursiivisille lukoille listassa, jossa on noita ratkaisuja. Tutustuin aiheeseen ensimmäisen kerran AMK-opintojeni Olio-ohjelmoinnin jatkokurssilla kotitehtävien osalta pikaisesti, ja myohemmin palasin aiheeseen vasta 2020 alussa, ja nyt katsoin vielä kolmannen kerran.


Sivun alkuun

Vastaus

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

Tietoa sivustosta