Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Tilemoottorin hitaus

Sivun loppuun

Mobel [16.05.2009 15:37:36]

#

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.

vehkis91 [16.05.2009 16:50:49]

#

En javasta kauheesti tiedä, mutt onko sulla kaksoispuskurointi päällä?

Mobel [16.05.2009 18:08:04]

#

Kyllä on päällä. Eli tuossa gameRender()-metodissa renderöidään kuva ensin panelBufferImageen ja gamePaint()-metodissa se piirretään näytölle.

kayttaja-2791 [17.05.2009 13:11:09]

#

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.

Mobel [17.05.2009 13:42:41]

#

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.

kayttaja-2791 [17.05.2009 15:06:35]

#

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.

Sami [17.05.2009 22:33:42]

#

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/image/VolatileImage.html tai exampledepotista http://www.exampledepot.com/egs/java.awt.image/VolImage.html

Mobel [20.05.2009 21:32:16]

#

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.

Mobel [20.05.2009 22:38:56]

#

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.


Sivun alkuun

Vastaus

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

Tietoa sivustosta