Является ли обрезка и масштабирование фона хорошим решением для java игр? - PullRequest
0 голосов
/ 18 апреля 2020

Я очень новичок в java и сейчас я разрабатываю 2D-игру. Я пытаюсь использовать Java Swing для графики, и у меня возникают проблемы при этом:

Отображение фона, который является изображением довольно высокой четкости (в настоящее время 2000x2000, но будет увеличиваться для более высокой четкости) с картой в 50 единиц по ширине и высоте.

Проблема в том, что я не хочу отображать всю карту, а только фиксированное количество ячеек по ширине и высоте (здесь я выбрал 20 ). Сначала я попытался изменить масштаб изображения шире экрана, чтобы идеально подогнать 20 ячеек (немного как увеличение нужной области), а затем нарисовать его со смещением, связанным с положением игрока (которое всегда отображается по центру экрана).

Но хотя я пытаюсь go с большими изображениями, я получаю исключение java памяти кучи.

Так что я думал о том, чтобы получить обрезанную версию изображение, а затем измените его масштаб до размера экрана, чтобы уменьшить масштаб изображения. Я больше не получаю исключений, но у меня есть некоторые важные проблемы с производительностью с падением 30 кадров в секунду.

Я также думал о том, чтобы получить все обрезанные изображения и сохранить их, но я хотел знать, так ли это или нет.

Подводя итог, мне было интересно, каковы наилучшие способы отображения фона в играх. Поскольку в 2D-играх или даже в 3D-играх карты даже больше, чем у меня, я думаю, что мне чего-то не хватает, я не понимаю, как отображать спрайты с высоким разрешением, сохраняя при этом приличную частоту кадров. Благодарим Вас за потраченное время.

edit:

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

Вот уменьшенный вид моего примера кода:

public class Background implements Drawable, Anchor {
    private final String name;
    private final Image image;
    private final int width;


    public Background(String name){
        this.name = name;
        BufferedImage image = FileSystem.readBufferedImage(GraphicType.BACKGROUND, name);
        //image is a 2000x2000 image
        this.image = image.getScaledInstance((int)(behavior.width()
                * (Game.frame.getWidth()/(double) Settings.NB_CELLS_ON_SCREEN_WIDTH)),
                -1,
                0
        );
        //result in a 19200x19200 image
        this.width = (int)(behavior.width()
                * (Game.frame.getWidth()/(double)Settings.NB_CELLS_ON_SCREEN_WIDTH));
    }

    @Override
    public void draw(Graphics g) {
        g.drawImage(
                image,
                -8640,
                -9060,
                null);

    }

}

С вычислением класса GraphicPosition положение на экране со следующими аргументами в конструкторе: объект привязки, xOffset и yOffset

1 Ответ

0 голосов
/ 19 апреля 2020

Теперь я рисую фон, используя drawImage (Изображение img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, наблюдатель ImageObserver) В качестве matt Предполагается, что это приводит к менее значительному падению fps, потому что я больше не создаю огромное временное изображение, и хорошо в этом решении то, что разница в частоте кадров с большими изображениями кажется небольшой.

Вот код, который я использовал и работал для меня:

publi c класс Foreground реализует Drawable {

private final String name;
private final BufferedImage image;
private final Behavior behavior;
private final int width;

public Foreground(String name, Behavior behavior){
    this.name = name;
    this.image = FileSystem.readBufferedImage(GraphicType.FOREGROUND, name);
    this.behavior = behavior;
}

@Override
public void draw(Graphics g) {
    /*This variable represents the width on the image of the number of cells
    In my code its is the width on the image of 20 cells*/
    int widthOnImageForNbCellsDisplayed = (image.getWidth()/behavior.width()) * Settings.NB_CELLS_ON_SCREEN_WIDTH;

    /*This posXInImage represents the position of the top left corner of the
    area of the image we want to draw*/
    int posXInImage = (int)(
            Game.player.posX()
                    * image.getWidth()
                    / (double)behavior.width()
                    - widthOnImageForNbCellsDisplayed/2
    );
    int posYInImage = (int)(
            Game.player.posY()
                    * image.getHeight()
                    / (double)behavior.height()
                    - widthOnImageForNbCellsDisplayed/2
    );
    /*Here is struggled with the fact that the position of the second 
    coordinates is absolute and not relative to the first coordinates
    ,what I was originally thinking*/
    g.drawImage(image,
            0,
            -(Game.frame.getWidth() - Game.frame.getHeight())/2,
            Game.frame.getWidth(),
            Game.frame.getWidth()-(Game.frame.getWidth() - Game.frame.getHeight())/2,
            posXInImage,
            posYInImage,
            posXInImage + widthOnImageForNbCellsDisplayed,
            posYInImage + widthOnImageForNbCellsDisplayed,
            null);
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...