Java 更好的游戏循环/引擎
我对Java游戏编程相当陌生,我想知道是否有人能帮我完成游戏循环。我试图避免使用预先制作的引擎库,我想看看自己是否能做到这一点。目前,我的游戏循环给了我一个非常低的FPS,有时甚至是个位数。在这种情况下,我必须使用多线程吗?还是有更好的方法解决这个问题?非常感谢您的帮助 下面是运行游戏循环的代码。我不包括所有的代码,因为它将有很多文件,但我认为这可能足够了,如果您需要更多,请告诉我。我还提供了一个我正在尝试创建的游戏的屏幕截图。提前谢谢Java 更好的游戏循环/引擎,java,Java,我对Java游戏编程相当陌生,我想知道是否有人能帮我完成游戏循环。我试图避免使用预先制作的引擎库,我想看看自己是否能做到这一点。目前,我的游戏循环给了我一个非常低的FPS,有时甚至是个位数。在这种情况下,我必须使用多线程吗?还是有更好的方法解决这个问题?非常感谢您的帮助 下面是运行游戏循环的代码。我不包括所有的代码,因为它将有很多文件,但我认为这可能足够了,如果您需要更多,请告诉我。我还提供了一个我正在尝试创建的游戏的屏幕截图。提前谢谢 package com.Farthorn.game; i
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;
}
}
正如您可能知道的,我正在渲染许多外部图像。可能是渲染效率低下导致其低于您的目标60hz。除此之外,您的追赶循环中肯定存在一个问题:
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1)
{
tick();
delta--;
}
由于tick例程也调用render,tick本身实际上是一个帧,但您并没有增加帧计数器。您的勾选应该会导致所有部分更新,但不会渲染图像,渲染应该每帧只调用一次。您可能想从勾选例程中删除渲染线。您可能会更好地询问此问题,但在发布之前请查看他们的帮助中心。哇,我甚至都没意识到我又在调用渲染,非常感谢您,完全修复了FPS!