我正在用Java制作rummikub游戏,我想实现一个运行2分钟的计时器。在2分钟内,用户必须输入有关他们是否要播放,跳过还是要转弯(如果已经播放了图块)的输入。如果他们选择游戏,则需要选择是要播放单个图块,进行融合还是退出序列(所有这些输入都必须在2分钟内完成)。如果他们在2分钟内仍未完成转牌,则该转牌必须结束且不需输入任何信息,下一位玩家将进行转牌。我将在下面发布一些代码。我应该如何实施此计时器?我在Human类和GameTimer类中有2种播放方法,在Game类中有playTurn()方法。此刻我正在测试10秒
package com.COMP3004.Rummikub.models;
import java.util.Timer;
import java.util.TimerTask;
public class GameTimer {
private int seconds;
private boolean started;
private boolean stopped;
private Timer timer;
private TimerTask task = new TimerTask() {
public void run() {
seconds++;
System.out.print(seconds + ", ");
if(seconds % 30 == 0) {
System.out.println();
}
if(seconds == 10) {
stop();
}
}
};
public GameTimer() {
started = false;
stopped = true;
seconds = 0;
timer = new Timer();
}
public void start() {
started = true;
stopped = false;
//timer.schedule(task, 0, 1000);
new Timer(true).schedule(task, 0, 1000);
//System.out.println("Timer Started");
/*if(seconds == 10) {
stop();
}*/
}
public boolean isStarted() { return started; }
public void stop() {
task.cancel();
seconds = 0;
//System.out.println("Timer Stopped");
stopped = true;
}
public boolean isStopped() { return stopped; }
public int getSeconds() { return seconds; }
public boolean stopsAtRightTime() {
start();
/*System.out.println(seconds);
int secondsPassed = 0;
do {
secondsPassed = seconds;
System.out.println(seconds);
}
while(seconds <= 10);
System.out.println(secondsPassed);
this.stop();
if(secondsPassed == 10) {
return true;
}*/
int secondsPassed = 0;
try {
Thread.sleep(60000);
secondsPassed = seconds;
System.out.println(seconds);
}
catch(InterruptedException e) {
}
if(secondsPassed == 60 || secondsPassed == 0) {
//stop();
return true;
}
return false;
}
}
public boolean makeAPlay(Scanner reader) {
returned = false;
while(true) {
System.out.println("Choose one of the following commands:");
System.out.println(" - 'M' to play a meld.");
System.out.println(" - 'T' to play an individual tile.");
System.out.println(" - 'B' to move an existing tile on the board.");
System.out.println(" - 'L' to exit this sequence.");
decision2 = 'K';
TimerTask timerTask = new TimerTask() {
public void run() {
if(decision2 == 'K') {
decision2 = 'L';
return;
}
}
};
try {
Timer timer = new Timer();
timer.schedule(timerTask, 10000 - getTimer().getSeconds()*1000);
decision2 = (decision2 == 'L')? 'L': reader.next().toUpperCase().charAt(0);
timer.cancel();
}
catch(Exception e) {
}
if (decision2 == 'M') {
String tileChoice = "";
Meld meld = new Meld();
this.getHand().createMeld();
while (!tileChoice.equals("D")) {
if (this.getHand().size == 0) { break; }
System.out.println("Current Meld: " + meld.meldToString());
System.out.println("Hand: " + this.getHand().handToString());
System.out.println("Select a tile you'd like to add to your meld, type 'D' to exit.");
tileChoice = reader.next().toUpperCase();
if (tileChoice.equals("D")) { break; }
for (int i = 0; i < this.getHand().size; i++) {
if (this.getHand().getTile(i).tileToString().equals(tileChoice)) {
meld.addTile(this.getHand().getTile(i));
this.getHand().removeFromHand(i);
break;
} else if (i == (this.getHand().size - 1) && !(tileChoice.equals("D"))) {
System.out.println("It seems that the tile " + tileChoice + " isn't in your posession. Please try again.");
}
}
}
if (tileChoice.equals("D")) {
if (meld.getMeldSize() >= 3 && meld.checkIfValidMeld() == true) {
for (int i = 0; i < meld.getMeldSize(); i++) {
System.out.println(meld.getTileInMeld(i).tileToString());
}
this.playMeld(meld, reader);
turnValue = turnValue + meld.getMeldValue();
} else {
System.out.println("Invalid meld. Please try again.");
for (int i = 0; i < meld.getMeldSize(); i++) {
this.getHand().addTile(meld.getTileInMeld(i));
}
this.getHand().sortHand();
tileChoice = "";
}
}
}
if (decision == 'T') {
if (initialMeldPlayed == true) {
String tileChoice = "";
System.out.println("Hand: " + this.getHand().handToString());
System.out.println("Which tile would you like to add to the board?");
tileChoice = reader.next().toUpperCase();
Tile tempTile = this.getHand().getTile(tileChoice);
if (this.getHand().getPlayerHand().contains(tempTile)) {
System.out.println("Where would you like to put " + tempTile.tileToString() + " ?");
System.out.println("X-Coordinate: ");
int xTile = reader.nextInt();
System.out.println("Y-Coordinate: ");
int yTile = reader.nextInt();
for (int i = 0; i < this.getHand().size; i++) {
if (this.getHand().getTile(i).tileToString().equals(tileChoice)) {
this.addTile(this.getHand().getTile(i), xTile, yTile);
}
}
System.out.println("Board:");
board.boardToString();
} else {
System.out.println("It seems that you don't have " + tileChoice + " isn't in your hand. Please try again.");
}
} else {
System.out.println("You cannot play individual tiles on the board during your initial meld.");
}
}
if (decision == 'B') {
if (initialMeldPlayed == true) {
while(true) {
board.boardToString();
System.out.println("Which tile would you like to move on the board?");
System.out.println("Current X-Coordinate ('-1' to exit): ");
int xTile = reader.nextInt(); if (xTile == -1) { break; }
System.out.println("Current Y-Coordinate ('-1' to exit): ");
int yTile = reader.nextInt(); if (yTile == -1) { break; }
Spot oldSpot = board.getSpot(xTile, yTile);
Tile tile = oldSpot.getTile();
System.out.println("Where would you like to move tile " + tile.tileToString() + " to?");
System.out.println("New X-Coordinate: ");
int xTileNew = reader.nextInt();
System.out.println("New Y-Coordinate: ");
int yTileNew = reader.nextInt();
Spot newSpot = board.getSpot(xTileNew, yTileNew);
this.moveTile(tile, newSpot);
}
} else {
System.out.println("You cannot manipulate the board during your initial meld.");
}
}
if (decision == 'L') {
if (board.checkIfValidMelds() == false) {
System.out.println("That wasn't a valid move. Please try again.");
this.setTilesBeenPlayed(false);
this.undoTurn();
return false;
} else {
return false;
}
}
return returned;
}
//return false;
}
public GameTimer getTimer() { return timer; }
public void play(Scanner reader, Deck deck) /*throws InterruptedException*/ {
turnValue = 0;
timer = new GameTimer();
long startTime = System.currentTimeMillis();
while( /*(System.currentTimeMillis()-startTime)<10000 ||*/ myTurn == true /*||timer.getSeconds()!=10*/) {
//reader = new Scanner(System.in);
System.out.println("Choose one of the following commands:");
System.out.println(" - 'P' to play your turn.");
System.out.println(" - 'S' to skip your turn & draw a tile.");
System.out.println(" - 'E' to end your turn if you've already played atleast one tile.");
if(timer.getSeconds() == 0) {
timer.start();
}
//while(timer.getSeconds() != 10) {
System.out.print(timer.isStopped());
/*else if(timer.getSeconds() == 10) {
//this.setHasInitialMeldBeenPlayed(false);
this.setTilesBeenPlayed(false);
this.undoTurn();
Tile t = this.getHand().dealTile(deck);
System.out.println("Out of time");
System.out.println("Turn ended: Player drew " + t.tileToString() + ".");
System.out.println("----------------------------------------");
this.setTurnStatus(false);
timer.stop();
}*/
decision = 'N'; //'N' for no input
TimerTask task = new TimerTask() {
public void run() {
if(decision == 'N') {
Tile t = getHand().dealTile(deck);
System.out.println("Timeout");
System.out.println("Turn ended: Player drew " + t.tileToString() + ".");
System.out.println("----------------------------------------");
setTilesBeenPlayed(false);
undoTurn();
setTurnStatus(false);
//return;
}
if(timer.getSeconds() == 10) {
}
}
};
try {
Timer timer = new Timer();
timer.schedule(task, 10000);
decision = reader.next().toUpperCase().charAt(0);
timer.cancel();
}
catch (Exception e) {
}
if (decision == 'P') {
makeAPlay(reader);
} else if (decision == 'S') {
if (hasTileBeenPlaced == false) {
Tile t = this.getHand().dealTile(deck);
System.out.println("Turn ended: Player drew " + t.tileToString() + ".");
System.out.println("----------------------------------------");
this.setTurnStatus(false);
timer.stop();
} else {
System.out.println("You've already made a play. Try typing 'E' to end your turn.");
}
} else if (decision == 'E') {
if (initialMeldPlayed == false) {
if (turnValue >= 1) {
System.out.println("Initial Meld Completed.");
System.out.println("----------------------------------------");
this.setHasInitialMeldBeenPlayed(true);
this.setTilesBeenPlayed(true);
this.setTurnStatus(false);
timer.stop();
} else {
System.out.println("Your Initial Meld total must be greater than or equal to 30 points.");
System.out.println("You played: " + turnValue + ". Please try again.");
this.setHasInitialMeldBeenPlayed(false);
this.setTilesBeenPlayed(false);
this.undoTurn();
turnValue = 0;
}
} else if (initialMeldPlayed == true) {
if (hasTileBeenPlaced == true) {
this.setTurnStatus(false);
timer.stop();
} else {
this.undoTurn();
System.out.println("You must either play your turn or draw a tile.");
}
}
}
else {
System.out.println("You may have entered the wrong character. Please try again.");
}
//}
}
}
public void playTurn(int i) {
printAll();
// Play if human
if (allPlayers.get(i).isAI() == false && allPlayers.get(i).myTurnStatus() == true) {
System.out.println("Player " + (i+1) + "'s Hand[" + allPlayers.get(i).getHand().size + "]: " + allPlayers.get(i).getHand().handToString());
int oneMoreTile = allPlayers.get(i).getHand().getNumTiles() + 1;
TimerTask timerTask = new TimerTask() {
public void run() {
if(allPlayers.get(i).getHand().getNumTiles() == oneMoreTile) {
}
else if(allPlayers.get(i).getHand().getNumTiles() == oneMoreTile - 1) {
Tile t = allPlayers.get(i).getHand().dealTile(deck);
System.out.println("ended: Player drew " + t.tileToString() + ".");
System.out.println("----------------------------------------");
allPlayers.get(i).setTurnStatus(false);
}
}
};
try {
Timer timer = new Timer();
timer.schedule(timerTask, 10000);
allPlayers.get(i).play(reader, deck);
timer.cancel();
if(allPlayers.get(i).myTurnStatus() == false) {
nextPlayersTurn(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Play if AI
if (allPlayers.get(i).isAI() == true && allPlayers.get(i).myTurnStatus() == true) {
allPlayers.get(i).play(reader);
if (allPlayers.get(i).hasTilesBeenPlayed() == false) {
Tile t = allPlayers.get(i).getHand().dealTile(deck);
System.out.println("Turn ended: Player " + (i+1) + " has decided to draw a tile.");
System.out.println("Tile drawn: " + t.tileToString());
nextPlayersTurn(i);
}
}
// Sets next players turn
nextPlayersTurn(i);
}
答案 0 :(得分:0)
这是非常快速的编写代码,但我希望它可以使您对事件管理有更好的看法。
private GameTimer _task; // the object.
// .....................
// Put these 2 lines wherever you call the event to start.
_task.setStartTime(System.currentTimeMillis() + (60000L * eventTime)); // eventTime == 2 minutes
ThreadPoolManager.getInstance().executeGeneral(_task);
// .....................
class GameTimer implements Runnable
{
private long _startTime;
public ScheduledFuture<?> nextRun;
public GameTimer(long startTime)
{
_startTime = startTime;
}
public void setStartTime(long startTime)
{
_startTime = startTime;
}
@Override
public void run()
{
int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
if (delay == 0)
{
// start
if (isStarted())
{
stop();
// You can place a scheduler here to trigger an auto-start.
}
else
{
start();
nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, endEvent);
// endEvent is the time you want the run() method to run again.
// In this case, when the event is finished.
// This line is triggering the jvm to auto run this method again in the given time.
// So if the event is already started, the run() method will run again and it will close it again.
}
}
}
}
仅提及代码只是如何更好地重写事件计时器的示例。
希望有帮助!