Ongelmani koskee jo hettken aikaa kehittelemääni tilemoottoria, jonka koodin hiljattain uudelleenkirjoitin. Grafiikka siis hieman välkkyy. Kertokaapa joku, teenkö jotain tyhmästi vai mikä on. Ollen kyllä yrittänyt ottaa mallia muista moottoreista, joiden koodeja olen lueskellut. Mukavaa jos joku jaksaa myös omia väännöksiäni hieman tutkailla, jos se vikakin sieltä löytyisi.
Tässäpä piirtoon liittyvät koodit:
Run-metodi:
public void run(){ long beforeTime, timeDiff, sleepTime; beforeTime = System.currentTimeMillis(); running = true; while(running) { gameUpdate(); //game state is updated gameRender(); //render to a buffer gamePaint(); //paint with the buffer timeDiff = System.currentTimeMillis() - beforeTime; sleepTime = preferedSleepPeriod - timeDiff; // time left in this loop System.out.println(sleepTime); if (sleepTime <= 0) // update/render took longer than period sleepTime = 5; // sleep a bit anyway try { Thread.sleep(sleepTime); //sleep a bit } catch(InterruptedException ex){} beforeTime = System.currentTimeMillis(); } System.exit(0); //Applet exits }
Kenttä on Tile-tyypin taulukko. Taulukon Tile-instansseilla on metodi, joka piirtää tilen kuvan annettuun grafiikkapintaan. Tämä tapahtuu ihan perus drawImage:lla.
gameRender:
private void gameRender(){ if (panelBufferImage == null){ panelBufferImage = createImage(PWIDTH, PHEIGHT); if (panelBufferImage == null) { System.out.println("dbImage is null"); return; } else panelBufferGraphics = panelBufferImage.getGraphics(); } // clear the background panelBufferGraphics.setColor(Color.black); panelBufferGraphics.fillRect (0, 0, PWIDTH, PHEIGHT); for(int i=offsetX-1; i<screenWidthInTiles+offsetX+1; i++){ //leaving buffers out side of the screen for smooth scrolling for(int j=offsetY-1; j<screenHeightInTiles+offsetY+1; j++){ //leaving buffers out side of the screen for smooth scrolling if(i>=0 && i<mapWidth && j>=0 && j<mapHeight){ tileMatrix[i][j].drawTile(panelBufferGraphics, offsetX, offsetY, pixelsX, pixelsY, this); } } } player.drawMovableCharacterBody(panelBufferGraphics, moving, pixelsX, pixelsY, this); player.drawMovableCharacterHead(panelBufferGraphics, moving, pixelsX, pixelsY, this); }
gamePaint:
private void gamePaint(){ // use active rendering to put the buffered image on-screen Graphics g; try { g = this.getGraphics(); if ((g != null) && (panelBufferImage != null)) g.drawImage(panelBufferImage, 0, 0, null); Toolkit.getDefaultToolkit().sync(); // sync the display on some systems g.dispose(); } catch (Exception e) // quite commonly seen at applet destruction { System.out.println("Graphics Context error: " + e); } }
Koko koodin laitoin tänne: http://pastebin.com/m1b00c85
Koodissa on vielä osia, joita ei ollenkaan käytetä. Keltaiset viivat erottavat luokat toisistaan.
En javasta kauheesti tiedä, mutt onko sulla kaksoispuskurointi päällä?
Kyllä on päällä. Eli tuossa gameRender()-metodissa renderöidään kuva ensin panelBufferImageen ja gamePaint()-metodissa se piirretään näytölle.
Sehän näyttää ällistyttävän paljon omaa eräällä Peliohjelmointi-kurssilla tekemääni harjoitustyötä (josta tosin moottorin pohja saatiin/tehtiin kurssin aikana opettajan avustamana):
(poistettu rikkinäinen linkki)
Tosin toikin nykii mielestäni ihmeellisesti, syystä mihin en keksinyt syytä. Mutta kärsiikö se samasta ongelmasta kuin sinun koodisi? Tuossa muistaakseni pitäisi olla jonkinlainen fps-mittarikin jonka saa debug-muuttujalla näkyviin, voin antaa koodin sinulle jos koet sen hyödylliseksi.
Oman moottorin pohjana käytin Killers game programming in Java kirjan värkettä. Eli GamePanel-luokan pohja on siitä lainattu.
Voiko ongelma johtua Applettien jonkin asteisesta hitaudesta, sillä nämä Java Web Start -ohjelmat piirtävät grafiikkaa verrattaen nopeasti. Esimerkiksi tämä peli pyörii melko sulavasti http://www.brackeen.com/javagamebook/#play .
Auttaisiko, jos BufferedImagen sijasta käyttäisi VolatileImagea, joka mahdollistaa tuen laitteistokiihdytetyille kuville? Jos joku tietää koodin pätkän, jossa VolatileImage on käytössä, olisi siitä varmasti apua.
Vielä tuosta pelistäsi. Omassa ohjelmassani ilmenee myös satunnaista hidastumista. Hetken pelattua peli hidastuu ja hetken päästä vauhti palaa normaaliksi. Tämä johtuu todennäköisesti siitä, että piirtoon kuluu niin paljon aikaa, ettei säie ehdi nukahtaa lainkaan. Tämän nopeuttamiseen en vielä ole keksinyt ratkaisua.
Mobel kirjoitti:
Vielä tuosta pelistäsi. Omassa ohjelmassani ilmenee myös satunnaista hidastumista. Hetken pelattua peli hidastuu ja hetken päästä vauhti palaa normaaliksi. Tämä johtuu todennäköisesti siitä, että piirtoon kuluu niin paljon aikaa, ettei säie ehdi nukahtaa lainkaan. Tämän nopeuttamiseen en vielä ole keksinyt ratkaisua.
Syytä vain en keksi. Kun se pyörii normaalisti, suorituskyky kyllä on enemmän kuin riittävä. Sitten tulee tuollainen "hidastusaalto" joka kestää aikansa, ja taas peli pyörii täysin moitteettomasti seuraavaan hidastumiseen asti. Tosin en sitä hirveästi jäänyt kaivelemaan, kun kurssi keskittyi vähän muihin aiheisiin kuin moottorinviilaukseen/Javan omituiksiin.
Mobel kirjoitti:
Oman moottorin pohjana käytin Killers game programming in Java kirjan värkettä. Eli GamePanel-luokan pohja on siitä lainattu.
Voiko ongelma johtua Applettien jonkin asteisesta hitaudesta, sillä nämä Java Web Start -ohjelmat piirtävät grafiikkaa verrattaen nopeasti. Esimerkiksi tämä peli pyörii melko sulavasti http://www.brackeen.com/javagamebook/#play .Auttaisiko, jos BufferedImagen sijasta käyttäisi VolatileImagea, joka mahdollistaa tuen laitteistokiihdytetyille kuville? Jos joku tietää koodin pätkän, jossa VolatileImage on käytössä, olisi siitä varmasti apua.
Vielä tuosta pelistäsi. Omassa ohjelmassani ilmenee myös satunnaista hidastumista. Hetken pelattua peli hidastuu ja hetken päästä vauhti palaa normaaliksi. Tämä johtuu todennäköisesti siitä, että piirtoon kuluu niin paljon aikaa, ettei säie ehdi nukahtaa lainkaan. Tämän nopeuttamiseen en vielä ole keksinyt ratkaisua.
Melko todennäköinen syy tuollaiselle ajoittaiselle hidastumiselle saattaisi olla roskien keruu, jota jvm harrastaa silloin tällöin.
VolatileImagen käyttöön voisi löytyä apua javan apista http://java.sun.com/javase/6/docs/api/java/awt/
Mitäs ihmettä? Onko Javan 7 uudistanut grafiikan piiirtoa, vai mistä on kyse. Aloin soveltamaan VolatileImage-esimerkkiä kirjoittamalla grafiikan piirron nopeutta testaavaa ohjelmaa. Huomasin, että ihan tavallinen paint()-metodi toimi yhtä hyvin ja ihan ilman välkkymistä. Kokeilin sitten em. moottoria kutsumalla run()-metodissa gameUpdate()-metodin lisäksi vain repaint():ia ja siirsin piirron paint()-metodiin, jolloin peli toimi täysin sulavasti ilman välkyntää.
Osaako joku kertoa mistä tämä johtuu? Kokeilin myös joitakin hyvin vanhoja graafisia ohjelmiani ja nämä toimivat myös moitteetta vaikka - ilman kaksoispuskurointia kun ovat - ennen välkkyivät. Varmistin vielä, ettei kyse ole vain omasta koneestani ja ajoin moottorin myös toisella koneella samoin tuloksin.
Osaako joku kertoa msitä on kyse? Tosin en kyllä valita, mahdollinen Delffiinin uudistus kelpaa minulle.
Eikun äh, eihän se vielä tuohon seiskaan ehtinyt päivittää kun ei sitä vielä olla julkaistukaan. Jotainhan se Java tuossa lähiaikoina päviitteli ja uusi Applettien latauspalkkikin ilmestyi. Tuo riitti saamaan minut luulemaan uuden version olemaan käytössä.
Kaipa tuo grafiikan piirto on sitten jo aikaisemmissa päivityksissä muutettu, jos ohjelman nopeutuminen nyt siitä johtuu.
Aihe on jo aika vanha, joten et voi enää vastata siihen.