[英]How to reduce lag in my java 2d platformer?
我正在使用Swing Java开发2D平台游戏,我想知道如何减少从它获得的延迟。 我的意思是,它并不会太落后,但值得注意的是它有时会变慢。 我有一个在12毫秒处滴答作响的Swing计时器,一个循环功能和一个绘画功能。
public void cycle() {
if (guy.getJumpState() == false) {
if (canExecuteMovement(0, 4)) {
onGround = false;
if (guy.getY() > 300) {
// if you are in the middle, move the platforms.
for (int i = 0; i < platformCount; i++) {
platform[i].setY(platform[i].getY() - 4);
}
} else {
// or just move the guy if not.
guy.moveY(4);
}
} else {
onGround = true;
}
} else {
if (canExecuteMovement(0, -8)) {
if (guy.getY() < 300) {
// if you are in the middle, move the platforms.
for (int i = 0; i < platformCount; i++) {
platform[i].setY(platform[i].getY() + 8);
}
} else {
// or just move the guy if not.
guy.moveY(-8);
}
jumpCount++;
if (jumpCount >= 15) {
jumpCount = 0;
guy.setJumpState(false);
}
} else {
jumpCount = 0;
guy.setJumpState(false);
}
}
if (guy.getDirection() == "left") {
if (canExecuteMovement(-3, 0)) {
if (guy.getX() < 450) {
// if you are in the middle, move the platforms.
for (int i = 0; i < platformCount; i++) {
platform[i].setX(platform[i].getX() + 3);
}
} else {
// or just move the guy if not.
guy.moveX(-3);
}
}
} else if (guy.getDirection() == "right") {
if (canExecuteMovement(3, 0)) {
if (guy.getX() > 450) {
// if you are in the middle, move the platforms.
for (int i = 0; i < platformCount; i++) {
platform[i].setX(platform[i].getX() - 3);
}
} else {
// or just move the guy if not.
guy.moveX(3);
}
}
}
}
public void paint(Graphics g) {
super.paint(g); // something important
Graphics2D g2d = (Graphics2D) g;
// draw platforms
for (int i = 0; i < platformCount; i++) {
if (platform[i].getX() > -50 && platform[i].getX() < 950 && platform[i].getY() > -50 && platform[i].getY() < 650) {
g2d.drawImage(platform[i].getImage(), platform[i].getX(), platform[i].getY(), this);
}
}
// draw guy
g2d.drawImage(guy.getImage(), guy.getX(), guy.getY(), this);
// destroy unneeded processes
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
我该怎么做才能优化这一点并减少延迟? 当我为循环功能本身创建线程时,平台有时会瞬间分开。 我假设是因为线程是异步的,所以它的一半是在paint函数打开时完成的。
一些松散的想法(自从我在Swing中制作动画以来已经有好几年了),并且您没有发布一些可编译的代码。
Toolkit.getDefaultToolkit().sync()
如果这样做没有帮助,请使用探查器查找瓶颈。 Visual VM非常不错。 另外,Visual VM在一段时间内还是jdk的一部分-只需进入bin文件夹并启动jvisualvm。
编辑:(线程问题)
paint()
而是在调用repeaint()
。 如果您确实调用了paint()
(无论您使用什么黑魔法都可以使它起作用),请仅调用repaint()
即可在适当的时间安排修复。 我会在方法之外创建变量,以免每次调用该方法时都不会创建该变量。 编写游戏程序的最佳方法是重用事物而不是破坏和创造,因为破坏和创造会消耗大量的计算能力。
Graphics2D g2d = (Graphics2D) g; <---declare it outside your method.
并尝试查找多余的条件。 我在您说的地方看到了一个(如果向右的方向是...,否则向左的方向...); 只是说(如果方向正确,则...否则...)。 有条件的花费不多,但是当您每秒调用该有条件的1000次时,我认为它加起来了。 (虽然idk,但我这样做是为了以防万一,并使事情变得流畅)
在说setjumpstate(false)
的地方,这是多余的,因为无论执行什么操作,都将其执行-只需将其移至条件setjumpstate(false)
之外即可。
首先,这是一个问题:
// destroy unneeded processes
Toolkit.getDefaultToolkit().sync();
g.dispose();
通常,处置未创建的资源可能是个坏主意。 在这种特定情况下,传递给paint()
的Graphics
可能会被层次结构中的所有其他组件使用,因此这可能会导致非常奇怪的结果。
我认为在这里调用Toolkit.sync()
是您尝试消除在后台移动事物时看到的撕裂感的尝试。 但是,它所做的只是刷新所有未决的绘制指令。 这在这里没有效果,因为您可能正在绘制一个将在以后完全绘制的后缓冲Swing组件。
消除撕裂的正确方法是在事件线程上执行任何更新,以便在绘制时不会更改屏幕数据。 一种简单的实现方法是让您的计时器只调用repaint()
,并在执行任何操作之前让paint()
方法调用cycle()。
为了处理延迟,一种解决方案可能是允许使用可变帧速率。 不必将所有内容每帧移动固定距离,而是计算自上一帧以来的时间并相应地移动所有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.