【问题标题】:Java Game Loop With editable frame cap带有可编辑框架帽的 Java 游戏循环
【发布时间】:2021-10-20 02:02:33
【问题描述】:

我正在尝试在 java 中创建一个游戏循环,该循环具有可以在游戏运行时设置的帧上限。我遇到的问题是我有一个 render() 函数和一个 update() 函数。只为 render() 和 update() 设置帧上限意味着当您更改帧上限时游戏逻辑的速度将会改变。知道如何在不影响游戏逻辑速度的情况下在游戏中设置帧上限(update())吗?

【问题讨论】:

  • 尝试使用定期触发事件(帧)的计时器,而不是循环。这会将代码翻过来。这就是 JavaFX 的 swing 正常工作方式。
  • 是的,它是图形的,我目前正在使用 swing。
  • 两个独立线程中的两个独立循环,一个用于更新,一个用于渲染。您可以调整渲染循环的延迟。
  • uffff 我过去做了很多工作,我需要刷新我的大脑才能显示完整的答案,同时,你可以看看我的项目(单个 java文件)github.com/vituchon/sleepy-screensaver/blob/master/main/… 以某种方式处理时间控制(有很多方法可以处理更新间隔)。

标签: java swing while-loop game-loop


【解决方案1】:

如 cmets 中所述:您可以创建两个线程,一个负责更新,另一个负责渲染。

尝试考虑适合您的需求和游戏的架构。您可以尝试以下方法:

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Runner extends JPanel {

    private static final long serialVersionUID = -5029528072437981456L;

    private JFrame window;
    
    private Renderer renderer;

    public Runner() {
        setPreferredSize(new Dimension(WindowData.WIDTH, WindowData.HEIGHT));
        setFocusable(true);
        requestFocus();
        
        window = new JFrame(WindowData.TITLE);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.add(this);
        window.setResizable(false);
        window.pack();
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        
        renderer = new Renderer(getGraphics());
        renderer.start();
    }
    
    public static void main(String[] args) {
        new Runner();
    }
}

import java.awt.Graphics;

public class Renderer implements Runnable {
    
    private Graphics context;

    private Thread thread;
    private boolean running;

    public Renderer(Graphics context) {
        this.context = context;

        thread = new Thread(this, "Renderer");
        running = false;
    }

    public void start() {
        if (running)
            return;
        running = true;
        thread.start();
    }

    public void render() {
        context.clearRect(0, 0, WindowData.WIDTH, WindowData.HEIGHT);
        context.fillRect(50, 50, 100, 100);
    }

    public void run() {
        while (running) {
            render();

            // ** DO YOUR TIME CONTROL HERE ** \\
        }
    }
}

此代码实际上会导致严重的性能问题,因为您无法控制渲染 (repaint()) 时间。

但这只是一个演示,向您展示如何使用不同的线程。做你自己的架构。

【讨论】:

  • 感谢您的回复。我没有使用 repaint() 而是使用我自己的渲染器在摇摆之上使用缓冲策略和其他东西所以希望这不重要。
  • 是的,这根本不重要。使用单独的线程是许多 AAA 游戏引擎中使用的非常常见的功能。例如,统一确实将物理处理与其他事物分开。使用canvas还是JPanel进行渲染也没关系。
  • 快速提问,如果我的游戏以每秒 144 帧的速度渲染,它应该以多快的速度更新?也应该以其他渲染帧速率更新相同的速度。
  • 您无需执行特定数量的更新。真的很依赖。做你的数学,你希望你的游戏反应灵敏吗?每秒进行 60 次更新,或者像您的帧一样进行 144 次更新。更新将决定您的游戏速度。
猜你喜欢
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多