JPanels не добавляются в JFrame - PullRequest
       104

JPanels не добавляются в JFrame

0 голосов
/ 03 августа 2020

Итак, я создавал эту очень простую игру и добавил все элементы (для движения), но когда я нажимаю «запустить», он показывает мне только JFrame, а не JPanel. Я должен упомянуть, что я новичок в Java, и код, который вы видите ниже, может быть не самым чистым (он также неполный).

Main

public class Main {
    public static void main(String[] args) {
       GameFrame frame = new GameFrame();
    }
}

   

GameFrame

public class GameFrame extends  JFrame {
         GamePanel panel;
     GameFrame() {
         panel = new GamePanel();
         this.add(panel);
         this.setTitle("Survival");
         this.setResizable(false);
         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         this.pack();
         this.setLocationRelativeTo(null);
         this.setVisible(true);
    }
}

Панель

public class GamePanel extends JPanel implements Runnable {
    static final int GAME_WIDTH = 1000;
    static final int GAME_HEIGHT = GAME_WIDTH * 9 / 16;
    static final Dimension SCREEN_SIZE = new Dimension(GAME_WIDTH, GAME_HEIGHT);
    static final int PLAYER_WIDTH = 40;
    static final int PLAYER_HEIGHT = 40;
    Thread gameThread;
    Graphics graphics;
    Player player;
    int fireBallY = (int) (Math.random() * 563);
    Fireballs fireball;
    Image image;
    int dimSky = 150;

     GamePanel() {
         newFireballs();
         newPlayer();
         this.setFocusable(true);
         this.addKeyListener(new actionListener());
         this.setPreferredSize(SCREEN_SIZE);
         this.setBackground(Color.CYAN);
         gameThread = new Thread(this);
         gameThread.start();
    }

    private void newPlayer() {
        player = new Player(200, 150, PLAYER_WIDTH, PLAYER_HEIGHT);
    }
    private void newFireballs() {
        for (int i = 0; i < 5; i++) new Fireballs(800, fireBallY, PLAYER_WIDTH, PLAYER_HEIGHT);
    }

    public void paint(Graphics g) {
        image = createImage(getWidth(), getHeight());
        graphics = image.getGraphics();
        draw(graphics);
        g.drawImage(image, 0,0, this);
    }

    public void draw(Graphics g) {
        player.draw(g);
    }

    public void move() {
         player.moveX();
         player.moveY();
    }

    public void collision() {}

    public void run() {
        //game loop
        long lastTime = System.nanoTime();
        double amountOfTicks =  60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        while (true) {
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            if (delta >= 1) {
                move();
                collision();
                repaint();
                delta--;
                System.out.println("It Works!");
            }
        }
    }

    private class actionListener extends KeyAdapter {
        public void keyPressed(KeyEvent e) {
            player.KeyPressed(e);
        }
        public void keyReleased(KeyEvent e) {
            player.KeyReleased(e);
        }
    }
}

Игрок

public class Player extends Rectangle {
int xVelocity;
int yVelocity;
int speed = 10;

    public Player(int x, int y, int PLAYER_WIDTH, int PLAYER_HEIGHT) {
        super(x,y, PLAYER_WIDTH, PLAYER_HEIGHT);
    }

    public void KeyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W) {
            setYDirection(-speed);
            moveX();
            moveY();
        }
        if (e.getKeyCode() == KeyEvent.VK_S) {
            setYDirection(+speed);
            moveX();
            moveY();
        }
        if (e.getKeyCode() == KeyEvent.VK_D) {
            setXDirection(+speed);
            moveX();
            moveY();
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            setXDirection(-speed);
            moveX();
            moveY();
        }
    }
    public void KeyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W) {
            setYDirection(-10);
            moveX();
            moveY();
        }
        if (e.getKeyCode() == KeyEvent.VK_S) {
            setYDirection(+1);
            moveX();
            moveY();
        }
        if (e.getKeyCode() == KeyEvent.VK_D) {
            setXDirection(+1);
            moveX();
            moveY();
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            setXDirection(-1);
            moveX();
            moveY();
        }
    }

    public void setXDirection(int xVelocity) {
        x = x + xVelocity;
    }
    public void setYDirection(int yVelocity) {
        y = y + yVelocity;
    }
    public void moveX() {
        x = x + xVelocity;
    }
    public void moveY() {
        y = y + yVelocity;
    }
    public void draw(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(x, y, width, height);
        }
}

Есть и другие классы, но они совершенно пусты, и я не думаю, что они являются причиной моей проблемы.

1 Ответ

0 голосов
/ 03 августа 2020

Несколько вопросов:

  1. Если вы новичок в Swing, не начинайте с излишней сложности. когда вы не видите JPanel на экране, я первым делаю поправку. Только тогда добавьте сложности в саму JPanel. Я сделал это ниже, просто отобразив большую красную панель JPanel.

  2. Является ли причина, по которой вы ничего не видите, потому что вы не установили JFrame.size(Dimension d)? Я добавил, что в конструкторе JFrame

  3. Действительно, как отметили @Frakcool и @camickr в своих комментариях, подход canoni c в Swing имеет приоритет над JPanel.paintComponent(Graphics g)

  4. Вы должны соблюдать ландшафт потоков, который Swing подготовил для вас. Это действительно использование SwingWorker потоков для фоновых задач, как прокомментировал @Frakcool. А также используйте EventDispatchingThread для обработки событий и запуска. В основном методе ниже вы видите вызов SwingUtilities.invokeLater(new Runnable()). Чем сложнее становится ваше приложение, тем больше вероятность того, что вы столкнетесь с проблемами, если не будете соблюдать EventDispatchingThread.

вот мой - минимальный - образец кода, содержащий примеры для пунктов выше. В вашем игровом логе c может быть проделана дополнительная работа, которая, я думаю, выходит за рамки.

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GameFrame extends JFrame {
    GamePanel panel;

    GameFrame() {
        panel = new GamePanel();
        this.add(panel);
        this.setTitle("Survival");
        this.pack();

        /*
         * might help to set a window size:
         */
        setSize(800, 600);

        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    private class GamePanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            // check if needed, eg for subcomponents
            // super.paintComponent(g);
            g.setColor(Color.red);
            g.fillRect(0, 0, getWidth(), getHeight());

        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new GameFrame();
            }
        });
    }
}
...