简体   繁体   English

在基于文本的游戏中处理时间(Java)

[英]Handling time in a text-based game (Java)

I'm trying to work up a basic text-based game as I'm learning Java. 我正在尝试编写一个基于文本的基本游戏,因为我正在学习Java。 I'd like to be able to count rounds in the game as a means of managing the pacing of certain events. 我希望能够在游戏中计算轮次,以此来管理某些事件的节奏。 For instance, changing rooms could be limited to once per round (a second, in the test code.) A small creature might attack or change rooms at a higher rate, whereas a larger one might be more cumbersome. 例如,更换房间可以限制为每轮一次(在测试代码中为一秒)。小型生物可能以更高的速率攻击或更换房间,而较大的房间可能更麻烦。 Good so far? 目前很好? Great. 大。

So, I cooked this up and immediately realized that I'd be hitting a block each time the while loop waited for the player to input a command. 所以,我把它煮熟了,立刻意识到每次while循环等待玩家输入命令时我都会碰到一个块。 Code: 码:

private void startPlaying() {
    //declare clock/round variables.
    int lastRound = 0;
    int currentRound = 0;
    long lastTime = System.currentTimeMillis();
    long currentTime;

    while (player.getIsPlaying()){
        //Clocking
        currentTime = System.currentTimeMillis();
        if ((lastTime + 1000) < currentTime) {
            lastTime = currentTime;
            lastRound = currentRound;
            currentRound++;
            System.out.println("Current round:\t" + currentRound + "\tCurrent time:\t" + currentTime); //EDIT:NOTE: This is just a test line to observe the loop.
        }//end if (Clocking)

        Command command = new Command();
        String[] commandString = command.setAll(); //Array gets parsed elsewhere.
        player.doCommand(commandString);  
        //Class Player extends Pawn extends Actor; Pawn has most command methods.
    }
    finishPlaying();
}//END STARTPLAYING()

So, here is my question: 所以,这是我的问题:

Is there a way I could use a separate method to log time/rounds concurrent to the while loop presenting the player with a command prompt? 有没有办法我可以使用一个单独的方法来记录时间/轮并发到while循环向玩家提供命令提示符?

If not, is there a different way to make this a non-issue that I'm just not seeing/practiced in yet? 如果没有,是否有不同的方法使这个问题成为我尚未看到/实践的问题呢?

Take a look at Concurrency tutorial . 看一下Concurrency教程 With threads you can wait user input without stopping other processes (and make these other processes execute at the same time - not in parallel, but time-sharing). 使用线程,您可以等待用户输入而不停止其他进程(并使这些其他进程同时执行 - 不是并行执行,而是分时)。

It is called "game loop" which allows the game to run smoothly regardless of the input of the user. 它被称为“游戏循环”,它允许游戏无论用户的输入如何都能平稳地运行。

The most straightforward solution - create 2 threads, frist will wait for user input and puts it into ConcurrentLinkedQueue with capacity 1. The second thread will run your game loop and takes user input from queue to process it if queue is not empty. 最直接的解决方案 - 创建2个线程,frist将等待用户输入并将其放入具有容量1的ConcurrentLinkedQueue 。第二个线程将运行您的游戏循环并从队列中获取用户输入以在队列不为空时处理它。

You can use any data structure you want to exchange data between 2 threads, it can be even volatile string variable. 您可以使用任何想要在2个线程之间交换数据的数据结构,它甚至可以是易变的字符串变量。 The only requirements read write access to this variable should be synchronized somehow. 应该以某种方式同步读取对此变量的写访问权限的唯一要求。

A real-time text adventure? 一个实时文本冒险? Sounds interesting. 听起来不错。 I wouldn't suggest trying to do concurrency for this particular problem, there are easier ways. 我不建议尝试为这个特定问题做并发,有更简单的方法。

Normally you wouldn't mix blocking on input with time in seconds. 通常情况下,您不会在输入中混合阻塞时间,以秒为单位。 Unless you have your heart set on this design, I'd suggest either. 除非你对这个设计有所了解,否则我建议你。

1) Don't block on user input. 1)不要阻止用户输入。 Write your own input handling code by checking for key-presses each frame. 通过检查每一帧的按键来编写自己的输入处理代码。 Then you can just calculate the time difference between iterations. 然后你可以计算迭代之间的时差。 Eg a monster moves 1 block second, so if the current loop iteration took 100ms then it moves 0.1 blocks. 例如,怪物每秒移动1个块,所以如果当前循环迭代花费100毫秒,那么它移动0.1个块。 (store these values as float s internally, even if you draw on a text grid. (将这些值存储在内部float ,即使您在文本网格上绘制。

2) Increment game time in 'ticks' based on user input. 2)根据用户输入增加'ticks'的游戏时间。 This would be NetHack/Roguelike-style. 这将是NetHack / Roguelike风格。 Monsters can move so many blocks per tick, rather than per second. 怪物每蜱可以移动这么多块,而不是每秒。

Yes there is a way. 是的,有办法。 You would need to put the "Round Counting" code in its own Thread, so it in not blocked by the user waiting to input data. 您需要将“Round Counting”代码放在其自己的Thread中,因此它不会被等待输入数据的用户阻止。 The java.util.concurrency package can help with this. java.util.concurrency包可以帮助解决这个问题。

Look at Java Doc the scheduleAtFixedRate() method will execute a runnable at fixed intervals. 查看Java Doc ,scheduleAtFixedRate()方法将以固定的时间间隔执行runnable。 The "round counting" code would be moved to a class that implements the runnable interface. “循环计数”代码将被移动到实现可运行接口的类。 And this would be executed at the set time interval. 这将在设定的时间间隔执行。 This is reasonably advanced though. 虽然这是合理的进步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM