[英]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.