尚未绘制JPanels

时间:2018-11-19 21:59:46

标签: java multithreading swing jpanel

我正在开发垂直滚动游戏,并且正在使用线程每2秒生成新的敌人。每个敌人都是JPanel中的图像。由于某些原因,生成的敌人没有出现在JFrame中,但它们存在。当玩家与其中一个敌人碰撞时,所有敌人都会出现。 这是代码:

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

private void setAlien() {
    alien = new AlienShip();
    add(alien);
    enemies.add(alien);
    System.out.println("Enemies: " + enemies.size());
}

public Thread alienGenerator() {
    for(int i = 0; i < 3; i++) { // these are being drawn
        setAlien();
    }

    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);
                }
                setAlien(); //these aren't
            }
        }
    });
}


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

1 个答案:

答案 0 :(得分:0)

您似乎总是不知所措而不知所措。就我而言,您放置在earlier post中的代码就足够了,事实上,它仍然缺乏(没有PlayerShip类)。这篇文章中的代码示例的公正性甚至更低。永远不要少...

在我开始之前,我只是想让您知道我本人将以不同的方式来完成这项任务,这里提供的微薄帮助将完全基于您在本篇和以前的文章中已经提供的代码。

创建后未在游戏板上显示“外来飞船”的原因是因为您没有重新验证板。现在,有了您的代码,就可以在添加外星飞船的 Board.setAlien()方法中完成此操作。直接在代码行的下方

alien = new AlienShip();
add(alien);
enemies.add(alien);

添加代码行:revalidate();,因此代码如下所示:

alien = new AlienShip();
add(alien);
enemies.add(alien);
revalidate();

您的外星飞船现在应该显示。

  

附带说明:

当任何外星飞船实际上进入游戏板底部时会发生什么?作为建议,请让它们重新生成到游戏板的顶部(为您提供不错的提示)。可以在 AlienShip.scrollShip()方法中进行检查,以查看“外星人飞船”是否已经到达板的底部,例如:

public void scrollShip() {
    if (getY() + 1 > this.getParent().getHeight()) { 
        setY(0 - PANEL_HEIGHT);
    }
    else {
        setY(getY() + 1);
    }
}

我认为 PANEL_HEIGHT 是使用错误的字段名称。我认为使用 ALIEN_SHIP_WIDTH ALIEN_SHIP_HEIGHT 之类的方法更合适。与变量 panelX panelY 相同,可以是 alienShipX alienShipY 。令人回味。

如您在代码上方看到的那样,当前游戏板高度是通过轮询游戏板的 getHeight()方法来获取的:this.getParent().getHeight()。这样,您可以随时更改游戏板的大小,向下滚动时,外星飞船将知道当前边界在哪里。所有这些都意味着在游戏的JFrame窗口的Main Class中完成的 setResizable(false); 属性设置现在可以调整大小:setResizable(true);

您还将注意到,当外星飞船在游戏板顶部重新生成时,它实际上不在现场,并且随着向下移动,它会进入视野。我认为这是进入游戏领域的平滑过渡,而不仅仅是弹出。这是通过上面的setY(0 - PANEL_HEIGHT);代码行完成的。事实上,即使游戏最初开始时,您的“外星飞船”也应以这种方式流入游戏区域,这可以通过初始化 AlienShip.initAlienShip()方法来完成> panelY 变量到panelY = -PANEL_HEIGHT;

现在,这将带我初始化 PANEL_WIDTH PANEL_HEIGHT 字段。这些值似乎很大(分别为224和250)。当然,出于碰撞测试等目的,您可能已经设置了这些大小,但是我认为64 x 35的图像大小很可能就足够了:

enter image description here

此图像应该是具有透明背景的PNG图像,这样就无需使用 AlienShip.initAlienShip()方法中的setBackground(Color.BLUE);代码行。

AlienShip.getX() AlienShip.getY()方法应被覆盖:

@Override  
public int getX() { ... }

@Override  
public int getY() { ... }

我认为将AlienShip类扩展到JLabel会比扩展到JPanel更好。对于JPanel来说似乎有些矫kill过正:

public class AlienShip extends JLabel { ... }

在游戏板上添加背景图像可以为游戏添加皮兹风格。这可以通过将以下代码添加到 Board.paintComponent()方法中来实现:

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

    ImageIcon imgIcon = new ImageIcon("images/StarBackground.png");
    Image img = imgIcon.getImage();
    g.drawImage(img, 0, 0, this.getSize().width, this.getSize().height, this);
}

图像可以是acquired here

enter image description here

这应该让您继续一段时间。不久以后它将是外星人的混乱。

enter image description here