带有单独计时器循环的基于文本的游戏?

时间:2015-07-08 12:47:25

标签: java multithreading timer

我大约5个月前在大学开始了Java编码短期课程。我已经学到了很多关于Java编码的东西,但是我仍然缺乏线程,处理异常,甚至是JFrame游戏等其他东西。我决定开始一个基于文本的游戏来学习和弄清楚游戏循环应该如何工作(种类),以及逻辑应该如何工作(仍然,非常"有点")。我编写的游戏使用if-else命令运行,因此您会显示一个屏幕,输入您要选择的选项的命令,然后它会让您碰到下一个菜单,当然非常标准。我在嵌套的if-else循环中运行这些for语句。

我的嵌套for循环如下所示:

    // This is just an example, they're actually a lot more cluttered
    // in my actual source code.

    mainMenu.writeOutput();

    reply = keyboardInput.nextLine();

    for (int i = 0; i <= 10; i--)
    {
        for (int ii = 0; i <= 10; i--)
        {
             if (reply.equalsIgnoreCase("/help")
             {
                 System.out.println("Here I have a separate call to a class
                     file (excuse me, forgot the exact wording), thus it
                     call something like help.writeOutput(); to display
                     the help menu");

                 reply = keyboardInput.nextLine();

                 if (reply.equalsIgnoreCase("/makegameeasy")
                 {
                     // Just an example.
                     gamedifficultyEasy.writeOutput();

                     reply = keyboardInput.nextLine();

                     if (reply.equalsIgnoreCase("/back")
                     {
                         mainMenu.writeOutput();

                         reply = keyboardInput.nextLine();

                         break;
                     }
                 }
                 else if (reply.equalsIgnoreCase("/makegamedifficult")
                 {
                     // Another example.
                     gamedifficultHard.writeOutput();

                     reply = keyboardInput.nextLine();

                     if (reply.equalsIgnoreCase("/back")
                     {
                         mainMenu.writeOutput();

                         reply = keyboardInput.nextLine();

                         break;
                     }
                 }
                 else if (reply.equalsIgnoreCase("/back")
                 {
                     mainMenu.writeOutput();

                     reply = keyboardInput.nextLine();

                     break;
                 }
             }
             else
             {
                 System.out.println("Here I print out an error for incorrect
                     input received, standard fare.");

                 mainMenu.writeOutput();

                 reply = keyboard.nextLine();

                 break;
             }
         }
     }

如上所述,上面只是一个例子,它不是很优雅,我可以使用Exceptions来提供用户提交的任何不正确的信息,但是我不太了解Exceptions以便轻松添加它们,所以我稍后会这样做,但是我目前的主要问题是我的游戏中的一部分,即资源挖掘&#34;必须定期进行。我一直都在谷歌,但仍然无法理解如何为我的游戏设置ThreadTimer,以便自动进行挖掘,玩家可以继续他们的游戏。

游戏基本上就是那些你建立基础,升级你的挖掘工具,并生成更多东西的游戏之一。我已经粘贴了几块代码来自我的&#34;采矿&#34;下面的类文件基本上会运行一件事应该挖掘多少。在游戏中,您当然可以购买升级,因此它将被考虑到您的采矿速度。

    // I initiate my variables a lot earlier, but just for some
    // clarity, I have initiated the variables in the below methods,
    // they will not work correctly anyway, I am aware of that, however
    // I didn't want to add the other "get, set and initiate"
    // variables and methods everywhere, as to not spam this block of code.

    // upgradeOS, upgradeHF, and upgradeLM all have their own respective
    // set and get methods. They are also all int variables.

    public void handleOS()
    {
        // OS = short for Oxygen Silo

        int mineOS = os.getStoredO2() + (1 * upgradeOS);

        os.setStoredO2(mineOS);
    }

    public void handleHF()
    {
        // HF = short for Hydrogen Fuel

        int mineHF = hf.getStoredO2() + (1 * upgradeHF);

        hf.setStoredO2(mineHF);
    }

    public void handleLM()
    {
        // LM = short for Liquid Minerals

        int mineLM = lm.getStoredMinerals() + (1 * upgradeLM);

        lm.setStoredMinerals(mineLM);
    }

    // This is what's going to run the whole time on the set intervals.
    public void mine()
    {
        mineOS = os.getStoredO2() + (1 * upgradeOS);
        mineHF = hf.getStoredO2() + (1 * upgradeHF);
        mineLM = lm.getStoredMinerals() + (1 * upgradeLM);

        os.setStoredO2(mineOS);
        hf.setStoredO2(mineHF);
        lm.setStoredMinerals(mineLM);
    }

    // Using 10 seconds here to have it update as quickly as possible so I can
    // see any changes. This is just here to write an output.
    public void getUpgradeInfo()
    {
        System.out.println("Oxygen: " + (1 * upgradeOS) + " / per 10 seconds.");
        System.out.println("Hydrogen: " + (1 * upgradeHF) + " / per 10 seconds.");
        System.out.println("Liquid Mineral: " + (1 * upgradeLM) + " / per 10 seconds.");
    }

我不是我材料的最佳命名方案......

TL; DR:我无法弄清楚如何仅针对上述thread方法实施timermine(),因为我没有适当的数量知识。我的if-else规则并不太优雅,但我当然会处理这些规则。基本上if-else规则应该与mine()方法分开运行,你可以在没有游戏更新System.out输出的情况下进行一些AFKing,因此你可以漂浮,例如,氧气筒仓升级菜单,由于线程&#34;醒来&#34;,例如被退回到主菜单,你不会被弹回到不同的菜单,但mine()方法将仍然在后台生成资源。

任何有关这方面的帮助,或者只是在正确方向上的推动都将非常感激。

2 个答案:

答案 0 :(得分:2)

要回答您提出的问题,您可以执行以下操作:

import java.util.*;

TimerTask tt = new TimerTask() {
  public void run() {
    mine();
  }
}

Timer t = new Timer();
t.scheduleAtFixedRate(tt, 0, 1000);

或者,您可以以类似的方式使用ActionListenerswing timer。如果你在顶部构建一个swing gui,那么它具有线程安全的优点

最后,您应该查看synchronizedvolatile的使用情况,以确保mine()中更新的变量以线程安全的方式完成

答案 1 :(得分:0)

感谢@ControlAltDel,正确推动了正确的方向。我已经采取了一些代码并将其设置为:

import java.util.*;

// extends TimerTask needed
public class TimerTestOne extends TimerTask
{
    // Needed
    @Override
    public void run()
    {
        TimerTestTwo ttt = new TimerTestTwo();

        mine();
    }

    // Needed, method doesn't need the same name though.
    private void completeTask()
    {
        try
        {
            //assuming it takes 10 secs to complete the task
            Thread.sleep(10000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String[] args)
    {
        // You will need to define the following line of code:
        TimerTask tt = new TimerTestOne();

        Scanner keyboard = new Scanner(System.in);

        String reply;

        // Following 2 lines of code, yup, need them.
        Timer timer = new Timer(true);
        timer.scheduleAtFixedRate(tt, 0, 10*1000);

        previousMenu();

        for (int i = 0; i <= 10000; i++)
        {
            for (int ii = 0; ii <= 10000; i++)
            {
                System.out.println("Go to another menu?");

                reply = keyboard.nextLine();

                if (reply.equalsIgnoreCase("/yes"))
                {
                    yes();

                    reply = keyboard.nextLine();
                }
            }
        }
    }

    // I added the following methods, just so I didn't have to work
    // off 2 class files.
    public void mine()
    {
        System.out.println("Mined");
    }

    public static void yes()
    {
        System.out.println("Next menu");
    }

    public static void previousMenu()
    {
        System.out.println("Previous menu");
    }
}

所以,如果有人需要设置一个不会破坏基于文本的游戏的计时器。