问题
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