[JAVA] Repaint zonder alles opnieuw te tekenen

Pagina: 1
Acties:

  • 0123456
  • Registratie: Maart 2005
  • Laatst online: 28-07-2010
Ik ben dus bezig met een spel aan het maken..
Het is een poker spel, waarin de tafel getekent wordt en geen plaatje is (resizable met de frame grootte). Nu teken ik alle 52 kaarten op 1 stapel, dit duurt ongeveer 3-5 min...

Als de kaarten aan de spelers uitgedeeld worden, moet ik dus de kaarten erin teken...
Dit die ik met een paint, die ik aanroep via een Repaint...
Maar het probleem is dus, dat als ik de repaint aanroep, de hele tafel weg is en/of de stapel kaarten...
De tafel is wel opnieuw te teken met repaint, maar de 52 kaarten duren te lang om opnieuw te doen (3-5 sec.)

Is er een methode in Java, om alleen de kaarten erbij te tekenen en voor de rest alles te laten staan??

Verwijderd

euh, zelfs al zou je ze alle 52 moeten tekenen dan zou je met een beetje hardware niet langer dan 1 a 2 seconde bezig moeten zijn (als het al niet sneller is).

En dat is waarschijnlijk nog los van de aanname dat je ze waarschijnlijk niet alle 52 hoeft te tekenen.
Dus ik vraag me af wat je doet. Alle plaatjes van je hardeschijf inladen in de paint methode ofzo?

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 09:47
Lol, ik denk dat je eerst maar is achter je oren moet gaan krabben waarom het 3-5 minuten duurt om 52 kaarten te tekenen. Zo ingewikkeld is dat echt niet namelijk.

Zit je misschien iets te vaak naar het flushen ofzo? Post is wat code. Wat vooral belangrijk is, de manier waarop je tekent. Zit je misschien tig keer repaint aan te roepen ofzo?

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
Als ik hier voor de test 100 unieke JPG afbeeldingen van 80x100 pixels (~20 kB) met behulp van de ImageIcon klasse laad en via JLabels in een JFrame gooi, dan doet ie daar welgeteld ~250ms over bij een geheugen gebruik van ~17,6 MB.
Lijkt mij dat er iets niet helemaal goed gaat in jouw code?

  • Jochem Knoops
  • Registratie: November 2000
  • Laatst online: 25-11 13:57
Ik denk dat je gebruik maakt van de "oude" awt manier ipv de swing classes.
Klopt dat ?
Volgens mij tekenen de swing classes namelijk alleen dat deel dat ook zichtbaar is ipv alle objecten.

  • Upsal
  • Registratie: Mei 2005
  • Laatst online: 27-08-2024
Ik denk dat je code niet optimaal is. Denk eraan om eerst zo veel mogelijk eenmalig te laten initialiseren. Dus bijv. alle plaatjes als Image instantie in een array gooien als je het programma opstart.

Als je de update methode override dan kun je aangeven of hij wel/niet het complete scherm moet leegmaken. (De default doet dit n.l. wel.)
Voorbeeld:
Java:
1
2
3
public void update(Graphics g){
    this.paint(g);
}

[ Voor 39% gewijzigd door Upsal op 17-01-2007 17:01 ]


  • 0123456
  • Registratie: Maart 2005
  • Laatst online: 28-07-2010
Mijn code is als volgt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    void loadImage(String cardImage) {
             Toolkit kit = Toolkit.getDefaultToolkit();
             displayImage = kit.getImage(cardImage + ".jpg");
             MediaTracker mt = new MediaTracker(this);
             mt.addImage(displayImage, 1);
             try {
                 mt.waitForAll();
             } catch (Exception e) {
                 System.out.println("Exception while loading.");
             }

             if (displayImage.getWidth(this) == -1) {
                 System.out.println("Missing .jpg file");
                 System.exit(0);
             }

    }

    void drawImage(Graphics g,int mode) {
            Dimension d = getSize();
            bi = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
            Graphics2D big = bi.createGraphics();
            AffineTransform at = new AffineTransform();
            at.setToIdentity();
            at.translate(stepx(),stepy());
            if (mode == 0){
              at.rotate(Math.toRadians(0));
            }
            else{
              at.rotate(Math.toRadians(200));
            }
            big.drawImage(displayImage, at, this);
            Graphics2D g2D = (Graphics2D) g;
            g2D.drawImage(bi, 0, 0, null);
            big.dispose();
   }


Hiermee teken ik dus de plaatjes met de naam "cardImage"...
Dit duurt dus 3-5 sec. (minuten was een foutje :+ )
Ik gebruik extra Graphics2D, omdat ik dan de plaatjes ook kan draaien en bewegen (voor uitdelen)...

Verder roep ik de code als volgt aan:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void paint(Graphics g) {
       if (mode == 0){
           drawTable(g, 8, 25, frameWidth-15, frameHeight-35); 
        }
        else if (mode == 1){
            for (int i = 0; i < 52;i++){
                loadImage(cards[0]);
                drawImage(g,0);
            }
        }
        else if (mode ==2){
            if (player == 1){
               x1a = 20;
               y1a = 20;
               loadImage(cards[1]);
               drawImage(g,0);
            }
        }
    }


