Поэтому я хочу разработать небольшой игровой движок. У него есть основные классы движка, такие как Vector и Actor, которые может использовать пользователь. Поскольку мне нужен движок только один раз, я хочу, чтобы игры использовали один и тот же движок, и чтобы все игры не находились в одной банке, я намерен разместить их в отдельных папках, одну с движком, а затем папки для каждой игры. . Затем двигатель должен быть в состоянии загрузить, например. Класс игрока из другой папки и используйте его.
Я думал, что одним из решений может быть компиляция папки с игрой во время выполнения. Но тогда проблема будет заключаться в том, что файлы зависят друг от друга и от скомпилированных классов, уже загруженных в JVM. Для этого подхода:
Итак, в качестве примера у нас есть три класса: Актер из движка, Игрок, расширяющий класс актеров движка, написанный пользователем, и третий класс, элемент, написанный пользователем, порожденный в проигрывателе, но снова нуждающийся в проигрывателе. быть скомпилированы, что означает, что они не могут быть скомпилированы один за другим.
Насколько я понимаю, Актер уже будет скомпилирован в JVM, когда мы запустим программу. Теперь мы знаем папку со всеми классами для компиляции, где Player зависит от скомпилированного класса в JVM и некомпилированного класса в папке, которая зависит от Player.
Теперь я хочу скомпилировать класс Player, при этом мы также должны скомпилировать Item, а затем создать экземпляр Player, чтобы мы могли перемещаться и создавать элементы.
Вот основной пример того, что я имею в виду:
// already compiled in eg. executing jar file
class MainStuff
{
public static void main(String args[])
{
String FolderOfUncompiledClasses = "Some/folder/to/src/";
Class<?>[] CompiledClasses = CompileFolderContents(FolderOfUncompiledClasses);
// iterating through compiled classes
for (Class<?> C : CompiledClasses)
{
// if we have an Actor class, we create a new instance
if (C.isAssignableFrom(Actor.class))
{
try
{
C.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e)
{
e.printStackTrace();
}
}
}
}
// should compile all the files and returns the classes of the compiled java files
private static Class<?>[] CompileFolderContents(String Folder)
{
File[] JavaFiles = new File(Folder).listFiles();
Class<?>[] CompiledClasses = new Class<?>[JavaFiles.length];
for (int i = 0; i < JavaFiles.length; i++)
{
Class<?> CompiledClass = DoCompilationStuff(JavaFiles[i]);
CompiledClasses[i] = CompiledClass;
}
return CompiledClasses;
}
// this should effectively compile the class which it can both use non compiled
// java files in the folder and already compiled classes
private static Class<?> DoCompilationStuff(File ToCompile)
{
return null;
}
}
// already compiled in eg. executing jar file
class Actor
{
int X, Y;
}
В папке где-то на диске:
// not compiled
class Player extends Actor
{
public Player()
{
// uses other non compiled class
new Item();
}
}
// not compiled
class Item
{
// Also uses Actor so we can't compile them in series
public Item(Player P)
{
}
}
Я пытался использовать команду javac, но я не могу заставить ее работать со всей структурой папок.
Надеюсь, я объяснил это логично, и если этот подход не имеет смысла. Это была просто идея, если у вас есть лучший подход, я был бы очень рад услышать это.
Большое спасибо!




Если вам действительно нужно использовать javac, держите классы в одном и том же упаковка и каталоге. Это упростит процесс сборки, вместо того, чтобы использовать аргумент -cp для указания пути к классу, существующего в нескольких разных каталогах.
Я бы рекомендовал вместо ручной компиляции настроить проект с помощью системы сборки, например. Грейдл. Если вы посмотрите на документы Gradle Создание Java-приложений, это займет около 10 минут, и у вас должно быть все необходимое: сборка, тесты и упаковка.