JPanels not being drawn in JFrame

浪子不回头ぞ 提交于 2019-12-13 04:18:42

问题


I'm working on a vertical scrolling game, and I'm using a thread to generate new enemies every 2 seconds. Each enemy is an image in a JPanel. For some reason, The generated enemies are not showing up in the JFrame, but they are present. When the player collides with one of the enemies, all the enemies show up. This is the main class:

package asteroidblaster;


import javax.swing.*;
import javax.swing.Timer;
import java.awt.event.*;
import java.awt.*;

public class Main extends JFrame {

/**
 * 
 */
private static final long serialVersionUID = 1L;

public Main() {
    initUI();
}

private void initUI() {
    add(new Board());
    setResizable(false);
    pack();
    setTitle("Alien Blaster");
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String[] args) {

      EventQueue.invokeLater(() -> {
          JFrame ex = new Main();
          ex.setVisible(true);
      });
}

}

This is the main game logic:

package asteroidblaster;

import javax.swing.*;
import javax.swing.Timer;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class Board extends JPanel {

private static final long serialVersionUID = 1L;
private final int B_WIDTH = 1500;
private final int B_HEIGHT = 700;
private final int REFRESH_TIME = 150;

private AlienShip alien;
private PlayerShip player;
private ArrayList<AlienShip> enemies = new ArrayList<AlienShip>();

private Timer alienScrollTimer, mainTimer;

public Board() {
    initBoard();
}

private void initBoard() {

    setBackground(Color.BLACK);
    setFocusable(true);

    setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
    setPlayer();
    initAlienTimer();
    gameLoop();
}

private void initAlienTimer() {
    alienScrollTimer = new Timer(25, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            for(AlienShip as : enemies) {
                as.scrollShip();
            }
            repaint();
        }
    });
    alienScrollTimer.start();
}

private void setPlayer() {

    player = new PlayerShip();
    add(player);
    addMouseMotionListener(new MouseMotionListener() {
        @Override
        public void mouseMoved(MouseEvent e) {
            player.followMouse(e.getX(), e.getY());
            //checkCollision();
            repaint();
        }

        @Override
        public void mouseDragged(MouseEvent e) {

        }
    });
}

private void checkCollision() {
    for(AlienShip as : enemies) {
        if(player.getBounds().intersects(as.getBounds()))
            player.setVisible(false);
    }
}

private Thread alienGenerator() {
    for(int i = 0; i < 3; i++) { //these two are being drawn
        alien = new AlienShip();
        add(alien);
        enemies.add(alien);
    }

    return new Thread(new Runnable() {
        @Override
        public void run() {
            int sleepTime = 2000;
            while(true) {
                try {
                    Thread.sleep(sleepTime);
                } catch(InterruptedException e) {
                    System.out.println(e);
                }
                alien = new AlienShip();
                add(alien);
                enemies.add(alien);
                System.out.println("Enemies: " + enemies.size());
            }
        }
    });
}


private void gameLoop() {
    alienGenerator().start();
    mainTimer = new Timer(REFRESH_TIME, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            checkCollision();
            repaint();
        }
    });
    mainTimer.start();
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
}
}

This is the AlienShip class:

package asteroidblaster;

import java.util.Random;
import java.awt.*;
import javax.swing.*;

public class AlienShip extends JPanel {
/**
 * 
 */
private static final long serialVersionUID = 1L;
private final String ALIEN_SHIP_FILE = "images/alienShip.jpg";
private final int PANEL_WIDTH = 224, PANEL_HEIGHT = 250;
private int panelX, panelY;
private Image alienShipImage;

public AlienShip() {
    initAlienShip();
}

private void loadImage() {
    alienShipImage = Toolkit.getDefaultToolkit().getImage(ALIEN_SHIP_FILE);
}

public int getX() {
    return panelX;
}

public int getY() {
    return panelY;
}

private void setY(int yCoord) {
    panelY = yCoord;
}

private int setX() {
    Random r = new Random();
    int rand = r.nextInt(14) + 1;
    return panelX = rand * 100;
}

private void initAlienShip() {
    panelX = setX();
    panelY = 0;
    setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
    setBackground(Color.BLUE);
    loadImage();
}

@Override
public Rectangle getBounds() {
    return new Rectangle(panelX, panelY, PANEL_WIDTH, PANEL_HEIGHT);
}

public void scrollShip() {
    setY(getY() + 1);
}

@Override
public void paint(Graphics g) {
    super.paint(g);
    g.drawImage(alienShipImage, 0, 0, null);
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
}
}

来源:https://stackoverflow.com/questions/53380769/jpanels-not-being-drawn-in-jframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!