# Von Canvas (mit BufferStrategy) zu Applet



## fallencake (15. Apr 2009)

Hi Forum
Ich bastle im Moment selbst ein Game und habe hier schon das ein oder andere gelesen. Nun würde ich mein Game gerne als Applet veröffentlichen. Da ich aber von Applets keine Ahnung habe und mein Game als Canvas aufgebaut ist will ich bei euch mal um Hilfe fragen.

Hier mal als mehr oder weniger Pseudocode wie mein Game aufgebaut ist:

```
public class Game extends Canvas {
private BufferStrategy strategy;
public Game() {
        //Fenster init:
        JFrame frame = new JFrame("Game");
        JPanel panel = (JPanel) frame.getContentPane();
        panel.setPreferredSize(new Dimension(windowx, windowy));
        panel.setLayout(null);
        setBounds(0,0,windowx,windowy);
        panel.add(this);
        setIgnoreRepaint(true);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        requestFocus();

        createBufferStrategy(2);
        strategy = getBufferStrategy();
        Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
        g.setColor(Color.black);
        g.fillRect(0, 0, windowx, windowy);
        g.dispose();
        strategy.show();
        run();
}

run() {
        while(true) {
                //Berechnen, Bewegen, etc

                Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
                g.setColor(Color.black);
                g.fillRect(0, 0, windowx, windowy);
                //Noch weitere Sachen zeichnen
                g.dispose();
                strategy.show();
                try { Thread.sleep(looptime); } catch(Exception e) {};
        }
}
}
```

Wie kann ich dass nun am besten in ein Applet packen?

Meine ganzen Erfahrungen mit Applets:

```
public class AppletTester extends Applet {
    public void paint(Graphics g) {
        g.drawString("Hello world!", 50, 25);
    }

}
```

.. ^^

Könnte ich das oben erstellte Canvas einfach ihrgendwie ins Applet packen so dass ich es gar nicht verändern muss?

Vielen Dank für eure Hilfe/Tipps

Gruss
fallencake


----------



## SlaterB (15. Apr 2009)

> Meine ganzen Erfahrungen mit Applets

musst du erweitern auf Applets nicht nur mit paint sondern auch/ vor allem mit JPanel, JButton & Co.,
findet man doch in jedem Lehrbuch oder wenn man allein bei google > 1 Seiten zu Applets anschaut..

kurz gesagt musst du in der init-Methode das Canvas adden, so wie du es zum ContentPane des JFrame hinzufügst

dass du mindestens zwei Klassen brauchst (Applet + Canvas) sollte wohl noch erwähnt werden


----------



## fallencake (15. Apr 2009)

Hey
Ich weiss war ne einfache Frage.
Ich hab gest Nacht gegooglet, aber ihrgendwie... War wohl schon zu spät :/


SlaterB hat gesagt.:


> kurz gesagt musst du in der init-Methode das Canvas adden, so wie du es zum ContentPane des JFrame hinzufügst


Thx, jetzt klappts (ka was ich gestern verbrochen hab).

Vielleicht kommen auch mal noch anspruchsvollere Fragen 
Gruss
fallencake


----------



## fallencake (15. Apr 2009)

Leider habe ich es doch noch nicht ganz hinbekommen.
 Wenn ich es einfach adde funktioniert es, allerdings in einem neuen Fenster:

```
public class GameApplet extends Applet {
     public void init() {
         Game game = new Game();
     }
 }
```


```
public Game() {
         
         game=this;
         //Fenster init:
         JFrame frame = new JFrame("Game");
         JPanel panel = (JPanel) frame.getContentPane();
         
         panel.setPreferredSize(new Dimension(windowx, windowy));
         panel.setLayout(null);
         setBounds(0,0,windowx,windowy);
         panel.add(this);
         setIgnoreRepaint(true);
         frame.pack();
         frame.setResizable(false);
         frame.setVisible(true);
         frame.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 System.exit(0);
             }
         });
         
         requestFocus();
         
         //Key Listerner adden
         addKeyListener(new KeyInputHandler());
         
         createBufferStrategy(2);
         strategy = getBufferStrategy();
         //schwarz zeichnen
         Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
         g.setColor(Color.black);
         g.fillRect(0, 0, windowx, windowy);
         g.dispose();
         strategy.show();
         
     initGame();
     
     }
```
 
 Wenn ich es so machen will, dass es im gleichen Fenster angezeigt wird, sehe ich einfach ein leeres Fenster (mit der richtigen Grösse).

```
public class GameApplet extends Applet {
     public void init() {
         this.setSize(new Dimension(1000, 700));
         Panel p = new Panel();
//Panel zuerst zu Appled adden, damit ich in Game createBufferStrategy(2) aufrufen kann
         add(p);
 
         Game game = new Game(p);
     }
 }
```


```
public Game(Panel panel) {
         
         game=this;
 
         panel.setPreferredSize(new Dimension(windowx, windowy));
         panel.setLayout(null);
         setBounds(0,0,windowx,windowy);
         panel.add(this);
 
         setIgnoreRepaint(true);
 
         
         requestFocus();
         
         //Key Listerner adden
         addKeyListener(new KeyInputHandler());
         panel.setVisible(true);
         createBufferStrategy(2);
         strategy = getBufferStrategy();
         //schwarz zeichnen
         Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
         g.setColor(Color.black);
         g.fillRect(0, 0, windowx, windowy);
         g.dispose();
         strategy.show();
         
     initGame();
     
     }
```

