实现游戏播放的最佳方式?

发布于 2024-07-18 08:24:48 字数 405 浏览 10 评论 0原文

我正在用 Java 创建一个基于网格的游戏,我想实现游戏录制和播放。 我不知道如何做到这一点,尽管我考虑过两个想法:

  1. 每秒几次,我会记录整个游戏状态。 为了回放它,我编写了一个渲染器来读取状态并尝试创建视觉表示。 然而,这样一来,我的保存文件可能会很大,并且任何播放尝试都可能会出现明显的延迟。

  2. 我还可以将每次按键和鼠标点击写入保存文件中。 这会给我一个更小的文件,并且可以以更少的延迟进行播放。 然而,游戏开始时最轻微的错误(例如,1毫秒后射击)都会导致游戏几分钟后的游戏状态截然不同。

那么,实现游戏播放的最佳方式是什么?

编辑-我不确定我的游戏到底有多大的确定性,所以我不确定整个游戏是否可以通过仅记录击键和鼠标点击来准确地拼凑在一起。

I'm creating a grid based game in Java and I want to implement game recording and playback. I'm not sure how to do this, although I've considered 2 ideas:

  1. Several times every second, I'd record the entire game state. To play it back, I write a renderer to read the states and try to create a visual representation. With this, however, I'd likely have a large save file, and any playback attempts would likely have noticeable lag.

  2. I could also write every key press and mouse click into the save file. This would give me a smaller file, and could play back with less lag. However, the slightest error at the start of the game (For example, shooting 1 millisecond later) would result in a vastly different game state several minutes into the game.

What, then, is the best way to implement game playback?

Edit- I'm not sure exactly how deterministic my game is, so I'm not sure the entire game can be pieced together exactly by recording only keystrokes and mouse clicks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

梦纸 2024-07-25 08:24:48

一个好的播放机制并不是简单地添加到游戏中就不会遇到很大困难的。 最好的方法是在设计游戏基础设施时考虑到这一点。 命令模式可用于实现这样的游戏基础设施。

例如:

public interface Command{
    void execute();
}
public class MoveRightCommand implements Command {
   private Grid theGrid;
   private Player thePlayer;

   public MoveRightCommand(Player player, Grid grid){
        this.theGrid = grid;
        this.thePlayer = player;
       }

   public void execute(){
     player.modifyPosition(0, 1, 0, 0);
   } 
}

然后,当用户按下键盘按钮、移动鼠标​​或没有使用播放机制的触发器时,可以将命令两者推送到执行队列中。 命令对象可以有一个时间戳值(相对于播放的开始)以实现精确播放......

A good playback mechanism is not something that can be simply added to a game without major difiiculties. The best would be do design the game infrastructure with it in mind. The command pattern can be used to achieve such a game infrastructure.

For example:

public interface Command{
    void execute();
}
public class MoveRightCommand implements Command {
   private Grid theGrid;
   private Player thePlayer;

   public MoveRightCommand(Player player, Grid grid){
        this.theGrid = grid;
        this.thePlayer = player;
       }

   public void execute(){
     player.modifyPosition(0, 1, 0, 0);
   } 
}

And then the command can be pushed in an execution queue both when the user presses a keyboard button, moves the mouse or without a trigger with the playback mechanism. The command object can have a time-stamp value (relative to the beginning of the playback) for precise playback...

看透却不说透 2024-07-25 08:24:48

Shawn Hargreaves 最近在他的博客上发表了一篇关于他们如何在 MotoGP 中实现重播的文章。 介绍了几种不同的方法及其优缺点。

http://blogs.msdn.com/shawnhar/存档/2009/03/20/motogp-replays.aspx

Shawn Hargreaves had a recent post on his blog about how they implemented replay in MotoGP. Goes over several different approaches and their pros and cons.

http://blogs.msdn.com/shawnhar/archive/2009/03/20/motogp-replays.aspx

友欢 2024-07-25 08:24:48

假设您的游戏是确定性的,那么记录用户的输入可能就足够了(选项 2)。 但是,您需要确保您识别这些事件的正确且一致的时间,例如服务器识别的时间。 我不确定你如何处理网格中的事件。

我担心的是,如果您没有可以统一引用定时事件的机制,那么您的代码处理分布式用户的方式可能会出现问题。

以 XBOX 360 上的 Halo 3 等游戏为例,每个客户端都会记录他对游戏的看法,包括基于服务器的更正。

Assuming that your game is deterministic, it might be sufficient if you recorded the inputs of the users (option 2). However, you would need to make sure that you are recognizing the correct and consistent times for these events, such as when it was recognized by the server. I'm not sure how you handle events in the grid.

My worry is that if you don't have a mechanism that can uniformly reference timed events, there might be a problem with the way your code handles distributed users.

Consider a game like Halo 3 on the XBOX 360 for example - each client records his view of the game, including server-based corrections.

方觉久 2024-07-25 08:24:48

为什么不每秒记录几次,然后压缩你的输出,或者也许这样做:

recordInitialState();
...
runs 30 times a second:
recordChangeInState(previousState, currentState);
...

如果你只记录带有时间戳的状态变化(并且每次变化很小,如果没有变化,则不记录任何内容),你应该最终得到合理的文件大小。

Why not record several times a second and then compress your output, or perhaps do this:

