我是一个新的动态java swing 编程。我当然使用常规摆动组件之前使用Buttons
,Panels
等等。
所以我正在尝试使用Swing
和Graphics2D
制作一个非常基本的乒乓球游戏。我以前制作了一个我成功的绘画程序。
我的问题是程序运行时图形会严重停顿。到目前为止,我只实现了球,它只是选择一个随机方向并开始在面板中反弹。哪个有效。但是,如果我一直在不断调整框架的大小,我只能看到球,否则它会严重破坏,看起来空白。在第一秒左右,您实际上可以看到球在移动,但严重卡顿,然后面板开始显得空白。
相关代码和结构:
该计划的主要部分是Controller
和Frame
类。 Controller
实现runnable并包含执行游戏更新的run方法。
Frame类扩展JFrame
并包含一个私有实例变量JPanel
gamePanel,其中绘制了所有图形。 JFrame
也有重写paint()
;方法
当Controller
更新程序时,它会调用Frame
中名为updateGraphics()
的类,该类之前称为paint(getGraphics())
;
public class Frame extends JFrame {
private JPanel gamePanel;
....
public void paint(Graphics g) {
super.paint(g);
label.setText(Integer.toString(ball.getPos().x) + ", " + Integer.toString(ball.getPos().y));
Graphics2D g2 = (Graphics2D) gamePanel.getGraphics();
g2.setStroke(new BasicStroke(2));
//g2.drawRect(0, 0, gamePanel.getWidth(), gamePanel.getHeight());
try{
//Draws the ball
g2.fillOval(ball.getPos().x, ball.getPos().y, 10, 10);
//Draws the player1(left) shield
g2.setStroke(new BasicStroke(2));
g2.drawLine(playerShield.getNorthX(), playerShield.getNorthY(), playerShield.getSouthX(), playerShield.getSouthY());
g2.drawLine(playerShield.getNorthX(), playerShield.getNorthY(), playerShield.getSouthX(), playerShield.getSouthY());
//Draws the computer/Player2(right) Shield
g2.drawLine(computerShield.getNorthX(), computerShield.getNorthY(), computerShield.getSouthX(), computerShield.getSouthY());
g2.drawLine(computerShield.getNorthX(), computerShield.getNorthY(), computerShield.getSouthX(), computerShield.getSouthY());
} catch(Exception e) {
System.out.println(e);
}
}
...
public void updateGraphics() {
paint(getGraphics());
}
//Another version of the updateGraphics i have tried to use with as little success
public void updateGrapgics() {
gamePanel.validate();
gamePanel.repaint();
}
}
在搜索时,我发现有人说我应该而且不应该使用油漆或重绘方法。
有人可以向我解释为什么它的口吃以及我该怎样做才能使它没有口吃?
答案 0 :(得分:1)
无需实施双缓冲或其他技巧。只需执行以下操作:
public class SomeVisualObject extends JComponent {
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
// paint things
}
}
...
final SomeVisualObject obj = new SomeVisualObject()
frame.add(obj);
...
final Timer repaintTimer = new Timer(20, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// do some stuff here, for example calculate game physics.
// repaint actually does not repaint anything, but enqueues repaint request
obj.repaint();
}
});
repaintTimer.start();
它会平稳地运行和绘画,没有毛刺。
只是不要乱用循环。 Swing运行它自己的事件循环,这对重绘和其他东西至关重要。
在此处查看2d游戏对象(弹跳球)的完整且有效的示例:https://gist.github.com/akhikhl/8199472
答案 1 :(得分:0)
我认为你应该实现某种双重缓冲。
你的问题与此问题类似Java Panel Double Buffering,本教程可以为你提供很多帮助http://www.cokeandcode.com/info/tut2d.html。