Ongelma on seuraava: olen tehnyt Javalla toimintapelin, mutta se toimii kaikilla eri koneilla eri nopeudella. Luulin huomioivani asian, ja luulen tietäväni, mistä nopeuden vaihtelu johtuu. Jouduin nimittäin laittamaan ohjelmaan hidasteen. En käyttänyt hidasteena pitkää silmukkaa, vaan seuraavaa rakennetta:
try { viive.sleep(nopeus); } catch (InterruptedException w){}
Ajattelin, että tämä on tietokoneriippumaton hidaste, joka otetaan kellosta. Eikö näin olekaan? Osaako joku sanoa, mitä tarkalleen tarkoittaa, jos laitan tuossa lausekkeessa muuttujan nopeus paikalle vaikkapa 5? Onkohan Java apleteissa jokin käyttökelpoisempi hidastetapa, vai onko vika lopulta edes tässä? Ohjelman nopeudenvaihtelu on siitä kummaa (minusta), että se saattaa toimia nopeassa tietokoneessa hitaasti, ja hitaassa nopeasti. Ja käsittääkseni internet yhteyden nopeudellakaanhan ei tässä ole merkitystä, ja sekin kyllä menisi ristiin. Osaako joku neuvoa?
http://java.sun.com/j2se/1.5.0/docs/api/java/
Tuon mukaan kyse on ihan millisekunneista.
PaavoOR kirjoitti:
Ajattelin, että tämä on tietokoneriippumaton hidaste, joka otetaan kellosta. Eikö näin olekaan? Osaako joku sanoa, mitä tarkalleen tarkoittaa, jos laitan tuossa lausekkeessa muuttujan nopeus paikalle vaikkapa 5? Onkohan Java apleteissa jokin käyttökelpoisempi hidastetapa, vai onko vika lopulta edes tässä? Ohjelman nopeudenvaihtelu on siitä kummaa (minusta), että se saattaa toimia nopeassa tietokoneessa hitaasti, ja hitaassa nopeasti. Ja käsittääkseni internet yhteyden nopeudellakaanhan ei tässä ole merkitystä, ja sekin kyllä menisi ristiin. Osaako joku neuvoa?
Onhan tuo tietokoneriippuvainen hidaste, mutta kaiken muun ohjelmakoodin suorittamiseen menee eri koneilla eri aika. Esimerkiksi, jos viiveesi on 10 ms ja nopealla koneella ruudun päivittävän koodin suoritus vie 10 ms, on ruutujen välinen aikaero noin 20 ms. Toisaalta himaalta koneelta koodin suorittamiseen saattaa mennä tuplasti kauemmin jolloin ruutujen välinen aika onkin 30 ms eli tämä ohjelma näyttää toimivan paljon hitaammin.
Ratkaisuja on lähinnä kaksi.
Eräs vaihtoehto on käyttää vaihtelevan mittaista omaa viivettä, joka ottaa huomioon kuinka kauan ruudun päivitys kestää.
Toinen vaihtoehto on päivittää ruutua ilman mitään viivettä ja jollakin tavalla suhteuttaa kaiken liikkeen kelloon. Tämä on yleensä sulavampi ja parempi tapa.
Oikeastaan vähän niin arvelinkin. Mutta jos hidaste otetaan kellosta, niin eikö sen pitäisi olla sama kaikilla tietokoneilla?
edit. kerkesi tulla väliin jo toinen vastaus. Tämä oli tarkoitettu vastaukseksi edelliseen.
FooBat kirjoitti:
... tietokoneriippuvainen ...
Tuohon jäi näköjään pehemman laatuinen kirjoitusvirhe. Toki tuo viive on tietokoneriippumaTON. Toivottavasti asiayhteydestä sentään ymmärsi idean.
Tässä nopeushommassa onkin merkillisyytenä sen kummallisuus eri tietokoneiden suhteen. Ohjelma on tehty 1,6 GHz centrinolla. Kun testaan sitä ikivanhalla, jollain 400 MHz Pentiumilla, niin peli toimii, joskin ruutu välkkyy häiritsevästi, mutta toimii kuitenkin. Sen sijaan kun testaan koulun modernilla 2,8 GHz Pentiumilla, jossa on kunnolla muistiakin, niin nopeus on yli tuplaten liian hidas. Mistähän tuo voisi johtua? Voisin yrittää tuota nopeuden suhteuttamista kelloon. Miten Javan kelloa luetaan millisekunttien tarkkuudella? En ole Javassa kelloa käyttänyt. Käytän nimittäin viiveenä ainoastaan arvoja 5-9 tuossa laittamassani koodipätkässä.
Java 1.4 ja aiemmissa pystyy kelloa lukemaan millisekunnin tarkkuudella komennolla System.currentTimeMillis(). Java 1.5:ssa on myös System.nanoTime(), jolla pitäisi pystyä tarkempaan aijanmittaamiseen (niin ne ainakin väittää).
Se, että ohjelma on hitaampi nopealla konella vaikuttaa todella kummalliselta. Yksi etäinen mahdollisuus liittyy liian suureen garbage collectorin käyttöön (kokeile ajaa ohjelma "java -verbose:gc Luokka", jos gc:tä ajetaan jatkuvasti voi kyse olla siitä). Joskus vuosia sitten itselläni oli tiettyjen koneiden kanssa ongelmia siinä, että koneiden kellot eivät antaneet kovin tarkkoja arvoa, vaan arvot olivat noin 30ms:n tarkkuuteen pyöristettyjä. Ehkä delayn kanssa voi olla samanlaisia ongelmia? Toisinaan myös liian pienet delayn arvot ovat saaneet ohjelman nykimään tietyillä koneilla.
Jonkinverran nopeuseroja syntyy käytettävästä JRE;stä. Joskin en usko, että tässä on kyse siitä.
Kertomasi koodi ei kerro sulle try silmukkassa syntyvää virhettä, vaikka sellainen tapahtuisi eli on mahdollista, että koulun nopea kone on javan osalta jäänyt kivikaudelle ja esim. tuo sleep ei toimi ja heittää poikkeuksen, joka taas on äärimmäisen hidas operaatio. Tosin tuo voi tapahtua ihan missäpäin tahansa ohjelmaa.
Yleensä uusillakin koneilla windowsissa on oletuksena se MS:n surkea java tulkki, joka ei tue juuri mitään tosin, jos ohjelma käyttää vanhoja luokkia, niin ohjelma voi periaatteessa toimiakkin lähes oikein, mutta hitaasti ja surkeasti heitellen poikkeuksia joista ei kerrota mitään.
Aihe on jo aika vanha, joten et voi enää vastata siihen.