簡體   English   中英

如何在JFrame中的JPanel中正確重繪

[英]How to repaint properly in JPanel inside JFrame

stackoverflow社區! 我正在用JAVA制作基於GUI的小型游戲。 我現在有一些麻煩。 為了讓您對我的程序有基本的了解,

我有一個窗口,首先顯示菜單(JPanel)。 當我點擊“開始游戲”按鈕時。 它進入另一個我可以玩游戲的JPanel。 ![menu_window] [1]

我有一個計時器在處理定期移動的小子彈。 每次計時器工作時,面板都會重新繪制項目符號。 我可以看到repaint方法有效,但是它不會刪除以前的跟蹤。

![在此處輸入圖片描述] [2]

這是我的主班

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main {
    private final int window_x_size = 500;
    private final int window_y_size = 500;

    private JFrame frame;
    private JPanel Menu;
    private Game myGame = new Game();//extends from JPanel



    private JButton startButton = new JButton("Game Start");
    private JButton exitButton = new JButton("Game Exit");
    private JButton showRank = new JButton("Rank");
    private JButton OneOnOne = new JButton("One on One");


    private ActionListener MyButtonListener = new MyButtonListener();
    public class MyButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();

            if (source == startButton) {

                frame.remove(Menu);
                frame.setContentPane(myGame);
                frame.validate();
                frame.repaint(); // prefer to write this always.

            } else if (source == exitButton) {
                System.exit(1);
            } else if (source == showRank) {

            } else {// one on one

            }

        }
    }


    public Main() {
        frame = new JFrame();

        frame.setBackground(Color.white);
        frame.setSize(window_x_size, window_y_size);
        frame.setTitle("My First GUI Game");
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);

        Menu = new JPanel();
        startButton.addActionListener(MyButtonListener);
        exitButton.addActionListener(MyButtonListener);
        showRank.addActionListener(MyButtonListener);
        OneOnOne.addActionListener(MyButtonListener);

        Menu.setLayout(new GridLayout(4, 1));
        Menu.add(startButton);
        Menu.add(OneOnOne);
        Menu.add(showRank);
        Menu.add(exitButton);

        frame.setContentPane(Menu);
        frame.setVisible(true);

    }

    public static void main(String[] args) {
        /*
         * This is the most important part of your GUI app, never forget 
         * to schedule a job for your event dispatcher thread : 
         * by calling the function, method or constructor, responsible
         * for creating and displaying your GUI.
         */
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {  
                new Main();
            }
        });


    }

}

這是我的游戲課

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Game extends JPanel {
    private Random rnd = new Random();
    private ActionListener MyBulletListener = new BulletListener();
    public KeyListener myKeyListen = new MyKeyListener();
    Timer bullet_timer;

    private boolean IsExplosion = false;
    private ImageIcon spacecraftImg = new ImageIcon("spacecraft.png");
    private Rectangle spacecraftBox = new Rectangle(5, 10,
            spacecraftImg.getIconWidth(), spacecraftImg.getIconHeight());
    private ImageIcon explosionImg = new ImageIcon("explosion.png");
    private ImageIcon bulletImg = new ImageIcon("bullet.png");
    private Rectangle bulletBox = new Rectangle(70, 200,
            bulletImg.getIconWidth(), bulletImg.getIconHeight());

    private MySound explosion_sound = new MySound();

    public Game() {

        addKeyListener(myKeyListen);
        bullet_timer = new Timer(500, MyBulletListener);
        bullet_timer.start();

    }

    public class MyKeyListener implements KeyListener {

        private int x;
        private int y;

        @Override
        public void keyPressed(KeyEvent e) {

            // TODO Auto-generated method stub
            int keyCode = e.getKeyCode();

            if (keyCode == 37) {
                x = -10;
                y = 0;

            } else if (keyCode == 38) {
                x = 0;
                y = -10;
            } else if (keyCode == 39) {
                x = 10;
                y = 0;
            } else {
                x = 0;
                y = 10;
            }
            if (spacecraftBox.x + x < 0
                    || spacecraftBox.x + x > 500
                    || spacecraftBox.y + y < 0
                    || spacecraftBox.y + y > 500) {

            } else {
                move_plane(x, y);
                repaint();
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }

    }
    public class BulletListener implements ActionListener {
        private int x;
        private int y;

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            Object source = e.getSource();
            if (source == bullet_timer) {

                int dir = rnd.nextInt(4);
                if (dir == 0) {// move left
                    x = -10;
                    y = 0;
                } else if (dir == 1) {// move right
                    x = 10;
                    y = 0;
                } else if (dir == 2) {// move up
                    x = 0;
                    y = -10;
                } else {// move down
                    x = 0;
                    y = 10;
                }
                if (bulletBox.x + x < 0
                        || bulletBox.x + x > 500
                        || bulletBox.y + y < 0
                        || bulletBox.y + y > 500) {

                } else {
                    move_bullets(x, y);
                    repaint();
                }
            }

        }
    }


    @Override
    public void paint(Graphics g) {

        g.drawImage(bulletImg.getImage(), (int) bulletBox.getX(),
                (int) bulletBox.getY(), null);

        g.drawImage(spacecraftImg.getImage(), (int) spacecraftBox.getX(),
                (int) spacecraftBox.getY(), null);

        if (IsExplosion) {
            g.drawImage(explosionImg.getImage(), (int) bulletBox.getX(),
                    (int) bulletBox.getY(), null);
            MySound.play();
            IsExplosion = false;

        }

    }

    public void move_plane(int x, int y) {

        spacecraftBox.translate(x, y);

        if (spacecraftBox.intersects(bulletBox)) {
            IsExplosion = true;
        }
    }

    public void move_bullets(int x, int y) {
        bulletBox.translate(x, y);

        if (spacecraftBox.intersects(bulletBox)) {
            IsExplosion = true;
        }
    }

}

另外,我添加了KeyListener,但是它不起作用。 我不知道如何解決它。

我嘗試使用Google搜索該問題。 我嘗試了以主要班級為重點的游戲面板,但是沒有用。

我將衷心感謝您的幫助。

最好的祝福,

Dongseop

這幾乎總是由於您的繪畫方法未調用super的繪畫方法來清除臟像素而引起的。 由於您要覆蓋繪畫,因此需要調用super.paint(g); 作為繪畫替代中的第一個方法調用。

其他事宜:

  • 接下來,我建議您不要覆蓋paint,而要覆蓋paintComponent(Graphics g) ,因為這將使您的動畫具有自動雙重緩沖,並使動畫更加平滑。 再次,調用super.paintComponent(g); 在您的方法中覆蓋。
  • 交換視圖的最簡單方法是使用CardLayout。
  • 最好使用KeyBindings而不是KeyListener,因為這將幫助您解決KeyListener的焦點問題,該問題可能會阻止KeyListener正常工作。 它還允許您使用可重復使用的操作。 請在KeyListeners上搜索此站點,以了解我的意思並查看鍵綁定的示例(某些示例由我執行)。 另外,請參閱Google Java Key Bindings Tutorial以了解有關如何使用它們的官方教程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM