Reputation: 12718
I have a question on how I can change the interval of a single timer throughout the life of a program:
global variables Timer and interval initially set at runtime:
interval = 800;
timer();
Board's Timer class:
public void timer() {
int delay = 1000;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (pause && gameWon){
message = "You've won!";
}
else if (pause) {
seconds++;
}
else {
seconds = 0;
newPiece.autoMove();
}
}
}, delay, interval);
}
Board class: Change interval for the timer:
public void timer2(int val) {
interval = val;
}
Board class: Check Bottom Full will be called each time a piece is moved. And in that, changeLevel()
will be called after the score is incremented to see if the level needs to be incremented based on score.
//loop through all rows starting at bottom (12 rows)
public void checkBottomFull() {
int lines = 0;
for(int row = totalRows-1; row > 0; row--) {
while (isFull(row)) {
lines++;
clearRow(row);
}
}
totalScore += tallyScore(lines);
//check if level needs to be changed based on current score...
changeLevel();
//reset lines after score has been incremented
lines=0;
}
Board class: ChangeLevel()
will increment level, reset score, the clear all rows... You can see that the switch
statement will change the global variable interval
for the timer based on level.
public void changeLevel () {
int max = (level+1)*changeLevelMultiplier;
if (totalScore >= max) {
level++;
totalScore = 0;
for(int row = 0; row < grid.length; row++) {
for(int col = 0; col < grid[row].length; col++) {
grid[row][col] = null;
}
}
//timer(0);
}
if (level == finalLevel) {
pause = true;
gameWon = true;
System.out.println("YOU HAVE WON");
}
switch (level) {
//each level increases drop speed by .10 seconds
case 1: interval = 700;
break;
case 2: interval = 600;
break;
case 3: interval = 500;
break;
case 4: interval = 400;
break;
case 5: interval = 300;
break;
default: interval = 800;
break;
}
}
Piece class: once UP arrow has been hit, board.timer2(1);
will set the global variable interval
to 1
... which should speed up the timer Only for that currently falling piece... if you see below, once there is a collision and createNewPiece()
is called, timer2(800);
will be called to reset the interval...
//hard drop
if (keycode == KeyEvent.VK_UP) {
board.timer2(1);
for (int i = 0; i < tile.length; i++) {
calcNewPosition(tile[i].getRow()+1, tile[i].getCol(), i);
}
clearCurrPosition();
for (int i = 0; i < tile.length; i++) {
board.checkEndGame(tile[i].getRow(), tile[i].getCol());
}
board.checkBottomFull();
if (isCollision()) board.createNewPiece();
move();
}
Board class: createNewPiece()
will be called once there is a collision on the bottom... this will also call timer2(800);
to reset the global interval
variable to 800
.
public void createNewPiece() {
//current playable piece becomes what the nextPiece was
currPiece = nextPiece;
newPiece = new Piece(this, nextPiece, getColor(), false);
//generate next piece
nextPiece = randomPiece();
timer2(800);
}
The problem is, the interval doesn't seem to be resetting once the global variable interval
is changed. How can I change the speed of the current timer throughout the life of the program?
Thanks
Upvotes: 2
Views: 1671
Reputation: 162
Generally speaking, using multiple timers or changing timer intervals in a game tends to lead to all sorts of chaos (at least within a single rendering/event area).
What you should be doing is giving the game a single "heartbeat" timer that never changes, and then changing the amount of movement of the moving pieces based on their status (for instance, a regularly falling piece would move 2 pixels per heartbeat, whereas a swiftly falling one would move 4).
Admittedly this can lead to jittery movement, but that just means that you should adjust your heartbeat and movement rates accordingly until it looks the way you want it to.
EDIT: Otherwise, ditch all the movement stuff out of the keyup (that should happen in the timer's tick) and make sure you're actually cancelling and re-creating the TimerTask with the desired new interval.
Upvotes: 2