Как добавить отображение начисления баллов в окно игры?

В классе 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);
        }
    }

}
→ Ссылка