recordInitialState();
...
runs 30 times a second:
recordChangeInState(previousState, currentState);
...

If you only record the change in state with a timestamp(and each change is small, and if there is no change, then record nothing), you should end up with reasonable file sizes.

吐个泡泡 2024-07-25 08:24:48

无需为每一帧保存场景中的所有内容。 增量保存更改并使用一些好的插值技术。 我不会真正使用基于命令模式的方法,而是以固定的速率对每个游戏对象进行检查,看看它是否更改了任何属性。 如果发生更改,则该更改会以某种良好的编码进行记录,并且重播甚至不会变得那么大。

There is no need to save everything in the scene for every frame. Save changes incrementally and use some good interpolation techniques. I would not really use a command pattern based approach, but rather make checks at a fixed rate for every game object and see if it has changed any attribute. If there is a change that change is recorded in some good encoding and the replay won't even become that big.

暮色兮凉城 2024-07-25 08:24:48

如何实现这一点在很大程度上取决于您在游戏中使用的语言,但总的来说,有很多方法,具体取决于您是否想要使用大量存储空间或想要一些延迟。 如果您能思考一下您愿意做出哪些牺牲,将会很有帮助。

但是,正如前面提到的,最好的方法似乎可能是只保存用户的输入,并且同时存储游戏中所有演员/精灵的位置,这就像只保存方向一样简单、速度和平铺 x,y,或者,如果一切都是确定性的,则忽略演员/精灵,因为您可以获得他们的信息。

您的游戏的不确定性也有助于提供更好的建议。

如果有大量的动态运动,例如撞车德比,那么您可能需要保存每一帧的信息,因为您应该以特定的帧速率更新玩家/演员。

How you approach this will depend greatly on the language you are using for your game, but in general terms there are many approaches, depending on if you want to use a lot of storage or want some delay. It would be helpful if you could give some thoughts as to what sacrifices you are willing to make.

But, it would seem the best approach may be to just save the input from the user, as was mentioned, and either store the positions of all the actors/sprites in the game at the same time, which is as simple as just saving direction, velocity and tile x,y, or, if everything can be deterministic then ignore the actors/sprites as you can get their information.

How non-deterministic your game is would also be useful to give a better suggestion.

If there is a great deal of dynamic motion, such as a crash derby, then you may want to save information each frame, as you should be updating the players/actors at a certain framerate.

假面具 2024-07-25 08:24:48

我只想说,记录游戏重播的最佳方式完全取决于游戏的性质。 基于网格不是问题;问题在于。 问题是状态变化之后的可预测行为、系统新输入的频率、是否在任何点注入随机数据等等,您只需依次记录每个动作就可以存储整个国际象棋游戏,但这对于没有明确转弯的第一人称射击游戏来说是行不通的。 您可以通过记录每个输入的确切时间来存储第一人称射击游戏,但这不适用于角色扮演游戏,因为输入的结果可能会被随机掷骰子的结果修改。 如果重要信息立即出现并且不以任何可捕获的形式持续存在,那么即使是尽可能频繁地拍摄快照这一看似万无一失的想法也不够好。

有趣的是,这与网络中遇到的问题非常相似。 一台计算机如何确保另一台计算机了解游戏状态,而不必以不切实际的高频率发送整个游戏状态? 典型的方法最终是事件通知和状态更新的定制组合,这可能正是您在这里需要的。

I would simply say that the best way to record a replay of a game depends entirely on the nature of the game. Being grid based isn't the issue; the issue is how predictable behaviour is following a state change, how often there are new inputs to the system, whether there is random data being injected at any point, etc, You can store an entire chess game just by recording each move in turn, but that wouldn't work for a first person shooter where there are no clear turns. You could store a first person shooter by noting the exact time of each input, but that won't work for an RPG where the result of an input might be modified by the result of a random dice roll. Even the seemingly foolproof idea of taking a snapshot as often as possible isn't good enough if important information appears instantaneously and doesn't persist in any capturable form.

Interestingly this is very similar to the problem you get with networking. How does one computer ensure that another computer is made aware of the game state, without having to send that entire game state at an impractically high frequency? The typical approach ends up being a bespoke mixture of event notifications and state updates, which is probably what you'll need here.

我最亲爱的 2024-07-25 08:24:48

我曾经借用视频压缩的一个想法来做到这一点:关键帧和中间帧。 基本上,每隔几秒钟你就会保存世界的完整状态。 然后,每次游戏更新时,您都会保存自上次游戏更新以来对世界状态发生的所有更改。 详细信息(您保存关键帧的频率?究竟什么算作“世界状态的更改”?)将取决于您需要保留哪种游戏信息。

在我们的例子中,世界由许许多多的游戏对象组成,其中大多数在任何给定时间都保持静止,因此这种方法在记录不移动对象的位置时节省了我们大量的时间和内存。 在你看来,权衡可能会有所不同。

I did this once by borrowing an idea from video compression: keyframes and intermediate frames. Basically, every few seconds you save the complete state of the world. Then, once per game update, you save all the changes to the world state that have happened since the last game update. The details (how often do you save keyframes? What exactly counts as a 'change to the world state'?) will depend on what sort of game information you need to preserve.

In our case, the world consisted of many, many game objects, most of which were holding still at any given time, so this approach saved us a lot of time and memory in recording the positions of objects that weren't moving. In yours the tradeoffs might be different.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文