Java 渲染到JPanel的最快方法是什么?
所以我正在制作一些小型2D游戏引擎。 到目前为止,它工作得很好,但是渲染有点抖动,每1-2秒有一个延迟(帧冻结半秒)。尽管这很难成为交易的破坏者,但它仍然是一个需要解决的问题,我显然有点好奇为什么会这样 因此,我当前渲染帧的方法是通过操纵某个JPanel的g2d对象: (img是绘制的地图。此方法是一个类的一部分,该类包含所有信息,如屏幕的宽度和高度以及相机的位置。(因此,PosX、PosY、width、height是从调用它的对象的位置获取的)Java 渲染到JPanel的最快方法是什么?,java,swing,rendering,game-engine,Java,Swing,Rendering,Game Engine,所以我正在制作一些小型2D游戏引擎。 到目前为止,它工作得很好,但是渲染有点抖动,每1-2秒有一个延迟(帧冻结半秒)。尽管这很难成为交易的破坏者,但它仍然是一个需要解决的问题,我显然有点好奇为什么会这样 因此,我当前渲染帧的方法是通过操纵某个JPanel的g2d对象: (img是绘制的地图。此方法是一个类的一部分,该类包含所有信息,如屏幕的宽度和高度以及相机的位置。(因此,PosX、PosY、width、height是从调用它的对象的位置获取的) public void DrawbyManufa
public void DrawbyManufacturedMapsuImage(BuffereImage img,Graphics2D)
{
如果(isActive)
{
BuffereImage img2=img.getSubimage(PosX,PosY,width,height);
g2d.drawImage(img2,0,0,null);
List MapObjects=Map.getObjectInformation();
List UC=this.UI.getUiComponents();
int l=this.Map.getObjectInformation().size();
对于(int i=0;i
这基本上就是,它
- 由于
的原因,您不应该使用Thread.sleep(int),只有在您想要模拟一些长时间和昂贵的睡眠的情况下,否则就使用TimerThread.sleep(int)
==Thread.sleep(0)
冻结当前JVM实例直到循环结束,在该循环被0毫秒
Thread.sleep()冻结之前不会发生任何事情
- 本机操作系统中的延迟不低于16毫秒,25可能是一个限制,但使用计时器代替此值
g2d.drawImage
- 今天的
Java6/7
- 应通过
中的覆盖JPanel
调用paintComponent
- 1.
内的代码行应为paintComponent
==重置所有以前的绘制,否则绘制累积super.paintComponent()
- 以33-50毫秒的合理频率延迟或重新喷漆
- 在Swing中绘制时,将当前快照存储在
中是一种很好的做法,所有易失性变量或对象都可以存储在buffereImage
中,在paintComponent内部存储到g2d.drawImage中,其余的绘制将循环到已准备好的List
对象数组中(
)List
为了获得更好的帮助,请尽快发布一个简短、可运行、可编译的凌晨问题由于分配过多,您可能会遇到垃圾收集暂停。有些方法对于分配非常可疑(例如“GetCurrentlyActiveframeasBuffereImage”)。 使用VisualGC检查分配率,然后改进您的程序或尝试获得一个大的eden。位图/byte[]等大型二进制对象直接分配到OldSpace上,因此如果创建太多,将触发大量oldGC暂停。如果是这种情况,调整eden大小将无济于事 编辑:通过使用-verbose:GC选项运行您的程序,检查“暂停”是否与GC相关您应该在ActionListener中更改坐标后调用container.repaint()添加Swing计时器(50-125)
public void DrawByManipulatedMapSubimage(BufferedImage img, Graphics2D g2d)
{
if (isActive)
{
BufferedImage img2 = img.getSubimage(PosX, PosY, width, height);
g2d.drawImage(img2,0,0,null);
List<MapObject> MapObjects = Map.getObjectInformation();
List<UiComponent> UC = this.UI.getUiComponents();
int l = this.Map.getObjectInformation().size();
for (int i = 0; i < l; i++)
{
MapObject MO = MapObjects.get(i);
int MOX = MO.getPosX();
int MOY = MO.getPosY();
BufferedImage MOB = MO.getCurrentAnimation().getCurrentlyActiveFrameAsBufferedImage();
g2d.drawImage(MOB, MOX - PosX, MOY - PosY, null);
}
for (int i = 0; i < UC.size(); i++)
{
UiComponent CC = UC.get(i);
if (CC.isVisible())
{
Point P = CC.getPosition();
int x = P.x;
int y = P.y;
g2d.drawImage(CC.getImg(),x,y,null);
}
}
try
{
Thread.sleep(0);
}
catch (InterruptedException ex)
{
Logger.getLogger(Viewport.class.getName()).log(Level.SEVERE, null, ex);
}
}
}