Какой самый эффективный способ рендеринга 2D игры с возможностью изменения разрешения? - PullRequest
0 голосов
/ 30 июня 2018

Я пробовал:

1.Создание отдельной переменной, называемой «фактором», и умножение или деление буквально всего с ней: скорости объекта, размеров объекта, шрифтов, разрешения и т. Д. (коэффициент всегда зависит от разрешения, поэтому объекты масштабируются правильно)

public class Player extends Entity{

    float size;

    public Player(needed variables) {
        super(needed variables);
        resize();
    }

    public void resize() {
        /*
        Resize everything.
        This method is supposed to be called from a separate resizing
        function located in another class when the JFrame size is changed.

        the function has to play with the choice between divide or multiply
        variables with the factor
        */
    }

    public void tick() {
        x += velX*factor;
        y += velY*factor;
    }

    etc..

}

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

2.Рендеринг к BufferedImage и масштабирование BufferedImage для соответствия JFrame.

void render() {
    //Render the game to a new BufferedImage
    BufferedImage renderedFrame = new BufferedImage(1920, 1080, BufferedImage.TYPE_RGB);
    renderedFrame.createGraphics();
    Graphics g = renderedFrame.getGraphics();

    //Render the game ....

    //Scale the BufferedImage to fit the current resolution and render it to the Canvas
    BufferStrategy bs = getBufferStrategy();
    Graphics f = bs.getDrawGraphics();
    f.drawImage(renderedFrame.getScaledInstance(1280, 720, Image.SCALE_FAST), 0, 0, null);

    f.dispose();
    bs.show();
}

Что делает код намного более читабельным, но возникает 2 проблемы:

Проблемы с вводом мышью и изменение размера BufferedImage требует слишком много ресурсов, что делает игру медленной.

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

Есть ли лучшие способы рендеринга 2D игр? Если нет, то я подумаю о переходе на OpenGL.

Заранее спасибо.

1 Ответ

0 голосов
/ 30 июня 2018

Я сделал это наиболее успешно, масштабируя графический объект. В итоге вы получите что-то вроде следующего:

final int gameUnitsPerScreenDim = 32;

void render(JPanel panel, Graphics2D g2) {
    double pixelHeight = panel.getHeight();
    double pixelsPerGameUnit = pixelHeight / gameUnitsPerScreenDim;

    g2.scale(pixelsPerGameUnit, pixelsPerGameUnit);

    ...
}

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

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

if (this.tf == null || /* image size changed since the last frame */) {
    ...
    this.tf = AffineTransform.getScaleInstance(pxPerGu, pxPerGu);
}
g2.setTransform(this.tf);

(вызов scale создает новый AffineTransform каждый раз, когда вы его вызываете.)

Это даже немного более эффективно, хотя, вероятно, ненамного.

(Если вы хотите, вы также можете использовать преобразование, чтобы инвертировать ось Y и перевести так, чтобы начало координат было в центре изображения. Это делает большую часть тригонометрии и материала более естественными. Инвертирование оси Y хотя работа с текстом становится болезненной.)

Кроме того, использование OpenGL, вероятно, лучше. Написав пару простых игр с использованием Swing для развлечения, я не вижу веской причины для этого.

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