[Технически не [дубликат]] Я знаю, что это случалось раньше (есть ошибка, из-за которой мой JFrame не открывается при компиляции моей игры, как мне исправить это [дубликат]), и MadProgrammer ответил: «Game.main не ничего не делать. Поскольку это основная точка входа для программы, ей нужно что-то сделать, прежде чем что-то произойдет», но теперь, когда Game.main что-то делает, я не вижу ответа.
Я пробовал перекомпилировать и проверять на ошибки, ни одной, кто-то даже заставил это работать. Как я могу это исправить
Игра.java:
package com.hypopixel;
import java.awt.*;
import javax.swing.*;
import java.applet.*;
public class Game extends Canvas implements Runnable {
public static final long serialVersionUID = 1L;
private Thread thread;
private Boolean running = false;
public Game() {
new Window(800, 600, this);
}
public synchronized void start() {
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop() {
try {
thread.join();
running = false;
} catch(Exception e) {
e.printStackTrace();
}
}
public void run() {
}
public static void main(String[] args) {
new Game();
}
}
Окно.java:
package com.hypopixel;
import java.awt.*;
import javax.swing.*;
import java.applet.*;
public class Window extends Canvas {
public static int BlockSizing = 4;
public static final long serialVersionUID = 1L;
public Window(int Wwidth, int Wheight, Game game) {
JFrame Window = new JFrame();
setPreferredSize(new Dimension(Wwidth, Wheight));
setMinimumSize(new Dimension(800, 600));
Window.add(game);
Window.pack();
Window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Window.setTitle("HypoPixel");
Window.setLocationRelativeTo(null);
Window.setVisible(true);
game.start();
}
}
/*
Credits:
Just another Java Programmer
MadProgrammer
*/
manifest.txt такой же
Я ожидал, что JFrame откроется (потому что кто-то другой смог его получить), но он не открылся.




Итак, есть ряд вещей, которые «выключены»
Начиная с...
public Window(int Wwidth, int Wheight, Game game) {
JFrame Window = new JFrame();
setPreferredSize(new Dimension(Wwidth, Wheight));
setMinimumSize(new Dimension(800, 600));
Window.add(game);
Window.pack();
Window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Window.setTitle("HypoPixel");
Window.setLocationRelativeTo(null);
Window.setVisible(true);
game.start();
}
Помимо того, что в Window уже есть класс с именем java.awt, что сбивает с толку, вы используете имя переменной Window, что сбивает с толку.
Window является продолжением Canvas, но вы никогда им не пользуетесь. Вызов setPreferredSize и setMinimumSize, потому что Window на самом деле никогда ни к чему не добавляется, и обычно рекомендуется не делать этого, предпочитая вместо этого переопределять эти методы, чтобы предотвратить случайное изменение их значений.
С Game вы звоните Window... это какой-то странный способ делать что-то, так как создание окна на самом деле не входит в обязанности Games, скорее , это наоборот.
Лично я бы начал с выделенной точки входа, в обязанности которой входит, например, загрузка и подготовка среды и показ первого экрана...
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Game());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Убедитесь, что manufest.mf так, чтобы его свойство Main-Class указывало на этот класс.
Я бы также обновил Game, чтобы он переопределял getPreferredSize. Я бы также посмотрел на ваши методы start и stop.
public synchronized void start() {
thread = new Thread(this);
thread.start();
running = true;
}
Что произойдет, если это будет вызвано дважды? Вы должны проверить состояние Thread перед созданием нового
public synchronized void stop() {
try {
thread.join();
running = false;
} catch(Exception e) {
e.printStackTrace();
}
}
Это ничего не даст, так как join блокируется, поэтому состояние running никогда не изменится.
Кроме того, из-за модели памяти Java вы можете обнаружить, что даже установка running на false перед вызовом join не работает. Вместо этого вы должны использовать атомарная переменная (и использование Boolean, вероятно, вызовет множество других проблем, поскольку вы ссылаетесь на место в памяти, а не на фактическое значение)
Я бы порекомендовал прочитать параллелизм
import java.awt.Canvas;
import java.awt.Dimension;
import java.util.concurrent.atomic.AtomicBoolean;
public class Game extends Canvas implements Runnable {
public static final long serialVersionUID = 1L;
private Thread thread;
private AtomicBoolean running = new AtomicBoolean(false);
public Game() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
public synchronized void start() {
running.set(true);
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
public synchronized void stop() {
running.set(false);
if (thread == null) {
return;
}
try {
thread.join();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
}
}
the IDE I use (NetBeans) will not let me run the java file
На вкладке «Проекты» выберите класс Main/Java-файл, щелкните правой кнопкой мыши и выберите «Запустить файл».
Как вариант, при открытом в редакторе (и выбранном) Main нажмите Shift+F6
Далее убедитесь, что com.hypopixel.Main установлен в качестве проектов "основной класс"
com.hypopixel.Main, если нет, нажмите Browse... и выберите его из доступных вариантов.спасибо, я не понимал, сколько действительно не работает! Может быть, код, который я использовал, устарел, вот откуда я его взял: «youtube.com/watch?v=1gir2R7G9ws&t=40s», устарел?
@CyleLinin Одна из повторяющихся проблем, с которыми я сталкиваюсь, заключается в том, что учебные пособия на YouTube, как правило, ужасны, по моему опыту, они не предназначены для обучения «хорошей» практике, а показывают, «как» достичь определенной цели. Например, в приведенном выше коде я бы сказал, что Game не должен отвечать за управление потоком, это часть ответственности основного движка, Game действительно должен быть сосредоточен только на поверхности рендеринга, но это я. И, да, мы получаем много вопросов «Я слежу за видео на YouTube...», на которые, как правило, отвечают «не следи за ним» ;)
Подскажите, пожалуйста, как найти туториал по созданию 3D-игры? также код, который вы дали, не создает JFrame.
@CyleLinin «Кроме того, указанный вами код не создает JFrame» - Да, я запустил его перед публикацией, вы ДОЛЖНЫ запустить класс Main (он должен быть основной точкой входа). "Подскажите, пожалуйста, как найти туториал по созданию 3D-игры" — сомневаюсь, что он есть. Вам нужно будет использовать ряд источников для создания решения. Это также будет зависеть от того, какой 3D-движок вы пытаетесь использовать. Я мог бы порекомендовать потратить время на просмотр JavaFX, так как он имеет лучшую встроенную поддержку для этого.
Файл манифеста настроен с учетом «Main-Class: Main» в Main.java, и когда я скомпилирую его для получения T.jar, он не откроет JFrame с пометкой «Тестирование», как указано в коде.
@CyleLinin Мое личное предложение — сосредоточиться на решении «а» проблемы, а затем выяснить, как эта часть вписывается в общую головоломку. «Основные циклы» хорошо задокументированы и обсуждены, обновление состояния, визуализация состояния, подсчет кадров в секунду, повтор; широко обсуждается управление сущностями. Я бы попробовал просмотреть доступные движки с открытым исходным кодом, они дадут вам много полезной информации и идей, возможно, сосредоточусь на использовании одного или двух и посмотрим, в чем различия и как вы можете их использовать.
System.out.println в метод main, посмотрите, был ли вообще запущен Main. Main находится в упаковке? В Java есть проблемы с классами, помещенными в пакет по умолчанию.
Нет, ничего не делает. Нет ошибок, нет ошибок IDE, ничего, и да, это в пакете, имя пакета: "com.hypopixel"
Хорошо, вы можете запустить его из IDE? Запустить класс напрямую (из IDE)? Main-Class: Main должен больше походить на Main-Class: com.hypopixel.Main, исходя из имеющейся информации. На данный момент все, что у вас есть, это неправильная конфигурация - поэтому я связал руководство работа с файлом манифеста выше.
IDE, которую я использую (NetBeans), не позволяет мне запускать java-файл. также я не знаю, поможет ли это, но когда я компилирую, он генерирует 3 файла .class: Main.class, Main$1.class и Game.class.
В навигаторе проекта выберите класс Main (java-файл), щелкните правой кнопкой мыши и выберите «Запустить файл» или, пока файл открыт в редакторе, нажмите [Shift]+[F6]
всякий раз, когда я запускаю Main (в NetBeans), он говорит мне следующее: Исключение в потоке "AWT-EventQueue-0" java.lang.RuntimeException: Некомпилируемый исходный код - не удается найти символ: class Game at com.hypopixel.Main$1.run (Main.java:20) в java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) в java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) в java.awt.EventQueue.access$500( EventQueue.java:97) в java.awt.EventQueue$3.run(EventQueue.java:709) в java.awt.EventQueue$3.run(EventQueue.java:703) в java.security.AccessController.doPrivileged(собственный метод) а
Сначала выполните «Очистить и построить», затем запустите класс Main.
как мне ЭТО исправить?
Оба Main и Game в одном проекте? У вас есть они в правильных упаковках и правильный ли импорт. Когда вы компилируете код, вы получаете сообщения об ошибках?
@CyleLinin Кажется, вам нужен хороший учебник по Netbeans.
У меня открывается, правда в минимальном размере (только заголовок с некоторыми иконками). А минимальный размер связан с тем, что вы устанавливаете минимальный и предпочтительный размер в экземпляре
Window, но никогда не добавляете его вJFrame. ВJFrameвы добавляете экземплярGame, но не устанавливаете для него минимальный и предпочтительный размер.