Справочная информация : я работаю над довольно крупным игровым проектом, чтобы улучшить свои навыки в области ОО. Я использовал принципы SOLID и много искал (на самом деле больше, чем я его кодирую).
Проблема : я боролся с ресурсами (если быть точным, спрайтами). Во-первых, я создал класс, который загружал бы ресурсы в игре (на основе строки, в которой указывалось место размещения таблицы спрайтов в файле jar) и предоставлял к ней глобальный доступ. Он работал на основе статических переменных. Затем я прочитал, что статические переменные являются злом для ОО-проектов, и перешел к синглетонам. Затем я прочитал, что синглеты - это зло, и с тех пор я не нашел другого выхода. Я понимаю, что глобальное состояние создает много зависимостей (на самом деле, я уже чувствовал это на своей шкуре с этим классом ресурсов). Но я не могу найти хорошего способа избежать его использования.
Вопрос : В нижней части вопроса вы увидите мою реализацию для класса ресурсов и класса спрайтов. Каждый отдельный класс, который нуждается в этом, имеет графическую интерпретацию (мобы, игрок, тайлы, итены и т. Д.), Зависит от класса Sprite. И каждый класс может получить доступ к нему с помощью класса Resource (у которого в образце загружено только два ресурса, но это оффтоп). S * o, что было бы лучшим решением для этого? * (Я бы предпочел, чтобы вы ответили концепциями, а не давали мне код:))
OBS: У меня почти такая же проблема с хранением базы данных для типов плиток (см. Код ниже).
OBS2: ни база данных, ни ресурсы не изменятся во время игры. Они являются «постоянными», и я бы изменил их только для добавления новых плиток / ресурсов во время компиляции.
OBS2: у меня есть идея, которая может быть в порядке, но я не уверен:
-Создание суперкласса для спрайта / ресурсов, а затем создание подкласса для каждого типа ресурса, который мне нужен. Я не думаю, что это решение решит проблемы связывания и разделит реализацию спрайтов между различными пакетами.
public final class Resources {
private static HashMap<String, Sprite> sprites = new HashMap<String, Sprite>();
static {
loadSprites(new SpriteSheet("spritesheets/spritesheettest.png"));
}
private static void loadSprites(SpriteSheet s) {
sprites.put("Grass1", s.getRawSprite(0, 0).recolor(Color.GREEN));
sprites.put("Cave1", s.getRawSprite(0, 0).recolor(Color.GRAY));
}
public static Sprite getSprite (String name) {
return sprites.get(name);
}
}
public final class Sprite {
public static final int SIDE = 32;
private static SpriteFilter spriteFilter;
private static MySpriteRotator spriteRotator;
private BufferedImage image;
static {
spriteFilter = new MySpriteFilter();
spriteRotator = new MySpriteRotator();
}
public Sprite(BufferedImage img) {
image = img;
}
public Sprite rotate (double angle, BufferedImage sprite) {
return (spriteRotator.rotate(angle, this));
}
public Sprite recolor(Color c) {
MySpriteFilter sf = new MySpriteFilter();
return (spriteFilter.recolor(c, this));
}
public void render(Graphics2D g, int x, int y) {
g.drawImage(image, x, y, null);
}
public BufferedImage getImage() {
return image;
}
} * * тысяча двадцать-один
public final class TileDataBase {
private static HashMap<Integer, Tile> database = new HashMap<Integer, Tile>();
private static HashMap<Integer, Tile> rgbDatabase = new HashMap<Integer, Tile>();
private static final Tile grass = new MyTile(1, new Color(0, 255, 0), Resources.getSprite("Grass1"));
private static final Tile cave = new AnimatedTile(2, new Color(127, 127, 127), Resources.getSprite("Cave1"), new Animator(new Sprite[] {Resources.getSprite("Grass1"), Resources.getSprite("Cave1")}));
private TileDataBase() {
}
public static Tile getTileByID(int id, int x, int y) {
Tile t = database.get(id).cloneTile();
if (t == null) {
try {
throw new Exception("No tile for such id");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
t.setX(x);
t.setY(y);
return t;
}
static Tile getTileByRGB(int rgb, int x, int y) {
Tile t = rgbDatabase.get(rgb).cloneTile();
if (t == null) {
try {
throw new Exception("No tile for such rgb");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
t.setX(x * Sprite.SIDE);
t.setY(y * Sprite.SIDE);
return t;
}
static void putToDatabase(int id, Tile tile) {
database.put(id, tile);
}
static void putToRGBDatabase (Color c, Tile t) {
rgbDatabase.put(c.getRGB(), t);
}
}