【发布时间】:2020-04-19 10:32:49
【问题描述】:
我对 Java 和 GUI 世界还很陌生。现在我正在尝试创建一个非常基本的太空射击游戏。为了创建它,我开始创建一个JFrame,后来我在其中放置了一个名为GamePanel 的JPanel 的个人扩展,我现在正试图在其上显示我的所有组件。直到这里一切都很清楚,问题来了:我有我的GamePanel,在其中显示我的球员,而在按下S 的KeyEvent 上,球员应该射子弹。我将子弹作为一个数组管理,称为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);
}
}
}
我认为在GamePanel 的paint() 方法中调用draw 方法可以让我同时显示所有射出的子弹和玩家。实际发生的情况是,一开始看起来还不错,但是当我按下 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 是我创建的一个计数器,以避免在绘制整个数组时出现任何NullPointerExceptions,当按下 S 时它会增加,因此数组的另一个子弹被初始化和射击。
感谢您的耐心等待,我是该网站的新手,如有任何错误请警告我。
【问题讨论】:
-
不要调用 g.dispose() + 遵循 java 驼峰命名约定:类大写,属性小写。不遵循命名约定会使您的代码难以阅读。
-
@Chocksmith:实际上, 可以在编码人员获得的 Graphics 对象上调用
Graphics#dispose(),例如Graphics g = myBufferedImage.getGraphics();,事实上,你应该在使用完此类资源后将其处理掉以节省资源,但您不应在 JVM 提供给您的 Graphics 对象上调用.dispose(),这种区别很重要,它这就是我在回答中提到这一点的原因。 -
将允许我同时显示所有射击的子弹和玩家。 - 是的,如果您的数组包含多个子弹对象,它应该可以工作。您需要发布 minimal reproducible example 来证明问题。
-
把paint()改成paintComponent()+去掉g.dispose()解决了这个问题,而且你教会了我很多,非常感谢,你太棒了!跨度>