Как добавить отображение начисления баллов в окно игры?
В классе Okno я написал:
public void someMethod() { //Я не знаю, в каком методе вы производите действия
int num = pole.getNum(); //Параметры лучше сделать пустыми(нет смысла поставлять в метод переменную num. Её значение сохраняется!)
con.add(num); //Эта какая-та ваша строка
}
con.add(new JLabel("test" + pole.score)); //Обращаемся к статической переменной по имени класса.
'getNum' красное. Error: Cannot resolve method 'getNum' in 'pole'
'num' красное. Error: Cannot resolve method 'add(int)'
'score' красное Error: Cannot resolve symbol 'score'
В классе Pole написал:
public void paintComponent(Graphics gr)
{
// Выполнить отрисовку сначала самого окна
super.paintComponent(gr);
gr.drawImage(fon, 0, 0, null); // Рисование фона
gr.drawImage(shapka, x, 465, null); // Рисование шапки
// Цикл, который отображает подарки на игровом поле и проверяет пропущенные подарки
for (int i=0;i<7;i++)
{
gamePodar[i].draw(gr); // Отображение подарка
if (gamePodar[i].act==true) // Если подарок из массива подарков активен
{
// Если подарок достиг нижней границы:
if ((gamePodar[i].y+gamePodar[i].img.getHeight(null))>=470) {
if (Math.abs(gamePodar[i].x - x) > 75) // Если подарок пропущен
{
// Вывод картинки Окончания игры
gr.drawImage(end_game, 300, 300, null);
timerDraw.stop(); // Оставнока таймера timerDraw
timerUpdate.stop(); // Оставнока таймера timerUpdate
Clip clip = getClip("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\audio\\game_over.wav");
Thread thread = playForever(clip);
// ...
// do stuff
// ...
boolean play = true;
if (!play) stopAudio(thread);
break; // Прерывание цикла
}
// Снятие подарка с игрового поля, если он пойман шапкой
else
{
gamePodar[i].act=false;
Clip clip = getClip("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\audio\\coin.wav");
Thread thread = playForever(clip);
// ...
// do stuff
// ...
boolean play = true;
if (!play) stopAudio(thread);
public static int getNum() { //Параметры - пустые!
num++;
System.out.println(ANSI_GREEN + num +ANSI_RESET);
return num;
}
}
}
}
}
}
'gr' красное. Error: Cannot resolve symbol 'gr', ')' expected.
'getNum()' красное. Error: ';' expected
'return num;' красное. Error: Return outside method
Ответы (1 шт):
Я исправил код. Вернее, в нём нет теперь ошибок компиляции. Но код нуждается в сильной правке. У него есть несколько очень серьёзных проблем:
1)Названия переменных должны быть только говорящими и только на английском языке (с маленькой буквы).
2)названия классов - должны быть только говорящими и только на английском языке но с большой буквы!)
3)Не пишите коментарии, которые слишком очевидны("это конструктор класса")
4)"Полные" импорты - это обычно плохо. Подробней здесь: Зачем усложнять импорт в джава?
5)Слишком много пустых строк (большинство - лишние)
6)инкапсуляция
Возможно, вам это покажется странным, но это действительно проблемы. Такой код довольно тяжело читается. Ну и нарушение важных принципов до добра редко доводит. Я надеюсь, что вы постараетесь исправить вышеперечисленое. Это модет занять много времени, но я думаю, что это следует сделать. А вот код без ошибок компиляции:
класс game:
package com.company;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.*;
import java.io.File;
// Главный класс игры
public class game {
// Главный метод, который запускает игру
public static void main(String[] args) {
// Вызов диалогового окна для ввода сложности игры
String rez =
JOptionPane.showInputDialog(null,"Введите сложность игры от 1 до 7:","Сложность игры",1);
// Помещение результата выбора в переменную целого типа
int slogn = rez.charAt(0)-'0';
// Проверка, что введена цифра от 1 до 7
if ((slogn>=1)&&(slogn<=7))
{
// Создание окна, в котором находится игровое поле
okno window = new okno(slogn);
}
Clip clip = getClip("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\audio\\skeleton.wav");
Thread thread = playForever(clip); // Создание потока (последовательности данных, которая может работать параллельно с другими последовательностями)
boolean play = true;
if (!play) stopAudio(thread);
}
public static Thread playForever(Clip clip) {
Thread thread = new Thread(() -> {
clip.loop(Clip.LOOP_CONTINUOUSLY);
clip.start();
synchronized (Thread.currentThread()) { // synchronized - ключевое слово, которое позволяет заблокировать доступ к методу или части кода, если его уже использует другой поток
try {
Thread.currentThread().wait(); // Освобождает монитор и переводит вызывающий поток в состояние ожидания до тех пор, пока другой поток не вызовет метод notify()
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
thread.start();
return thread;
}
public static void stopAudio(Thread thread) {
synchronized (thread) {
thread.notify(); // продолжает работу потока, у которого ранее был вызван метод wait()
}
}
public static Clip getClip(String filepath) {
String reset = "\u001B[0m";
String red = "\u001B[31m";
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(filepath)));
return clip;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error. Can't find an audiofile skeleton.wav");
System.out.println(red + "Error. Can't find an audiofile skeleton.wav" + reset);
throw new RuntimeException(e);
}
}
}
класс okno:
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// Класс окна, в котором размещено игровое поле
class okno extends JFrame{
private pole gameP; // Закрытая Переменная класса - игровое поле
private int slogn; // Закрытая Переменная класса - сложность игры
// Обработчик событий нажатий на клавиши
private class myKey implements KeyListener
{
// Метод, который срабатывает при нажатии
public void keyPressed(KeyEvent e)
{
// Получение кода нажатой клавиши
int key_ = e.getKeyCode();
// Выход из программы, если нажат - Esc
if (key_==27) System.exit(0);
else if (key_==37) // Если нажата стрелка влево
{
// Контроль перемещения влево за пределы окна
if (gameP.x-30>-48) gameP.x-=30;
else gameP.x=752;
}
else if (key_==39) // Если нажата стрелка вправо
{
// Контроль перемещения вправо за пределы окна
if (gameP.x+30<752) gameP.x+=30;
else gameP.x=-48;
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
// Конструктор класса
public okno(int slogn)
{
// Помещение сложности, выбранной пользователем в переменную класса
this.slogn = slogn;
// Подключение обработчика события для клавиатуры к окну
addKeyListener(new myKey());
// Установка активности окна
setFocusable(true);
// Задание размеров и положения окна
setBounds(0,0,800,600);
// Задание заголовка окна
setTitle("Игра: Новогодний дождь");
// Создание объекта - игрового поля
gameP = new pole(slogn);
// Прикрепление (вложение) панели - игрового поля в окно
Container con = getContentPane();
con.add(gameP);
pole p = new pole();
int num = p.getNum(); //Параметры лучше сделать пустыми(нет смысла поставлять в метод переменную num. Её значение сохраняется!)
con.add(num); //Эта какая-та ваша строка
con.add(new JLabel("test" + pole.score)); //Обращаемся к статической переменной по имени класса.
// Сделать окно видимым
setVisible(true);
}
}
класс podar:
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// Класс для подарка, падающего сверху
class podar {
public Image img; // Изображение подарка
// Положение подарка на игровом поле, в пикселях, x - отступ слева,
// y - отступ сверху
// Переменная логического типа,
//показывающая активность подарка, есть он игровом поле или нет
public int x,y;
public Boolean act;
Timer timerUpdate; // Таймер, отвечающий за движение подарка вниз
public podar(Image img)
{
// Создание и настройка таймера, отвечающего за движение подарка вниз
timerUpdate = new Timer(500,new ActionListener() {
public void actionPerformed(ActionEvent e) {
vniz(); // Метод, осуществляющий движение подарка вниз
}
});
// Передача изображения из круглых скобок Конструктора класса в переменную класса
// Изначально делаем подарок неактивным, отсутствующим на игровом поле
this.img = img;
act=false;
}
//Метод, выполняющий активизацию подарка на игровом поле, вывод сверху игрового поля
public void start()
{
timerUpdate.start(); // Запуск таймера
y = 0; // Отступ сверху в пикселях
// Отступ слева в пикселях, получаем случайным образом от 0 до 700
x = (int)(Math.random()*700);
act = true; // Свойство активность устанавливаем в true
}
// Метод, осуществляющий движение подарка вниз
public void vniz()
{
if (act==true) // Если подарок активен на игровом поле
{
y+=6; // Увеличение отступа сверху на 6 пикселей
}
if ((y+img.getHeight(null))>=470) // Если подарок достиг нижней границы
{
timerUpdate.stop(); // Остановка таймера
}
}
// Метод, выполняющий отрисовку подарка на игровом поле, если он активен
public void draw(Graphics gr)
{
if (act==true)
{
gr.drawImage(img,x,y,null); // Рисование изображения
}
}
}
класс pole:
package com.company;
import com.sun.tools.javac.Main;
import javax.imageio.*;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
// Класс панели, которая является игровым полем
public class pole extends JPanel{
private Image shapka; // Закрытая Переменная класса, в которую загружается шапка
private Image fon; // Закрытая Переменная класса, в которую загружается фон
public int x = 400; // Открытая Переменная класса, в которую загружается шапка
private int slogn; // Переменная сложности игры
private podar[] gamePodar; // Массив подарков
private Image end_game; // Изображение Окончания игры
public Timer timerUpdate,timerDraw; // Два таймера
String ANSI_RED = "\u001B[31m";
String ANSI_GREEN = "\u001B[32m";
String ANSI_RESET = "\u001B[0m";
public static int score = 0;
public static int num = 0;
public pole(int slogn){
this.slogn = slogn;
// Загрузка изображения шапки из файла
try {
shapka = ImageIO.read(new File("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\images\\shapka.png"));
} catch(IOException ex) {System.out.println(ANSI_RED + "Не могу найти файл шапки." + ANSI_RESET);}
// Загрузка изображения фона из файла
try{
fon = ImageIO.read(new File
("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\images\\fon.jpg"));
} catch(IOException ex) {System.out.println("Не могу найти файл фона.");}
// Загрузка изображения Окончания игры
try{
end_game = ImageIO.read(new File("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\images\\end_game.png"));
} catch(IOException ex) {System.out.println("Не могу найти файл Game Over.");}
// Загрузка семи изображений подарков
gamePodar = new podar[7];
for (int i=0;i<7;i++){
try{
gamePodar[i] = new podar(ImageIO.read(new File("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\images\\p"+i+".png")));
} catch (IOException ex) {System.out.println("Не могу найти файлы подарков.");}
}
/*
Создание таймера,
который будет раз в три секунды проверять подарки и добавлять их на игровое поле
*/
timerUpdate = new Timer(3000,new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Метод для проверки и добавление подарков на игровое поле
updateStart();
}
});
timerUpdate.start(); // Запуск таймера timerUpdate
// Создание таймера,
//который будет перерисовывать игровое поле 20 раз в секунду
timerDraw = new Timer(50,new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint(); // Запуск метода перерисовки поля (public void paintComponent(Graphics gr))
}
});
timerDraw.start(); // Запуск таймера для перерисовки
}
// Метод, который отрисовывает графические объекты на панели
public void paintComponent(Graphics gr){
// Выполнить отрисовку сначала самого окна
super.paintComponent(gr);
gr.drawImage(fon, 0, 0, null); // Рисование фона
gr.drawImage(shapka, x, 465, null); // Рисование шапки
// Цикл, который отображает подарки на игровом поле и проверяет пропущенные подарки
for (int i=0;i<7;i++) {
gamePodar[i].draw(gr); // Отображение подарка
if (gamePodar[i].act==true) {
// Если подарок достиг нижней границы:
if ((gamePodar[i].y+gamePodar[i].img.getHeight(null))>=470) {
if (Math.abs(gamePodar[i].x - x) > 75) // Если подарок пропущен
{
// Вывод картинки Окончания игры
gr.drawImage(end_game, 300, 300, null);
timerDraw.stop(); // Оставнока таймера timerDraw
timerUpdate.stop(); // Оставнока таймера timerUpdate
Clip clip = getClip("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\audio\\game_over.wav");
Thread thread = playForever(clip);
boolean play = true;
if (!play) stopAudio(thread);
break; // Прерывание цикла
}
// Снятие подарка с игрового поля, если он пойман шапкой
else {
gamePodar[i].act=false;
Clip clip = getClip("C:\\Users\\powha\\Documents\\CTT\\ЗАНЯТИЯ\\Конкурсы\\Проекты\\NYRain\\src\\com\\company\\audio\\coin.wav");
Thread thread = playForever(clip);
// ...
// do stuff
// ...
boolean play = true;
if (!play) stopAudio(thread);
}
}
}
}
}
// Метод для проверки и добавления подарков на игровое поле
public int getNum() { //Параметры - пустые!
num++;
System.out.println(ANSI_GREEN + num +ANSI_RESET);
return num;
}
private void updateStart()
{
int kol=0; // Переменная для подсчета подарков на игровом поле
for (int i=0;i<7;i++) // Цикл перебора всех подарков массива
{
if (gamePodar[i].act==false) // Если подарок не на игровом поле
{
if (kol<slogn) // Если текущее количество менее номера сложности (от 1 до 7)
{
// Активизация подарка на игровом поле, вывод его сверху игрового поля
gamePodar[i].start();
break; // Прерывание цикла
}
}
else kol++; // Если подарок на игровом поле
}
}
public static Thread playForever(Clip clip) {
Thread thread = new Thread(() -> {
//clip.loop(Clip.LOOP_CONTINUOUSLY);
clip.start();
synchronized (Thread.currentThread()) {
try {
Thread.currentThread().wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
thread.start();
return thread;
}
public static void stopAudio(Thread thread) {
synchronized (thread) {
thread.notify();
}
}
public static Clip getClip(String filepath) {
String reset = "\u001B[0m";
String red = "\u001B[31m";
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(filepath)));
return clip;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error. Can't find an audiofile skeleton.wav");
System.out.println(red + "Error. Can't find an audiofile skeleton.wav" + reset);
throw new RuntimeException(e);
}
}
}