Итак, я предполагаю, что этот (ранее удаленный) код куда-то уходит в ваш код обработчика ключей Iceberg
...
if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);
}
Это выдвигает на первый план ряд проблем. Во-первых, вы создаете еще один экземпляр Mayflower
, который создает другой экземпляр JFrame
, то есть то, что удаляется, а не исходный кадр.
Iceberg
действительно не нужно взаимодействовать с Mayflower
, это за пределами сферы ответственности. Вместо этого Iceberg
«должен» генерировать уведомления о событиях для заинтересованных сторон об изменении его состояния.
Для этого нам нужен образец наблюдателя!
Давайте начнем с простого interface
, который описывает все уведомления Iceberg
готов сделать ...
public interface GameListener {
public void completed(Iceberg berg);
}
Далее нам нужен способ управления этими слушателями в Iceberg
...
public class Iceberg extends JPanel implements ActionListener, KeyListener {
private List<GameListener> listeners = new ArrayList<>(25);
public void addGameListener(GameListener listener) {
listeners.add(listener);
}
public void removeGameListener(GameListener listener) {
listeners.remove(listener);
}
И, наконец, способ генерации уведомлений ...
public class Iceberg extends JPanel implements ActionListener, KeyListener {
//...
protected void fireCompleted() {
for (GameListener listener : listeners) {
listener.completed(this);
}
}
Теперь, когда у вас есть состояние «завершено», вы можете уведомить заинтересованные стороны ...
if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
fireCompleted();
}
Теперь, в вашем методе start
, вам просто нужно создать экземпляр Iceberg
, зарегистрировать GameListener
и начать все это ...
private void Start(int clothes, int food, int repair, int money) {
Iceberg Tim = new Iceberg();
Tim.addGameListener(new GameListener() {
@Override
public void completed(Iceberg berg) {
f.dispose();
}
});
f.add(Tim);
f.setVisible(true);
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("SAILIN BABEEEEY");
f.setLocation(600, 200);
}
Наблюдения ...
Хорошо, в вашем примере кода есть много поводов для беспокойства, но давайте начнем с ...
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.RED);
g.fillRect(x, y, 40, 60);
g.setColor(Color.GRAY);
g.fillRect(0, hitscany, 650, 0);
if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);
}
time.start();
}
paintComponent
никогда не должно быть public
, никто не должен вызывать его напрямую.
- Вы заявляете, но никогда не используете
g2
Этот ...
if (y == hitscany) {
int complete = 1;
Mayflower bob = new Mayflower();
bob.epic(complete);
}
- плохая идея на нескольких уровнях. Краска должна рисовать текущее состояние компонента, больше ничего, она не должна принимать решения о состоянии компонента. Это относится к вашей основной петле
И ...
time.start();
Я не могу начать говорить вам, как это ужасно. paintComponent
будет вызываться часто (если вы выполняете анимацию), то есть вы постоянно сбрасываете Timer
. Состояние Timer
никогда не должно изменяться внутри paintComponent
. Вместо этого он должен управлять другими средствами, такими как конструктор или методы start / stop
KeyListener
сейчас плохой выбор. Он страдает от ряда хорошо известных и задокументированных ошибок. Лучшее всестороннее решение - использовать API связывания клавиш , который был разработан, чтобы помочь решить эти проблемы надежным и надежным способом