如何在java中为基于资源可用性重新绘制自身的绘制方法分配每秒的限制?
我对用Java创建游戏有点陌生,但是我当前的设置是这样的:paint方法上的FPS仅受系统限制。所以,我的FPS倾向于在300到450之间。为了使物体的运动速度标准化,我一直在用FPS除以增量,这样它将在1秒的时间内增加总量 我有以下代码。我想做的是,根据FPS,每秒调用如何在java中为基于资源可用性重新绘制自身的绘制方法分配每秒的限制?,java,mouseevent,frame-rate,projectile,Java,Mouseevent,Frame Rate,Projectile,我对用Java创建游戏有点陌生,但是我当前的设置是这样的:paint方法上的FPS仅受系统限制。所以,我的FPS倾向于在300到450之间。为了使物体的运动速度标准化,我一直在用FPS除以增量,这样它将在1秒的时间内增加总量 我有以下代码。我想做的是,根据FPS,每秒调用map.addEntity()的次数不会达到300或400次;而是让我可以选择,例如,让射弹以10转/秒左右的速度发射。我怎样才能做到这一点 public void mousePressed(MouseEvent e) {
map.addEntity()
的次数不会达到300或400次;而是让我可以选择,例如,让射弹以10转/秒左右的速度发射。我怎样才能做到这一点
public void mousePressed(MouseEvent e) {
if (gameStarted)
shootProjectile = true;
}
public void paint(Graphics g) {
if (shootProjectile)
map.addEntity(new Projectile("projectile.png", x, y, 0, projectileSpeed));
}
我一直在用FPS除以增量
不要那样做!使用或swing
以恒定速率更新所有内容。例如,您可以这样做:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer(10,new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
updateProjectilePositions();
}
});
timer.start();
}
private static void updateProjectilePositions() {
// TODO Auto-generated method stub
}
}
请注意,如果使用swing计时器,您的投射物更新将发生在swing线程上。如果更新挂起,GUI也将挂起
您也不应该在paint()
内部调用map.addEntity
,因为paint()
只做一件事:绘制所有内容。你可以绕过这个问题,但是把更新位置之类的代码和渲染对象的代码混为一谈最终会让你难受
我一直在用FPS除以增量
不要那样做!使用或swing
以恒定速率更新所有内容。例如,您可以这样做:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer(10,new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
updateProjectilePositions();
}
});
timer.start();
}
private static void updateProjectilePositions() {
// TODO Auto-generated method stub
}
}
请注意,如果使用swing计时器,您的投射物更新将发生在swing线程上。如果更新挂起,GUI也将挂起
您也不应该在paint()
内部调用map.addEntity
,因为paint()
只做一件事:绘制所有内容。你可以绕过这一点,但将更新位置的代码与渲染对象的代码混合在一起最终会咬到你。你不应该使用FPS作为量化器,否则你的游戏将在不同的机器上以不同的速度运行,甚至在同一台机器上根据帧下降或峰值运行
您可以做两件不同的事情:
- 在每次帧更新和按比例更新游戏逻辑之间使用增量时间
- 使用累加器,在累加器中添加时间增量,然后每固定一个量触发一次逻辑更新(这样,您就不需要按比例进行操作,因为您的逻辑更新是固定的)
您不应该使用FPS作为量化器,否则您的游戏将在不同的机器上以不同的速度运行,甚至在同一机器上根据帧下降或峰值运行
您可以做两件不同的事情:
- 在每次帧更新和按比例更新游戏逻辑之间使用增量时间
- 使用累加器,在累加器中添加时间增量,然后每固定一个量触发一次逻辑更新(这样,您就不需要按比例进行操作,因为您的逻辑更新是固定的)
它实际上不在paint()方法中。渲染很好,但我只是想尽可能简化这个示例的代码。另外,如何使用计时器而不使屏幕闪烁?如果启用了双缓冲,它应该不会闪烁。我添加了一些示例代码。顺便说一句,在更新所有位置后,您还应该调用repaint()
。这样,在完成更新后,将立即调用paint()
。如果正在运行的计算机速度非常慢,则逻辑仍将以相同的速度运行,但每秒只能调用几次paint()
,从而导致帧跳过。通常,这是预期的结果。它实际上不在paint()方法中。渲染很好,但我只是想尽可能简化这个示例的代码。另外,如何使用计时器而不使屏幕闪烁?如果启用了双缓冲,它应该不会闪烁。我添加了一些示例代码。顺便说一句,在更新所有位置后,您还应该调用repaint()
。这样,在完成更新后,将立即调用paint()
。如果正在运行的计算机速度非常慢,则逻辑仍将以相同的速度运行,但每秒只能调用几次paint()
,从而导致帧跳过。通常情况下,这是预期的结果。但实际上我该怎么做呢?您需要存储每次重新绘制之间经过的时间,以便知道经过了多少毫秒,并相应地进行计算。当然,逻辑和图形必须是绝对不同的两件事。这与计算FPS和划分有什么区别,以便每一步每秒执行正确的次数?这是不同的,因为时间是绝对的,FPS是相对的:每次刷新可能更短或更长,所以这不是一个具有固定时间行为的好方法。如果FPS下降到一半一段时间,那么你的逻辑将表现得更慢,这是不正确的。但我实际上应该怎么做呢?你需要存储每次重新绘制之间经过的时间,这样你就知道经过了多少毫秒,并相应地进行计算。当然,逻辑和图形必须是绝对不同的两件事。这与计算FPS和划分有什么区别,以便每一步每秒执行正确的次数?这是不同的,因为时间是绝对的,FPS是相对的:每次刷新可能更短或更长,所以这不是一个具有固定时间行为的好方法。如果FPS下降到一半一段时间,那么您的逻辑将表现得较慢,这是不正确的。