- 已关闭。**此问题需要debugging details。当前不接受答案。
编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
昨天关门了。
Improve this question
我已经使用Swing UI在Java中设置了一个游戏。
预期
当在屏幕上发射炮弹时,我希望背景一直在那里
问题
当我运行代码时,背景看起来很好。但是当发射抛射体的按钮被按下时,背景就消失了。
代码
public class ProjectileShooterTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame f = new JFrame() {
};
ImageIcon background=new ImageIcon("Background.png");
Image img=background.getImage();
Image temp=img.getScaledInstance(800,440,Image.SCALE_SMOOTH);
background=new ImageIcon(temp);
JLabel back=new JLabel(background);
back.setBounds(0,0,800,500);
f.getContentPane().setLayout(new BorderLayout());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,500);
final ProjectileShooter projectileShooter = new ProjectileShooter();
ProjectileShooterPanel projectileShooterPanel = new ProjectileShooterPanel(projectileShooter);
projectileShooter.setPaintingComponent(projectileShooterPanel);
JPanel controlPanel = new JPanel(new GridLayout(1,0));
controlPanel.add(new JLabel(" Post-Launch Angle"));
final JSlider angleSlider = new JSlider(70, 89, 85);
angleSlider.setLayout( new FlowLayout() );
controlPanel.add(angleSlider);
f.add(back);
controlPanel.add(new JLabel(" Thrust"));
final JSlider powerSlider = new JSlider(50, 80, 60);
powerSlider.setLayout( new FlowLayout() );
controlPanel.add(powerSlider);
JButton shootButton = new JButton("Launch");
shootButton.setLayout( new FlowLayout() );
shootButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int angleDeg = angleSlider.getValue();
int power = powerSlider.getValue();
projectileShooter.setAngle(Math.toRadians(angleDeg));
projectileShooter.setPower(power);
projectileShooter.shoot();
}
});
f.add(back);
controlPanel.add(shootButton);
f.getContentPane().add(controlPanel, BorderLayout.NORTH);
f.getContentPane().add(projectileShooterPanel, BorderLayout.CENTER);
f.setVisible(true);
f.setLayout(new BorderLayout());
}
}
class ProjectileShooter
{
private double angleRad = Math.toRadians(45);
private double power = 50;
private Projectile projectile;
private JComponent paintingComponent;
void setPaintingComponent(JComponent paintingComponent)
{
this.paintingComponent = paintingComponent;
}
void setAngle(double angleRad)
{
this.angleRad = angleRad;
}
void setPower(double power)
{
this.power = power;
}
void shoot()
{
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
executeShot();
}
});
t.setDaemon(true);
t.start();
}
private void executeShot()
{
if (projectile != null)
{
return;
}
projectile = new Projectile();
Point2D velocity =
AffineTransform.getRotateInstance(angleRad).
transform(new Point2D.Double(1,0), null);
velocity.setLocation(
velocity.getX() * power * 0.5,
velocity.getY() * power * 0.5);
projectile.setVelocity(velocity);
//System.out.println("Initial "+velocity);
long prevTime = System.nanoTime();
while (projectile.getPosition().getY() >= 0)
{
long currentTime = System.nanoTime();
double dt = 3 * (currentTime - prevTime) / 1e8;
projectile.performTimeStep(dt);
prevTime = currentTime;
paintingComponent.repaint();
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
return;
}
}
projectile = null;
paintingComponent.repaint();
}
Projectile getProjectile()
{
return projectile;
}
}
问题
我该如何解决这个问题?
1条答案
按热度按时间xdnvmnnf1#
相当于:
在后面的代码中,您可以:
这将导致问题,因为您无法将两个组件添加到CENTER。
Swing GUI是父/子设计,因此您需要类似以下内容:
我将让您弄清楚上述语句的逻辑顺序和位置。
另外,您为什么要:
在构造函数的末尾?这将替换原始布局的所有约束信息。
最后,你的射弹射击面板需要是透明的,否则它会覆盖背景。所以你还需要:
注意:如果不使用JLabel作为背景,在投射型射手面板中绘制背景会更容易。这样,您就不会遇到尝试将多个面板添加到另一个面板的问题,射手面板也不需要透明。
编辑:
您需要在组件之间建立父/子关系,例如:
我的第一个建议是将背景作为一个组件,并向其中添加投射面板:
1.设置背景组件的布局
1.添加投射物面板到背景
1.使投射物面板透明,以便您可以看到图像
这不是最佳解决方案
第二种解决方案是将背景绘制为射弹面板的一部分:
1.在投射体面板中绘制背景图像
1.给炮弹上色
这是首选解决方案。