#java #animation #event-handling #paintcomponent #filewriter
#java #Анимация #обработка событий #paintcomponent #filewriter
Вопрос:
Я столкнулся с одной проблемой, которую я изо всех сил пытаюсь решить. Представьте себе простую игру, в которой некоторый объект, назовем его car, остается неподвижным по оси X (x = 50) и способен перемещаться только по оси Y (вверх и вниз). В то же время другие объекты создаются за пределами экрана в случайной точке (и перемещаются к моему первому объекту), поэтому их координаты уменьшаются по оси X. Как только каждый объект достигает моих первых координат объекта, некоторая переменная int оценивает; увеличивается.
int scores;
if(cars.getX() == getCarPos_X() amp;amp; cars.getY() != getCarPos_Y() )
scores ;
По сути, эта игра выглядит как автомобиль, который проезжает между другими автомобилями и избегает столкновения, и счетчик баллов увеличивается каждый раз, когда моя машина проезжает следующую движущуюся машину.
Так в чем проблема?Я использую таймер, который отсчитывает время между перерисовкой. Все объекты передаются в paintComponent, где фактически рисуется вся графика. В actionPerformed я вызываю методы для всех перемещений и один метод, который проверяет, произошло ли столкновение с другим автомобилем. В случае столкновения игра останавливается, а результаты должны быть записаны в какой-нибудь текстовый файл. Проблема в том, что, хотя два объекта имеют одинаковые координаты, JVM записывает бесконечное количество цифр (баллов) в файл (я думаю, это потому, что координаты перестают уменьшаться, и каждый интервал таймера проверяется на коллизию, и это == true, поскольку игра остановлена, а объект остается там, где они есть.) Так что мои оценки в текстовом файле выглядят так :
0
0
0
0
В одном столбце.
Или он отображает любой результат, который у меня есть.
И так далее…
Вот важный фрагмент кода, который я использовал
public void actionPerformed(ActionEvent e)
{
animate();
checkTouch();
}
private void animate()
{
//here code that creates obstacles and moves them
}
checkTouch()
{
//objects creating in some inner class Cars and add to ArrayList ( I don’t mention about it as it is beside the point )
for(Cars car : cars)
{
if((cars.getX() == getCarPos_X amp;amp; cars. getY() == getCarPos_Y())
{
//boolean var which stops game
inGame = false;
writeScore();
}
}
}
public void writeScore()
{
File scoresTxt = new File("scores.txt");
FileWriter fw = null;
BufferedWriter bw = null;
try
{
fw = new FileWriter(scoresTxt, true);
bw = new BufferedWriter(fw);
bw.write(scores "n");
}catch (IOException e)
{
e.printStackTrace();
}finally
{
try
{
bw.flush();
bw.close();
fw.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
public void paintComponent (Graphics g)
{
if(inGame)
{
g.drawImage(myCar, 50, 100, this);
for(Cars car : cars)
{
g.drawImage(obstacleCar, car.getX(), car.getY(), this);
}
}
}
Если вам понадобится какой-то дополнительный код, который я использовал, напишите комментарий, и я добавлю его.
И снова мне нужно исправить ошибку, из-за которой записывается бесконечный столбец чисел вместо одного итогового балла с момента столкновения.
Что не так с моим кодом и как решить эту проблему?
Дайте мне совет по простейшему решению, поскольку я новичок.
Заранее спасибо!
Комментарии:
1. Я бы написал это как ответ, но я не могу быть уверен в этом, поэтому не буду. Попробуйте сделать
System.exit(0)
, сделайтеboolean value GameOver
который изменяется после того, как экран завершения игры происходит только один раз, предотвращая его повторную запись, или найдите способ остановить повторное запускcheckTouch()
метода. Возможно,timer.stop()
рассылка спама прекратится. Если вы обнаружите, что ни одно из этих действий не работает, скажите мне.2. @FailingCoder да, я остановил таймер, и он прекратил рассылку спама. Но я не знаю, является ли это лучшим решением с точки зрения хорошего стиля программ?
Ответ №1:
Если ваш таймер запущен подобным образом или что-то подобное, вы можете отменить его, когда игровая переменная становится false. Хорошая статья о таймерах.
TimerTask task = new TimerTask() {
public void run() {
if (!inGame)
cancel();
else
// whatever it is that you are doing now
}
};
Вы также можете захотеть аналогичным образом прекратить обработку событий в методе actionPerformed(e).
if (!inGame)
return;