Как запустить программу .jar, чтобы она работала плавно и не завершалась с ошибкой?

Вопрос или проблема

У меня есть игра на Java (.jar), но когда я ее запускаю, она работает не плавно. Очень сильно лагает.

my game

Игра по сути такая, и очень простая, но если вы запустите эту игру (по крайней мере, в моем случае), она будет иметь сбои, из-за которых в нее очень трудно играть. Я создал эту игру в 2023 году на Windows и мог нормально ее тестировать. Недавно я скачал Ubuntu, и я не уверен, делаю ли я что-то неправильно

Вот код игры, если кто-то программист:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import java.util.Set;
import java.util.HashSet;
import javax.sound.sampled.*;

public class Main extends JFrame {
    ImageIcon icon = new ImageIcon(getClass().getClassLoader().getResource("logogame.png"));
    int comeu = 0;
    int x = 200;
    int y = 100;
    Set<Integer> keys = new HashSet<>();
    int speed = 5;
    Circle circle;
    public Main() {
        JMenuBar barramenu = new JMenuBar();
        JMenu menu = new JMenu("Menu");
        JMenuItem sobre = new JMenuItem("Sobre");
        JMenuItem sair = new JMenuItem("Sair");

        setJMenuBar(barramenu);
        barramenu.add(menu);
        menu.add(sobre);
        menu.add(new JSeparator());
        menu.add(sair);

        sobre.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "Primeiro jogo puro criado em java por Cabralito em 2023");
            }
        });

        sair.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        setTitle("Square and Circle (2023)");
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setSize(400, 400);
        setLocationRelativeTo(null);
        getContentPane().setBackground(Color.black);
        getContentPane().add(new Cavar());
        setIconImage(icon.getImage());

        circle = generateRandomCircle();

        Timer timer = new Timer(10, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (keys.contains(KeyEvent.VK_A)) {
                    x -= speed;
                }
                if (keys.contains(KeyEvent.VK_D)) {
                    x += speed;
                }
                if (keys.contains(KeyEvent.VK_W)) {
                    y -= speed;
                }
                if (keys.contains(KeyEvent.VK_S)) {
                    y += speed;
                }

                checkCollision();
                repaint();
            }
        });
        timer.start();

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                keys.add(e.getKeyCode());
            }

            @Override
            public void keyReleased(KeyEvent e) {
                keys.remove(e.getKeyCode());
            }
        });

        setFocusable(true);
        requestFocusInWindow();
    }

    public void playSound(String soundFileName) {
        try {
            ClassLoader classLoader = getClass().getClassLoader();
            InputStream audioIn = classLoader.getResourceAsStream(soundFileName);

            if (audioIn == null) {
                throw new IOException("Arquivo de áudio não encontrado: " + soundFileName);
            }

            byte[] audioData = audioIn.readAllBytes();
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(audioData);

            AudioInputStream audioStream = AudioSystem.getAudioInputStream(byteArrayInputStream);
            Clip clip = AudioSystem.getClip();
            clip.open(audioStream);
            clip.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }






    class Cavar extends JComponent {
        public void paint(Graphics g) {
            g.setColor(Color.RED);
            g.fill3DRect(x, y, 50, 50, true);
            if (circle != null && circle.isVisible()) {
                g.setColor(Color.GREEN);
                g.fillOval(circle.getX() - circle.getRadius(), circle.getY() - circle.getRadius(), circle.getRadius(), circle.getRadius());
            }
            g.setColor(Color.WHITE);
            g.drawString("Comeu: " + comeu, 10, 20);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new Main();
        });
    }

    class Circle {
        private int x;
        private int y;
        private int radius;
        private boolean visible;

        public Circle(int x, int y, int radius, boolean visible) {
            this.x = x;
            this.y = y;
            this.radius = radius;
            this.visible = visible;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public int getRadius() {
            return radius;
        }

        public boolean isVisible() {
            return visible;
        }

        public void setVisible(boolean visible) {
            this.visible = visible;
        }
    }

    private Circle generateRandomCircle() {
        Random random = new Random();
        int circleX;
        int circleY;
        do {
            circleX = random.nextInt(getWidth() - 50);
            circleY = random.nextInt(getHeight() - 50);
        } while (Math.abs(circleX - x) < 50 && Math.abs(circleY - y) < 50);
        return new Circle(circleX, circleY, 25, true);
    }

    private void checkCollision() {
        if (circle.isVisible() && Math.abs(x - circle.getX()) < 50 && Math.abs(y - circle.getY()) < 50) {
            circle.setVisible(false);
            circle = generateRandomCircle();
            comeu++;

            playSound("som/Dingw.wav");
        }
    }
}

Ответ или решение

Чтобы обеспечить стабильную работу программы Java (.jar) без падений и лагов, особенно если она испытывает проблемы при запуске на Ubuntu после разработки в Windows, следует рассмотреть ряд аспектов, начиная от кода и заканчивая средой выполнения. Давайте разберём ключевые шаги, которые могут помочь решить проблему.

Анализ и оптимизация кода

  1. Проверка использования ресурсов.
    Внимательно изучите использование ресурсов в вашем коде. В вашей программе создаётся объект Clip для воспроизведения звука при каждом столкновении. Убедитесь, что этот объект корректно закрывается после завершения воспроизведения (метод clip.close()). Это предотвратит утечки ресурсов.

  2. Оптимизация графического интерфейса.
    Метод repaint() вызывается очень часто из таймера с интервалом в 10 миллисекунд. Это может вызывать нагрузку, особенно на слабых системах. Рассмотрите возможность увеличения интервала или оптимизации метода paint. Например, используйте двойную буферизацию, чтобы уменьшить мерцание и повысить производительность отрисовки.

  3. Устранение проблем с кодировкой потоков.
    При загрузке аудио файлов или изображений убедитесь, что пути к этим ресурсам корректны и поддерживаются во всех операционных системах. Путь к "som/Dingw.wav" должен быть проверен на наличие в структуре проекта.

Оптимизация исполнения в среде Linux (Ubuntu)

  1. Проверка Java Runtime Environment (JRE).
    Убедитесь, что на Ubuntu установлена актуальная версия JRE, соответствующая вашей версии Java. Можно использовать java -version для проверки версии Java.

  2. Использование параметров JVM.
    Если игре не хватает памяти, увеличьте выделение памяти для JVM. Это можно сделать через параметры запуска VM, например: java -Xms256m -Xmx512m -jar yourgame.jar.

  3. Проверка производительности графической подсистемы.
    Убедитесь, что на Ubuntu установлены актуальные драйвера для вашей видеокарты. Это особенно важно, если игра использует графику и рендеринг.

  4. Обработка событий.
    Проверьте, корректно ли обрабатываются события клавиатуры и окна. Убедитесь, что метод setFocusable(true) и вызов requestFocusInWindow() правильно применяются для обеспечения ввода с клавиатуры.

Общие рекомендации

  • Логирование и дебаггинг.
    Добавьте логирование для отслеживания выполнения программы и обнаружения узких мест. Информация о том, на каком этапе происходит сбой, поможет скорейшему обнаружению и устранению проблемы.

  • Кроссплатформенное тестирование.
    Протестируйте вашу программу в разных средах исполнения (Windows, Linux) с использованием различных JDK/JRE. Это поможет идентифицировать платформозависимые проблемы.

Эти шаги помогут улучшить производительность и стабильность вашего Java-приложения как на Ubuntu, так и на Windows. Оптимизация каждого из аспектов значительно увеличит общую плавность и надёжность работы программы.

Оцените материал
Добавить комментарий

Капча загружается...