Avatar billede soren112 Nybegynder
12. oktober 2001 - 12:46 Der er 8 kommentarer og
1 løsning

java2d og double buffer

Jeg er ved at lave en skabelon til noget java2d men har lidt problemer.
Jeg vil gerne have skiftet \"g2d.drawString(\"TEST\", posX, posY)\" ud med et billede (pic.gif) der bliver vist på posX, posY. Billedet skal ikke \"blinke\" ligesom teksten gør(prøv programmet..)
Jeg ønsker helst noget kode jeg kan copy and paste direkte ind i kode... men et link eller gode hints er også ok.

Min kode:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Gui extends JFrame implements WindowListener, KeyListener, MouseMotionListener, Runnable{
   
    private int frameWidth = 640;
    private int frameHeight = 480;
    private int posX = 40;
    private int posY = 40;
    private Thread internalThread;
    private boolean running = true;
   
    public Gui(){
        createFrame();
        internalThread = new Thread(this);
        internalThread.start();   
    }

    private void createFrame(){
        setTitle(\"Eksperiment1\");
        setResizable(false);
        addKeyListener(this);       
        addWindowListener(this);
        addMouseMotionListener(this);
       
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setSize(new java.awt.Dimension(frameWidth, frameHeight));
        setLocation((screenSize.width-frameWidth)/2,(screenSize.height-frameHeight)/2);
    }
   
    public void run(){
        while(running){
            try{
                Thread.sleep(16);
            }
            catch(InterruptedException e){
                Thread.currentThread().interrupt();
            }
            repaint();
        }
       
    }
    public void paint(Graphics g){
        Graphics2D g2d = (Graphics2D) g;
        super.paint(g2d);
        g2d.drawString(\"TEST\", posX, posY);
    }
   
    public void keyPressed(KeyEvent k){
        if(k.getKeyCode()==27){
            running = false;
            System.exit(0);
        }
    }
    public void keyReleased(KeyEvent evt){}
    public void keyTyped(KeyEvent evt){}
    public void windowOpened(WindowEvent evt){}
    public void windowClosing(WindowEvent evt){    System.exit(0);}
    public void windowClosed(WindowEvent evt){}
    public void windowIconified(WindowEvent evt){}
    public void windowDeiconified(WindowEvent evt){}
    public void windowActivated(WindowEvent evt){}
    public void windowDeactivated(WindowEvent evt){}
    public void mouseDragged(MouseEvent evt){}
    public void mouseMoved(MouseEvent evt){
        posX = evt.getX();
        posY = evt.getY();
    }
}

class Main{
    public static void main(String args[]){
          new Gui().show();
    }
}

Mvh
Søren Olesen
Avatar billede disky Nybegynder
12. oktober 2001 - 13:01 #1
jeg bruger denne her til at dobbeltbuffere med, og det virker :)

import java.awt.*;
import java.applet.*;

public class DoubleBufferApplet extends Applet
{
    // The width and height of our offscreen image
    private int width=-1;
    private int height=-1;
   
    // The offscreen image
    private Image offscreen;
   
    // switch: are we double buffering or not?
    private boolean dbon = true;
   
    // Use this to turn double buffering on and off
    protected void setDoubleBuffering( boolean dbon )
    {
        this.dbon = dbon;
        if (!dbon)
        {
            offscreen = null;
        }
    }
   
    // Depending on the value of our switch, we either call our
    // special code, or just call the default code
    public void update( Graphics g )
    {
        if (dbon)
        {
            updateDoubleBufffered( g );
        }
        else
        {
            super.update( g );
        }
    }
   
    // Do the drawing to an offscreen buffer -- maybe
    private void updateDoubleBufffered( Graphics g )
    {
       
        // Let\'s make sure we have an offscreen buffer, and that
        // it\'s the right size.  If the applet has been resized,
        // our buffer will be the wrong size and we need to make
        // a new one
        Dimension d = getSize();
        if (offscreen == null || width!=d.width || height!=d.height || offscreen==null)
        {
            width = d.width;
            height = d.height;
            if (width>0 || height>0)
            {
                offscreen = createImage( width, height );
            }
            else
            {
                offscreen = null;
            }
        }
       
        // If we still don\'t have one, give up
        if (offscreen == null) return;
       
        // Get the off-screen graphics object
        Graphics gg = offscreen.getGraphics();
       
        // Clear the off-screen graphics object
        gg.setColor( getBackground() );
        gg.fillRect( 0, 0, width, height );
        gg.setColor( getForeground() );
       
        // Draw to the off-screen graphics object
        paint( gg );
       
        // We don\'t need this Graphics object anymore
        gg.dispose();
       
        // Finally, we transfer the newly-drawn stuff right to the
        // screen
        g.drawImage( offscreen, 0, 0, null );
    }
}
Avatar billede soren112 Nybegynder
12. oktober 2001 - 13:42 #2
tjaaa, det virker sikkert, men hvordan viser jeg et billede der er double duffered? (Jeg er lidt lost..)
Avatar billede disky Nybegynder
12. oktober 2001 - 13:48 #3
du får lige resten med. Det her er dog fra en applet.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;

//Tråden i denne klasse styrer hvor tit selve skærmen skal opdateres.

public class Pacman extends DoubleBufferApplet implements java.lang.Runnable, KeyListener
{
    private Ghost ghost1,ghost2,ghost3,ghost4;
   
    private Image player;
    private Thread thread=null;
    private URL codeBase=null;

    int x=100;
    int y=100;
   
    public void init()
    {
        codeBase=getCodeBase();
        addKeyListener(this);
               
        Image tmp=getImage(codeBase,\"test.gif\");       
        ghost1=new Ghost(tmp,300,180);

        tmp=getImage(codeBase,\"test.gif\");       
        ghost2=new Ghost(tmp,340,180);
       
        tmp=getImage(codeBase,\"test.gif\");       
        ghost3=new Ghost(tmp,300,220);

        tmp=getImage(codeBase,\"test.gif\");       
        ghost4=new Ghost(tmp,340,220);

        player=getImage(codeBase,\"test.gif\");       
               
        thread=new Thread(this);
        ghost1.start();
        ghost2.start();
        ghost3.start();
        ghost4.start();
        thread.start();
        setDoubleBuffering( true );
    }
   
    public void paint( Graphics g )
    {
        g.drawImage(player,x,y,this);

        ghost1.paint(g);
        ghost2.paint(g);
        ghost3.paint(g);
        ghost4.paint(g);
    }
   
    public void run()
    {
        while(true)
        {
            repaint();
            handlePlayer();
            try
            {
                Thread.sleep(50);
            }
            catch( InterruptedException ie )
            {
            }
        }
    }
   
/** This function handles everything about the player.
* That is collision control, checking to see if a pellet or a fruit has been eaten,
* updating the score, and se if a ghost has catched the player.
*/   
    private void handlePlayer()
    { 
    }
   
    public void keyReleased(java.awt.event.KeyEvent e)
    {
    }
   
    public void keyPressed(java.awt.event.KeyEvent e)
    {
        handleKey(e);
    }
   
    public void keyTyped(java.awt.event.KeyEvent e)
    {
    }
   
    private void handleKey(KeyEvent e)
    {
        switch(e.getKeyCode())
        {
            case java.awt.event.KeyEvent.VK_LEFT:
                x-=2;
                break;
            case java.awt.event.KeyEvent.VK_RIGHT:
                x+=2;
                break;
            case java.awt.event.KeyEvent.VK_DOWN:
                y+=2;
                break;
            case java.awt.event.KeyEvent.VK_UP: //up
                y-=2;
                break;
        }
        e.consume();
    }
}




Og den sidste fil:

/*
* Ghost.java
*
* Created on 18. februar 2001, 18:55
*/

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;

/**
*
* @author  administrator
* @version
*/
public class Ghost extends DoubleBufferApplet implements java.lang.Runnable
{
    private Thread thread=null;
    private Image imgGhost=null;
    private int x,y; //ghost position
   
    /** Creates new Ghost */
    public Ghost(Image imgGhost,int x,int y)
    {
        this.imgGhost=imgGhost;
        this.x=x;
        this.y=y;
        thread=new Thread(this);
    }
     
    public void start()
    {
        thread.start();
    }
   
    public void paint( Graphics g )
    {
      g.drawImage(imgGhost,x,y,this);
    }
   
    public void run()
    {
        while(true)
        {
            try
            {
                if(Math.random()>0.5)
                {
                    x++;
                }
                else
                {
                    x--;
                }

                if(Math.random()>0.5)
                {
                    y++;
                }
                else
                {
                    y--;
                }
                Thread.sleep(50);
            }
            catch( InterruptedException e )
            {
                e.printStackTrace(System.out);
            }
        }
    }   
}
Avatar billede disky Nybegynder
12. oktober 2001 - 13:50 #4
Det der laver hele magien er denne metode:

    public void update( Graphics g )
    {
        if (dbon)
        {
            updateDoubleBufffered( g );
        }
        else
        {
            super.update( g );
        }
    }

Smid den ind i dit system, sammen med updateDoubleBuffered() Så skulle det spill + det løse   
Avatar billede soren112 Nybegynder
12. oktober 2001 - 14:07 #5
Jeg får en:
java.lang.StackOverflowError
    at sun.java2d.loops.ICRFillRectRasterContext.invoke(IntDiscreteRenderer.java:261)
    at sun.awt.image.BufferedImageGraphics2D.fillRect(BufferedImageGraphics2D.java:653)
    at sun.java2d.pipe.ValidatePipe.fillRect(ValidatePipe.java:42)
    at sun.java2d.SunGraphics2D.fillRect(SunGraphics2D.java:1560)
    at Gui.updateDoubleBufffered(Gui.java:70)
    at Gui.paint(Gui.java:50)
    at Gui.updateDoubleBufffered(Gui.java:72)
    at Gui.paint(Gui.java:50)
    at Gui.updateDoubleBufffered(Gui.java:72)

med følgende kode:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Gui extends JFrame implements WindowListener, KeyListener, MouseMotionListener, Runnable{
   
    private int frameWidth = 640;
    private int frameHeight = 480;
    private int posX = 40;
    private int posY = 40;
    private Thread internalThread;
    private boolean running = true;
    private boolean doubleBuffered = true;
    private Image offscreen;
    private int width=-1;
    private int height=-1;
   
    public Gui(){
        createFrame();
        internalThread = new Thread(this);
        internalThread.start();   
    }

    private void createFrame(){
        setTitle(\"Eksperiment1\");
        setResizable(false);
        addKeyListener(this);       
        addWindowListener(this);
        addMouseMotionListener(this);
   
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setSize(new java.awt.Dimension(frameWidth, frameHeight));
        setLocation((screenSize.width-frameWidth)/2,(screenSize.height-frameHeight)/2);
    }
   
    public void run(){
        while(running){
            try{
                Thread.sleep(16);
            }
            catch(InterruptedException e){
                Thread.currentThread().interrupt();
            }
            repaint();
        }
       
    }
    public void paint(Graphics g){
        if(doubleBuffered)
            updateDoubleBufffered(g);
        else
            super.paint(g);
    }
   
    private void updateDoubleBufffered(Graphics g){
        Dimension d = getSize();
        if(offscreen == null || width!=d.width || height!=d.height || offscreen==null){
            width = d.width;
            height = d.height;
            if(width>0 || height>0)
                offscreen = createImage(width, height);
            else
                offscreen = null;
        }
       
        if (offscreen == null) return;
       
        Graphics gg = offscreen.getGraphics();
        gg.setColor(getBackground());
        gg.fillRect(0, 0, width, height);
        gg.setColor(getForeground());
        paint(gg);
        gg.dispose();
        g.drawImage(offscreen, 0, 0, null);
    }

    public void keyPressed(KeyEvent k){
        if(k.getKeyCode()==27){
            running = false;
            System.exit(0);
        }
    }
    public void keyReleased(KeyEvent evt){}
    public void keyTyped(KeyEvent evt){}
    public void windowOpened(WindowEvent evt){}
    public void windowClosing(WindowEvent evt){    System.exit(0);}
    public void windowClosed(WindowEvent evt){}
    public void windowIconified(WindowEvent evt){}
    public void windowDeiconified(WindowEvent evt){}
    public void windowActivated(WindowEvent evt){}
    public void windowDeactivated(WindowEvent evt){}
    public void mouseDragged(MouseEvent evt){}
    public void mouseMoved(MouseEvent evt){
        posX = evt.getX();
        posY = evt.getY();
    }
}

class Main{
    public static void main(String args[]){
          new Gui().show();
    }
}
Avatar billede soren112 Nybegynder
12. oktober 2001 - 14:08 #6
og det fatter jeg ikke??
Avatar billede disky Nybegynder
12. oktober 2001 - 14:16 #7
du har glemt update metoden, det den normalt gør er at den bare kalder paint.

Men når du skal dobbeltbuffere, bytter den hele tiden rundt imellem 2 grafik områder så du ser det ene og tegner på det andet.

Og den funktionalitet, laver updateDoubleBufffered for dig
Avatar billede soren112 Nybegynder
12. oktober 2001 - 14:21 #8
Det virkede... Mange tak
For en god ordens skyld poster jeg lige det stykke kode der virker, hvis andre skulle være interesseret..
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Gui extends JFrame implements WindowListener, KeyListener, MouseMotionListener, Runnable{
   
    private int frameWidth = 640;
    private int frameHeight = 480;
    private int posX = 40;
    private int posY = 40;
    private Thread internalThread;
    private boolean running = true;
    private boolean doubleBuffered = true;
    private Image offscreen;
    private int width=-1;
    private int height=-1;
   
    public Gui(){
        createFrame();
        internalThread = new Thread(this);
        internalThread.start();   
    }

    private void createFrame(){
        setTitle(\"Eksperiment1\");
        setResizable(false);
        addKeyListener(this);       
        addWindowListener(this);
        addMouseMotionListener(this);
   
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setSize(new java.awt.Dimension(frameWidth, frameHeight));
        setLocation((screenSize.width-frameWidth)/2,(screenSize.height-frameHeight)/2);
    }
   
    public void run(){
        while(running){
            try{
                Thread.sleep(16);
            }
            catch(InterruptedException e){
                Thread.currentThread().interrupt();
            }
            repaint();
        }
       
    }
   
    public void update(Graphics g){
        if(doubleBuffered)
            updateDoubleBufffered(g);
        else
            super.update(g);
    }
   
    public void paint(Graphics g){
        g.drawString(\"TEST\", posX, posY);
    }
   
    private void updateDoubleBufffered(Graphics g){
        Dimension d = getSize();
        if(offscreen == null || width!=d.width || height!=d.height || offscreen==null){
            width = d.width;
            height = d.height;
            if(width>0 || height>0)
                offscreen = createImage(width, height);
            else
                offscreen = null;
        }
       
        if (offscreen == null) return;
       
        Graphics gg = offscreen.getGraphics();
        gg.setColor(getBackground());
        gg.fillRect(0, 0, width, height);
        gg.setColor(getForeground());
        paint(gg);
        gg.dispose();
        g.drawImage(offscreen, 0, 0, null);
    }

    public void keyPressed(KeyEvent k){
        if(k.getKeyCode()==27){
            running = false;
            System.exit(0);
        }
    }
    public void keyReleased(KeyEvent evt){}
    public void keyTyped(KeyEvent evt){}
    public void windowOpened(WindowEvent evt){}
    public void windowClosing(WindowEvent evt){    System.exit(0);}
    public void windowClosed(WindowEvent evt){}
    public void windowIconified(WindowEvent evt){}
    public void windowDeiconified(WindowEvent evt){}
    public void windowActivated(WindowEvent evt){}
    public void windowDeactivated(WindowEvent evt){}
    public void mouseDragged(MouseEvent evt){}
    public void mouseMoved(MouseEvent evt){
        posX = evt.getX();
        posY = evt.getY();
    }
}

class Main{
    public static void main(String args[]){
          new Gui().show();
    }
}
Avatar billede disky Nybegynder
12. oktober 2001 - 14:25 #9
Det glæder mig, god weekende.

Tak for point.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester