可以更改分辨率的呈现2D游戏的最有效方法是什么?

时间:2018-06-29 22:31:27

标签: java awt resolution

我尝试过:

1。创建一个单独的变量,称为“ factor”,并用它逐字乘以或除以所有东西:实体速度,对象大小,字体,分辨率等。 (该因子始终与分辨率有关,因此可以正确缩放对象)

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();
}

这使代码更具可读性,但随后出现两个问题:

鼠标输入问题并调整BufferedImage的大小会占用过多资源,这会使游戏变得迟钝。

3。我基本上可以尝试为游戏制作一个单独的单位系统..但是然后存在一个相同的问题,当涉及到渲染字符串或矩形时,我必须将所有内容乘以该因子,并且代码太糟糕了。之后。

是否有更好的渲染2D游戏的方法?如果没有,那么我将考虑继续使用OpenGL。

谢谢。

1 个答案:

答案 0 :(得分:0)

我最成功地完成此操作的方法是缩放图形对象。您最终会得到以下内容:

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编写了一些简单的游戏很有趣,我看不出这样做的充分理由。