簡體   English   中英

Java主機游戲的抓拍方法

[英]Snap method for Java console game

我剛剛整理了我的第一個完整的 Java 程序進行練習。 這是一個簡單的快照游戲,但我對實際“快照”條件的方法不滿意。 我可能很挑剔,但我想知道是否有人可以提出更好的建議?

public static boolean snap() {
    Scanner response = new Scanner(System.in);
    double compReflex = (Math.random() * (1000 - 250 + 1)) + 250;
    long reflex = Math.round(compReflex);
    long startTime = System.currentTimeMillis();
    System.out.println("go");
    response.nextLine();

    if (System.currentTimeMillis() > startTime + reflex) {
        System.out.println("I win");
        response.close();
        return false;
    } else {
        System.out.println(System.currentTimeMillis() - startTime);
        System.out.println("Well done");
        response.close();
        return true;
    }
}

問題是如果按下按鈕,我希望else子句立即發生,如果沒有按下按鈕,則if=True子句在reflex延遲后自動發生。 此時必須按下回車,然后計算機判斷誰的反應時間最短。 哪個不是快...

我查看了 KeyListeners,但它們似乎只適用於 JSwing 等 UI? 我還查看了線程中斷,但不知道如何觸發線程中斷,然后使用正確的程序流程處理異常? 還是有可能?

我認為它需要是一個多線程解決方案,但還沒有完全處理並發/多線程,所以除了解決方案之外,任何真正好的學習資源都會受到贊賞。

如果控制台 API 不是那么舊,你可以簡單地做類似的事情

try {
    System.in.readLine(100, TimeUnit.MILLIS);
    System.out.println("You win!");
} catch (InterruptedException e) {
    System.out.println("Too slow!");
}

但不幸的是,從控制台讀取的 API 是在 Java 編程語言的第一個版本中定義的,此后沒有重新設計,因此它不允許超時讀取。 如果一個線程從一個 InputStream 讀取,它不會停止讀取,直到有數據,InputStream 本身發出錯誤信號,或者整個 JVM 退出。

所以如果你真的想這樣做,你需要這樣的東西:

public static void main(String[] args) {
    var readerThread = new Thread(() -> {
        try (var scanner = new Scanner(System.in)) {
            scanner.nextLine();
            gameOver(true);
        }
    });
    readerThread.setDaemon(true); // this thread should not inhibit JVM termination

    readerThread.start();
    System.out.println("Go!");
    sleep(500, TimeUnit.MILLISECONDS);
    gameOver(false);
}

static void sleep(int duration, TimeUnit unit) {
    try {
        Thread.sleep(unit.toMillis(duration));
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}

synchronized static void gameOver(boolean victory) {
    if (!over) {
        System.out.println(victory ? "You win!" : "I win!");
        over = true;
    }
}

static boolean over;

這里有幾點需要注意:

  • 由於兩個線程競相gameOver,我們需要確保它們不會同時執行它。 通過使方法同步,我們確保線程將在彼此之后執行它,並且通過設置 boolean,我們可以檢測其他線程是否更快。
  • 一切都是 static 因為我們無法取消讀取線程。 當然,我們可以讓它繼續運行並在下一個游戲實例中重用它,但它會同時吃掉任何控制台輸入(例如“你想再試一次嗎?”的答案),這很煩人。 所以我不會假裝這個解決方案很好並且可以重復使用,因此可以通過制作 static 來讓我的生活更輕松。
  • try-with-resources 語句是一種在我們完成后關閉資源(例如Scanner )的緊湊方式。
  • sleep的實用方法只是將無意義但必需的catch塊移出main方法,因此main方法更易於閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM