7
votes

Java Panel double tampon

Je me suis demandé si quelqu'un pouvait me diriger dans le bon directoire, j'ai développé un jeu de pong et il a besoin de double tampon en raison de scintillement. Iv essayé une partie du message ici pour essayer de le faire fonctionner, mais je suis toujours débutant avec le swing Awt suffe, toute aide serait incroyable merci.

public class PongPanel extends JPanel implements Runnable {

private int screenWidth = 500;
private int screenHeight = 300;

private boolean isPaused = false;
private boolean isGameOver = false;

private int playToPoints = 10;

private Padel player1,player2;
private Ball ball;

private Thread gameThread;
private Image dbImage;
private Graphics dbg; 

public PongPanel() {
   setPreferredSize(new Dimension(screenWidth,screenHeight));
   setBackground(Color.BLACK);
   setDoubleBuffered(true);
   setFocusable(true);
   requestFocus();

   player1 = new Padel(Position.LEFT,screenWidth,screenHeight);
   player2 = new Padel(Position.RIGHT,screenWidth,screenHeight);
   ball = new Ball(10,screenWidth/2,screenHeight/2,Color.WHITE);
}

public void addNotify(){
 super.addNotify();
   startGame();
}

private void startGame(){
  gameThread = new Thread(this);
  gameThread.start();
}

@Override
public void run() {
 while (!isGameOver) {   
 dbImage = createImage(screenWidth,screenHeight);
 dbg = this.getGraphics();
 if(!isPaused){
   if(!gameOverCheck()){
     updateGame();
     paintComponents(dbg);   
    }
 }else if(isPaused){
    dbg.setColor(Color.ORANGE);
    dbg.setFont(new Font("serif",Font.BOLD,50));
    dbg.drawString("Paused", screenWidth/2-82, screenHeight/2);
 } 
 try {
     Thread.sleep(30);
    } catch (InterruptedException e) {e.printStackTrace();}
   }
   }

  private boolean gameOverCheck(){
  if(player1.getScore() == playToPoints){
   dbg.setColor(player1.getColour());
   dbg.setFont(new Font("serif",Font.BOLD,50));
   dbg.drawString("Player 1 Wins!", screenWidth/2 - 161, screenHeight/2);
   setGameOver(true);
   return true;
  }else if(player2.getScore() == playToPoints){
   dbg.setColor(player2.getColour());   
   dbg.setFont(new Font("serif",Font.BOLD,50));
   dbg.drawString("Player 2 Wins!", screenWidth/2 - 161, screenHeight/2);
   setGameOver(true);
   return true;
  }

  return false;
 }

 private void updateGame(){
  ball.move(screenWidth,screenHeight,player1,player2);
  player1.aiForPadel(screenWidth, screenHeight, ball.getX(), ball.getY());
  player2.aiForPadel(screenWidth, screenHeight, ball.getX(), ball.getY());

 }

  @Override
  public void paintComponents(Graphics g) {
  super.paintComponents(g);
  dbg.setColor(Color.BLACK);
  dbg.fillRect(0, 0, screenWidth+20, screenHeight+20);
  dbg.setColor(Color.WHITE);
  dbg.drawLine(screenWidth/2, 0, screenWidth/2, screenHeight);
  dbg.setFont(new Font("serif",Font.BOLD,32));
  dbg.drawString(player1.getScore()+"", screenWidth/2-40, screenHeight - 20);
  dbg.drawString(player2.getScore()+"", screenWidth/2+20, screenHeight - 20);
  ball.drawBall(dbg);
    player1.drawPadel(dbg);
    player2.drawPadel(dbg);
 }
}


0 commentaires

4 Réponses :


6
votes

Il y a un très bon tutoriel ici qui explique comment utiliser Buffstrategy pour produire une animation non vacillante.

Les points importants sont:

  • Call seignorerepaint (true) sur le niveau supérieur Toile pour empêcher le REWT de le repeindre, car vous le ferez généralement dans la boucle d'animation. < / li>
  • Obtenez le graphiques2d objet à partir du bufferstrategy (plutôt que d'utiliser l'instance passée via PaintComponent (graphiques g) . .

0 commentaires

3
votes

une lecture incontournable sur le mécanisme de peinture dans AWT et Swing

peinture dans AWT et Swing


1 commentaires

Bien que cela puisse théoriquement répondre à la question, Ce serait préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence.



-1
votes

Je pense que vous pouvez simplement appeler super (vrai); code> La première chose, et cela indique simplement le jPanel code> qu'il est double tampon ... car l'un des constructeurs code> jPanel code> est le suivant:

public Jpanel(boolean isDoubleBuffered) {...}


1 commentaires

Le constructeur par défaut JPanel l'appelle déjà: public jPanel () {ceci (vrai); }



2
votes

Le problème de base est que vous enfreignez le système de peinture de base du swing. Swing utilise un algorithme "rendu passive", où les peintures ne sont effectuées que lorsque elles doivent être. Vous pouvez faire des suggestions à l'API lorsque quelque chose doit être mis à jour via l'appel code> code> appelé.

En fonction de votre code, le problème de base est, vous appelez PETECOMPONENTS CODE> Avec votre propre contexte code> graphiques CODE>, mais le système est ensuite en train de la prendre avec sa passe de peinture de peinture, vous combattez le système de peinture plutôt que de travailler avec elle. P>

Si c'est fait correctement, Les composants balançoires sont déjà tamponnés doubles, de sorte que vous n'avez pas besoin de faire quoi que ce soit "extra", autre que le travail réel avec l'API / SYSTEM. P>

i Strongement strong> Recommandez avoir un look AT: P>

  • Effectuer une peinture personnalisée li>
  • Peinture dans AWT et Swing LI> ul>

    Pour mieux comprendre comment la peinture fonctionne en swing. P>

    Donc, commençons par ... P>

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.text.Position;
    
    public class PongPanel extends JPanel implements Runnable {
    
        private int screenWidth = 500;
        private int screenHeight = 300;
    
        private boolean isPaused = false;
        private boolean isGameOver = false;
    
        private int playToPoints = 10;
    
        private Padel player1, player2;
        private Ball ball;
    
        private Timer gameThread;
    
        public PongPanel() {
            setPreferredSize(new Dimension(screenWidth, screenHeight));
            setBackground(Color.BLACK);
            setDoubleBuffered(true);
            setFocusable(true);
            requestFocus();
    
            player1 = new Padel(Position.LEFT, screenWidth, screenHeight);
            player2 = new Padel(Position.RIGHT, screenWidth, screenHeight);
            ball = new Ball(10, screenWidth / 2, screenHeight / 2, Color.WHITE);
        }
    
        public void addNotify() {
            super.addNotify();
            startGame();
        }
    
        private void startGame() {
            gameThread = new Timer(30, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    updateGame();
                    gameOverCheck();
                    if (isGameOver) {
                        repaint();
                        return;
                    }
                    if (!isPaused) {
                        if (!gameOverCheck()) {
                            updateGame();
                        }
                    }
                    repaint();
                }
            });
            gameThread.start();
        }
    
        private boolean gameOverCheck() {
            if (player1.getScore() == playToPoints) {
                setGameOver(true);
                return true;
            } else if (player2.getScore() == playToPoints) {
                setGameOver(true);
                return true;
            }
    
            return false;
        }
    
        private void updateGame() {
            ball.move(screenWidth, screenHeight, player1, player2);
            player1.aiForPadel(screenWidth, screenHeight, ball.getX(), ball.getY());
            player2.aiForPadel(screenWidth, screenHeight, ball.getX(), ball.getY());
    
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponents(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.BLACK);
            g2d.fillRect(0, 0, screenWidth + 20, screenHeight + 20);
            g2d.setColor(Color.WHITE);
            g2d.drawLine(screenWidth / 2, 0, screenWidth / 2, screenHeight);
            g2d.setFont(new Font("serif", Font.BOLD, 32));
            g2d.drawString(player1.getScore() + "", screenWidth / 2 - 40, screenHeight - 20);
            g2d.drawString(player2.getScore() + "", screenWidth / 2 + 20, screenHeight - 20);
            ball.drawBall(g2d);
            player1.drawPadel(g2d);
            player2.drawPadel(g2d);
    
            if (isGameOver) {
                if (player1.getScore() == playToPoints) {
                    g2d.setColor(player1.getColour());
                    g2d.setFont(new Font("serif", Font.BOLD, 50));
                    g2d.drawString("Player 1 Wins!", screenWidth / 2 - 161, screenHeight / 2);
                } else if (player2.getScore() == playToPoints) {
                    g2d.setColor(player2.getColour());
                    g2d.setFont(new Font("serif", Font.BOLD, 50));
                    g2d.drawString("Player 2 Wins!", screenWidth / 2 - 161, screenHeight / 2);
                }
            } else if (isPaused) {
                g2d.setColor(Color.ORANGE);
                g2d.setFont(new Font("serif", Font.BOLD, 50));
                g2d.drawString("Paused", screenWidth / 2 - 82, screenHeight / 2);
            }
    
            g2d.dispose();
        }
    }
    
    • Swing n'est pas le fil de sécurité, vous ne devez pas mettre à jour l'interface utilisateur de l'extérieur du contexte de l'événement Dispatching thread Li>
    • Vous ne devez jamais appeler directement la méthode code> de peinture code>. Le système effectuera cette opération lorsqu'il souhaite mettre à jour votre composant. LI> ul>

      Je recommande vivement de lire: p>


0 commentaires