Kann mir wer sagen was ich hier falsch mache? Ich nehme an, dass es irgendwas mit repaint() zu tun hat. Oder dass ich irgendwie das falsche Graphics2D Element von strategy.getDrawGraphics() bekomme.

Herzlichen Dank schonmal
Gruss
fallencake


----------



## SlaterB (15. Apr 2009)

geht es ohne die run-Methode?

immer ganz einfach anfangen,
erstmal nur ein Label/ JLabel mit "Hello World" anzeigen und dann Schritt für Schritt mehr

die run-Methode im ursprünglichen Programm wurde aus dem Konstruktor aufgerufen (der damit nie beendet wird..),
beschäftigte wahrscheinlich den main-Thread von public static void main() aus,

wenn beim Applet der gleiche Thread, der später zeichnen soll, die run()-Methode abarbeiten muss,
wird nicht oder nur rudimentär gezeichnet (Vermutung)


----------



## fallencake (15. Apr 2009)

Hey


			
				SlaterB hat gesagt.:
			
		

> die run-Methode im ursprünglichen Programm wurde aus dem Konstruktor aufgerufen (der damit nie beendet wird..),
> beschäftigte wahrscheinlich den main-Thread von public static void main() aus,
> 
> wenn beim Applet der gleiche Thread, der später zeichnen soll, die run()-Methode abarbeiten muss,
> wird nicht oder nur rudimentär gezeichnet (Vermutung)


Habe ich das jetzt richtig verstanden?: Du meinst, weil im Game() ja eine while(true) Schleife benutzt wird (Die run() Methode) kommt der Thread in der GameApplet Klasse nie über Game game = new Game(p); raus?
Falls ja, das stimmt und zwar beim Aufruf von initGame();. Das habe ich jetzt allerdings mal rausgenommen und nun müsste es schwarz gezeichnet werden. 


```
public class GameApplet extends Applet {
    public void init() {
        this.setSize(new Dimension(1000, 700));
        Panel p = new Panel();
        add(p);

        Game game = new Game(p);
        System.out.println("blah");
    }
}
```
blah wird ausgegeben. Leider bleibt das Applet aber weiss.



			
				SlaterB hat gesagt.:
			
		

> immer ganz einfach anfangen,
> erstmal nur ein Label/ JLabel mit "Hello World" anzeigen und dann Schritt für Schritt mehr


Eigentlich hatte ich nicht vor mich *im Moment* tiefer mit Applets zu beschäftigen.. Ich will nur mein Game auf einer Homepage veröffentlichen (Ohne es in einem zusätzlichen Fester zu öffnen).
Gibt es denn kein kleines Beispiel in dem ein Canvas auf ein Panel gepackt und dieser Panel aufs Applet gepackt wird und Canvas eine BufferStrategy nutzt?


PS: Wenn ich Game game = new Game(p); vor GameApplet.add(p); mache bekomme ich: java.lang.IllegalStateException: Component must have a valid peer beim Aufruf von Game.createBufferStrategy(2);


----------



## SlaterB (15. Apr 2009)

tja, zu BufferStrategy weiß ich nix, habe auch noch nie eine Internetseite dazu gesehen,
Applets verwende ich auch nicht,
da muss wohl jemand anders weiterhelfen

BufferStrategy java applet - Google-Suche
erster Link: dieses Thema hier 
aber bisschen mehr gibts da auch, z.B.
BufferStrategy and white rows of pixels - Java Forums

dort wird ein echter Thread gestartet (Runnable, Thread t = new Thread(this);      t.start(); )
vielleicht was für dich


----------



## fallencake (15. Apr 2009)

> erster Link: dieses Thema hier
:shock:

Ich habe mir noch Quaxli's Spiele Tutorial halb durchgelesen. In seinem 2ten Beispiel macht er es genau gleich wie ich mit der BufferStrategy.

```
createBufferStrategy(2);
strategy = getBufferStrategy();
```
So unüblich ist das also wohl nicht 
Und irgendwer muss doch sicher schon mal auf die Idee gekommen sein ein Game das auf diese Art programmiert wurde in ein Applet zu setzen..


Eigentlich würde ich gerne darauf verzichten das Game für das Applet gross um zu bauen.

Ich habe mir aber trozdem mal ein bisschen die Applets angeschaut und das hier gebastelt:

```
public class GameApplet extends JApplet implements Runnable {
    int timer;
    public void init() {

        this.setSize(new Dimension(1000, 700));
        Thread t = new Thread(this);
        t.start();
    }
    
    public void paint(Graphics g) {
        super.paint(g);
        Color c = Color.green;
        for(int i = 0;i<timer;i++) {
            c=c.darker();
        }
        g.setColor(c);
        g.fillRect(0, 0, 1000, 700);
        

    }
    public void run() {
        
        while(true) {
            timer++;
            this.repaint();

            try { Thread.sleep(300); } catch(Exception ex) {}
        }
    }
}
```
So kann man Animationen (Hier ein Farbverlauf) im Applet machen. Aber es ist nicht gebuffert und ja müsste einiges umschreiben um mein Game so sauber umzuschreiben.


Hoffe jemand weiss noch n bisschen mehr 

Gruss


----------



## fallencake (17. Apr 2009)

Also ich habe es nicht hinbekommen und lasse es erstmal als Frame.

Wer mal reinschnuppern will:
AGGRA - The Space Game

Ein Ziel gibt es noch nicht und hat auch noch den ein oder anderen Bug..


----------