Waar cards[] dus een String array is met waardes van kaarten voor de speler...
De code begint met opstarten in mode 0, daarna kan ik met knoppen naar de andere modussen gaan..

Het probleem is dus, dat als ik weg ga van het Frame door een ander venster eroverheen te zetten en weer terug ga naar mijn frame. Dat dan alles behalve de laatste paint actie verdwijnt |:(

Hoe los ik dit op??

[ Voor 4% gewijzigd door 0123456 op 17-01-2007 17:13 ]


  • 0123456
  • Registratie: Maart 2005
  • Laatst online: 28-07-2010
Ik heb dus nu een override op de update() functie gedaan.
Nu blijft het hele scherm staan zoals ik dat wil :D
Het probleem is nu, als ik dus alles erop heb staan en naar een ander venster ga of het frame vergroot, dat dan alles (behalve het laatste) verdwijnt... |:(

  • Ansur
  • Registratie: Januari 2004
  • Laatst online: 29-10 13:35
- Je code en de referentie naar je image is niet geheel duidelijk, dit kan al mooier
- Je leest je images telkens opnieuw in, lees deze eens in één keer in en hou ze in-memory bij. Dit zal al een performancewinst opleveren

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Elke keer dat er gepaint wordt (in mode 1) worden er weer 52 images geladen, dat duurt relatief lang. Kun je de MediaTracker variabele niet globaal definieren?

Het verdwijnen van de graphics behalve die van je laatste paint actie is te verklaren door dat je het tekenen van de achtergrond (drawTable) maar 1 keer lijkt te doen (bij het opstarten). In principe moet je dit bij elke paint actie doen, of je moet er kaarten overheen tekenen met behulp van een clip region.

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:52

.oisyn

Moderator Devschuur®

Demotivational Speaker

zwippie schreef op woensdag 17 januari 2007 @ 17:30:
of je moet er kaarten overheen tekenen met behulp van een clip region.
Dit zorgt dat de kaarten niet buiten een bepaald gebied tekenen, niet dat de tafel weer automagisch tevoorschijn komt als je de kaarten later op een andere plek tekent ;)

Naast je loadImage die je voor elke card doet (was al gemeld), is je drawImage ook nodeloos ingewikkeld. Je creëert elke keer een nieuw image en graphics object voor je kaarten - deze moet je gewoon opslaan. Het enige wat je dan uiteindelijk hoeft te doen tijdens het tekenen is g2D.drawImage() met de juiste transformatie.

[ Voor 31% gewijzigd door .oisyn op 17-01-2007 17:42 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

.oisyn schreef op woensdag 17 januari 2007 @ 17:38:
[...]

Dit zorgt dat de kaarten niet buiten een bepaald gebied tekenen, niet dat de tafel weer automagisch tevoorschijn komt als je de kaarten later op een andere plek tekent ;)
Nee, dat de tafel automatisch terug zou komen bedoelde ik ook niet, maar ik meende dat het reeds getekende stuk buit de clip region niet invalidated wordt op die manier. (wat een vage zin!)
Ben even te lui om nu uit te zoeken of het ook echt zo gaat. :p

Het plaatje van de tafel (waarvan de grootte afhankelijk is van de venstergrootte) kun je trouwens ook bufferen. Bij een resize event moet je dan even een nieuw plaatje maken.

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


  • 0123456
  • Registratie: Maart 2005
  • Laatst online: 28-07-2010
Ok, ik snap wat jullie bedoelen, maar het traag laden van de plaatjes is niet het probleem (ziet er wel leuk uit)

Het probleem is nu dus, dat als ik het frame ga resize of een ander venster voor het frame zet, dat dan alles op het frame weg is (alleen het laatste plaatje staat er nog)...
Is het mogelijk om alles te bufferenof in ieder geval te laten staan als ik weer terug ga naar het frame???

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Ik weet toch echt wel bijna zeker dat je beter de plaatjes slechts 1 keer in kunt laden. ;)

Misschien is het handig om even wat meer documentatie te lezen, zoals: Painting in AWT en Swing.

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


  • 0123456
  • Registratie: Maart 2005
  • Laatst online: 28-07-2010
Ja, ik snap dat het beter is maar daar gaat het op het moment niet om..
Dit komt later nog wel..

Waar het me nu om gaat is dat het scherm weer terug komt als er een ander scherm overheen gaat of als het geresized wordt....
Weet iemand hoe ik dit doe???

  • Upsal
  • Registratie: Mei 2005
  • Laatst online: 27-08-2024
0123456 schreef op woensdag 17 januari 2007 @ 19:31:
Ja, ik snap dat het beter is maar daar gaat het op het moment niet om..
Dit komt later nog wel..

Waar het me nu om gaat is dat het scherm weer terug komt als er een ander scherm overheen gaat of als het geresized wordt....
Weet iemand hoe ik dit doe???
Dat komt omdat repaint() niet alleen door je programma intern wordt aangeroepen, maar ook door Java/Windows (bij het resizen/minimaliseren van je scherm).

Ik denk dat die link van zwippie wel van pas kan komen.
Pagina: 1