gpt4 book ai didi

java - 创建游戏启动器时出错

转载 作者:行者123 更新时间:2023-12-02 04:35:09 24 4
gpt4 key购买 nike

我正在制作一个简单的java游戏,并尝试在游戏开始时实现一个启动器。

例如,一个 JFrame ,其中有一个按钮,按下该按钮即可启动我的应用程序。

我想做的是让 main 方法调用一个单独的类,该类打开一个 JFrame 和一个用于 JButtonActionListener > 在调用时调用 new Cliker();

但是,当在 main 方法之外调用 new Cliker(); 时,它会打开游戏 JFrame,但不会打开 JPanel

为什么会发生这个错误,我该如何修复它?我对编程相对较新,因此对于有关此问题或我的程序的任何不清楚之处,我提前表示歉意。

非常感谢您的帮助。如果您需要更多类(class)来帮助回答我的问题,请提出,或者如果您有任何其他问题,请随时告诉我。

package com.Cliker;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.Cliker.Accessories.Music;

public class Cliker extends JFrame {

private static final long serialVersionUID = 1L;

int score = 0;

JButton ball = new JButton(new ImageIcon("res/textures/ball/ball.PNG"));
JFrame gameFrame = new JFrame("Cliker v1.0");

public static void main(String[] args){
new Cliker();
}


public Cliker() {

gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.add(new MyPanel());
gameFrame.pack();
gameFrame.setVisible(true);
gameFrame.setResizable(false);
gameFrame.setLocationRelativeTo(null);

ClikerGame play = new ClikerGame();
play.run(this);

}

class MyPanel extends JPanel implements MouseListener {

private static final long serialVersionUID = 1L;

public MyPanel() {

setBackground(Color.CYAN);

ball.addMouseListener(new MouseListener() {

@Override
public void mousePressed(MouseEvent e) {
if (e.getSource() == ball) {
score++;
Music.music(4);
repaint();

}

}

@Override
public void mouseClicked(MouseEvent e) {

}

@Override
public void mouseEntered(MouseEvent e) {

}

@Override
public void mouseExited(MouseEvent e) {

}

@Override
public void mouseReleased(MouseEvent e) {

}
});
ball.setBorder(null);

add(ball);
addMouseListener(this);

}

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Fixedsys", Font.BOLD, 30));
g.setColor(Color.BLACK);
g.drawString(String.valueOf(score), getWidth() / 2, 40);

}

public Dimension getPreferredSize() {
return new Dimension(700, 500);
}

@Override
public void mousePressed(MouseEvent e) {
if (e.getSource() == this) {

this.setBackground(Color.RED);

gameFrame.setVisible(false);

ClikerEndGame sendData = new ClikerEndGame();

try {

sendData.finish(score);

} catch (Exception e1) {
JOptionPane.showInputDialog(null,"The game has encountered an error. Error code: 001");
e1.printStackTrace();
}




}

}

@Override
public void mouseClicked(MouseEvent e) {

}

@Override
public void mouseEntered(MouseEvent e) {

}

@Override
public void mouseExited(MouseEvent e) {

}

@Override
public void mouseReleased(MouseEvent arg0) {

}
}

}

下一个类

package com.Cliker;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import com.Cliker.Accessories.Music;

public class ClikerGame implements Runnable {

private int x, y, xa = 2, ya = 2;


public void run(Cliker panel) {


JButton ball = panel.ball;

Music.music(2);

while (true) {
try {
x += xa;
y += ya;
if (x < 0 || x > 700 - 20 ) {

Music.music(1);

xa = -xa;
}

else if (y < 0 || y > 500 - 20 ){

Music.music(1);

ya = -ya;

}

Thread.sleep(15);

ball.setBounds(x,y,30,30);
} catch (Exception e) {
JOptionPane.showMessageDialog(null,"Error 1");

}

}
}
public void run() {
this.run();

}

}

最佳答案

基本上,您违反了 Swing 的单线程规则,ClikerGame 正在运行一个 while-loop,它会阻塞事件调度线程,阻止其处理新事件,包括绘制事件。

它从 main 运行的原因是 main 不是从 EDT 中调用的,基本上,这是一个侥幸。然而,当您从 JButtonActionListener 中调用 new Clicker() 时,您是在 EDT 的上下文中运行,因此您的问题。

看看Initial ThreadsConcurrency in Swing了解更多详情。

“立即”解决方案可能看起来像使用Thread,但这也会违反 Swing 的单一规则,因为 Swing 不是线程安全的,并且您永远不应该从上下文外部更新 UI美国东部夏令时间。

更好的解决方案可能是使用 Swing Timer 来充当伪循环。这是在 EDT 上下文中定期通知的

也许,类似......

public class ClikerGame {

private int x, y, xa = 2, ya = 2;
private Clicker clicker;

private Timer timer;

public ClikerGame(Clicker clicker) {
this.clicker = clicker;

timer = new Timer(15, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
x += xa;
y += ya;
if (x < 0 || x > 700 - 20) {

Music.music(1);

xa = -xa;
} else if (y < 0 || y > 500 - 20) {

Music.music(1);

ya = -ya;

}

Thread.sleep(15);

clicker.ball.setBounds(x, y, 30, 30);
clicker.ball.getParent().repaint();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error 1");

}
}
});
}

public void start() {
if (!timer.isRunning()) {
Music.music(2);
timer.start();
}
}

public void stop() {
timer.stop();
// Stop the music
}
}

关于java - 创建游戏启动器时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30929274/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com