渲染具有更改分辨率可能性的 2D 游戏的最有效方法是什么?
What is the most efficient way of rendering 2D game with the possibility of changing the resolution?
我试过:
1.Creating 一个名为 "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.Rendering 到 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.I 基本上可以尝试为游戏制作一个单独的单位系统.. 但同样的问题是,当涉及到渲染字符串或矩形时,我必须将所有内容乘以因子和之后的代码很糟糕。
有没有更好的2D游戏渲染方式?如果没有,那么我会考虑转向 OpenGL。
提前致谢。
我最成功的方法是缩放图形对象。您最终会得到如下内容:
final int gameUnitsPerScreenDim = 32;
void render(JPanel panel, Graphics2D g2) {
double pixelHeight = panel.getHeight();
double pixelsPerGameUnit = pixelHeight / gameUnitsPerScreenDim;
g2.scale(pixelsPerGameUnit, pixelsPerGameUnit);
...
}
然后对于模拟,您使用游戏单元。游戏单元实际有多大有点随意,但如果您正在制作平铺游戏,则可能有一些明显的价值。
而不是使用 scale
, you can also create an 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 -axis 使处理文本变得很痛苦。)
此外,使用 OpenGL 可能更好。为了好玩而使用 Swing 编写了几个简单的游戏,我看不出这样做的充分理由。
我试过:
1.Creating 一个名为 "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.Rendering 到 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.I 基本上可以尝试为游戏制作一个单独的单位系统.. 但同样的问题是,当涉及到渲染字符串或矩形时,我必须将所有内容乘以因子和之后的代码很糟糕。
有没有更好的2D游戏渲染方式?如果没有,那么我会考虑转向 OpenGL。
提前致谢。
我最成功的方法是缩放图形对象。您最终会得到如下内容:
final int gameUnitsPerScreenDim = 32;
void render(JPanel panel, Graphics2D g2) {
double pixelHeight = panel.getHeight();
double pixelsPerGameUnit = pixelHeight / gameUnitsPerScreenDim;
g2.scale(pixelsPerGameUnit, pixelsPerGameUnit);
...
}
然后对于模拟,您使用游戏单元。游戏单元实际有多大有点随意,但如果您正在制作平铺游戏,则可能有一些明显的价值。
而不是使用 scale
, you can also create an 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 -axis 使处理文本变得很痛苦。)
此外,使用 OpenGL 可能更好。为了好玩而使用 Swing 编写了几个简单的游戏,我看不出这样做的充分理由。