我对Java中的游戏编程很新,我想知道是否有人可以帮我解决游戏循环问题。我试图避免使用预制的引擎库(我想看看我是否可以自己动手)。目前,我的游戏循环给了我一个非常低的FPS,有时甚至是一位数。这是我必须使用多线程的情况吗?或者有更好的解决方案吗?非常感谢任何帮助!
这是运行游戏循环的代码。我没有包含所有代码(因为它会包含很多文件),但我认为这可能就够了,请告诉我你是否需要更多代码。我还包括我正在尝试创建的游戏截图。提前谢谢!
package com.Farthorn.game;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferStrategy;
import javax.swing.ImageIcon;
public class Game extends Canvas implements Runnable
{
private static final long serialVersionUID = -4431078110090264106L;
public final static int WIDTH = 640;
public final static int HEIGHT = WIDTH / 12 * 9;
private Thread thread;
private boolean running = false;
private CharacterHandler cHandler;
private ObjectHandler oHandler;
public int change = 0;
private String mapBackgroundTop = "/Users/Ahhblala/Desktop/FarthornPics/background_top.png";
private String mapBackgroundBottom = "/Users/Ahhblala/Desktop/FarthornPics/background_bottom.png";
private Image backgroundTop;
private Image backgroundBottom;
public Game()
{
ImageIcon i = new ImageIcon(mapBackgroundTop);
backgroundTop = i.getImage();
i = new ImageIcon(mapBackgroundBottom);
backgroundBottom = i.getImage();
cHandler = new CharacterHandler();
cHandler.addCharacter(new Player(ID.Player, WIDTH/2-32, HEIGHT/2+64));
cHandler.addCharacter(new PlantEnemy(ID.PlantEnemy, WIDTH+180, HEIGHT/2+104, (Player) cHandler.characters.getLast()));
cHandler.addCharacter(new PlantEnemy(ID.PlantEnemy, WIDTH+195, HEIGHT/2+104, (Player) cHandler.characters.get(0)));
cHandler.addCharacter(new PlantEnemy(ID.PlantEnemy, WIDTH+300, HEIGHT/2+104, (Player) cHandler.characters.get(0)));
cHandler.addCharacter(new PlantEnemy(ID.PlantEnemy, WIDTH+315, HEIGHT/2+104, (Player) cHandler.characters.get(0)));
oHandler = new ObjectHandler();
oHandler.addObject(new HUD(10, 10, cHandler));
this.addKeyListener(new KeyInput(cHandler));
this.addMouseListener(new MouseInput(((Player) cHandler.characters.get(0))));
FarthornWindow window = new FarthornWindow(WIDTH, HEIGHT, this);
}
public synchronized void start()
{
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop()
{
try
{
thread.join();
running = false;
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
this.requestFocus();
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while (running)
{
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1)
{
tick();
delta--;
}
if (running)
{
render();
}
frames++;
if(System.currentTimeMillis() - timer > 1000)
{
timer += 1000;
System.out.println("FPS " + frames);
frames = 0;
}
}
stop();
}
private void tick()
{
int deltaX = 0;
int afterX = 0;
deltaX = cHandler.characters.get(0).getX();
oHandler.tick();
cHandler.tick();
deltaX = cHandler.characters.get(0).getX();
if (deltaX != afterX)
change = (afterX-deltaX);
else
change = 0;
render();
}
private void render()
{
BufferStrategy bs = this.getBufferStrategy();
if (bs == null)
{
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(backgroundTop, 0+change, 0, null);
g.drawImage(backgroundBottom, 0+change, 364, null);
oHandler.render(g);
cHandler.render(g);
g.dispose();
bs.show();
}
public static int clamp(int var, int min, int max)
{
if (var >= max)
{
return var = max;
}
else if (var <= min){
return var = min;
}
else
return var;
}
}
正如你可能会说的那样,我正在渲染很多外部图像。
答案 0 :(得分:0)
你的渲染可能效率低下,导致它低于目标60hz。除此之外,你的#34;赶上&#34;肯定存在问题。循环:
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1)
{
tick();
delta--;
}
由于tick()例程也调用render(),因此tick()实际上是一个帧,但是你没有递增帧计数器。你的tick()应该导致所有部分更新,但不渲染图像,渲染应该每帧只调用一次。您可能希望从tick()例程中删除render()行。