Рисование группы объектов в JPanel - PullRequest
0 голосов
/ 19 апреля 2020

Я довольно новичок в Java и мире GUI. Прямо сейчас я пытаюсь создать действительно базовый c космический шутер. Чтобы создать его, я начал создавать JFrame, в который позже я поместил личное расширение JPanel с именем GamePanel, на котором я сейчас пытаюсь отобразить все свои компоненты. Пока здесь все не ясно, проблема возникает: у меня есть GamePanel, в котором я показываю свой плеер, и при нажатии * S 1005 * игрок должен стрелять пулями. Я управлял пулями как массивом, называемым Shooter[], из Bullet объектов, созданных мной таким образом:

public class Bullet implements ActionListener{

    Timer Time = new Timer(20, this);

    private int BulletY = 430;
    public int PlayerX;
    public Rectangle Bound = new Rectangle();

    public Bullet(int playerx) {
        this.PlayerX = playerx;
        Time.start();
    }

    public void draw(Graphics g){
        g.setColor(Color.RED);
        g.fillRect(PlayerX + 2, BulletY, 3, 10);

        g.dispose();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (Time.isRunning()) {
            BulletY = BulletY - 5;
            Bound = new Rectangle (PlayerX + 2, BulletY, 3, 10);
        }
    }

}

Я думал, что вызов метода draw в GamePanel paint() метод позволил бы мне отобразить как все выстрелы пули, так и игрока. Что на самом деле происходит, так это то, что на старте все выглядит нормально, но когда я нажимаю S, игрок исчезает и выстреливает только одна пуля. Можете ли вы объяснить мне, почему? Вот как выглядит мой метод paint():

public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, 500, 500);

        for(int i = 0; i < BulletsCounter; i++) {
            Shooter[i].draw(g);
        }

        g.setColor(Color.RED);
        g.fillRect(PlayerX, PlayerY, 20, 20);

        //System.out.println("Here I should have painted the player...");

        g.dispose();
    }

BulletsCounter - это счетчик, который я создал, чтобы избежать каких-либо NullPointerException s при рисовании всего массива, он увеличивается при нажатии S и поэтому другая пуля массива инициализируется и выстреливает. Спасибо за ваше терпение, я новичок на сайте, поэтому предупредите меня за любую ошибку.

1 Ответ

2 голосов
/ 19 апреля 2020

У вас есть несколько значительных проблем, самая большая из которых указана первой:

  • Вы уничтожаете графический объект, предоставленный вам JVM. Никогда не делайте этого, так как это сломает цепь живописи. Вместо этого используйте только созданный вами графический объект.
  • Вы рисуете внутри краски, что не хорошо по нескольким причинам, но особенно плохо для анимации, поскольку у вас нет автоматов c double буферизация изображения
  • Вы не вызываете метод суперпокраски в своем переопределении и, следовательно, не позволяете JPanel выполнять покраску дома.

Рекомендации:

  • Не утилизируйте объект Graphics, если только вы сами его не создадите, например, если извлечете его из BufferedImage.
  • Переопределите метод JPCelel paintComponent, а не его рисование. метод, чтобы дать вам двойную буферизацию и более плавную анимацию.
  • И вызовите super.paintComponent(g) первым делом в переопределении, чтобы учесть рисование по хозяйству
...