Java俄罗斯方块 - 我如何更改一个丢弃的计时器间隔,然后恢复?

时间:2013-05-17 18:50:32

标签: java timer

我有一个问题是如何在程序的整个生命周期中更改单个计时器的间隔:

全局变量最初在运行时设置的计时器和间隔:

    interval = 800;
    timer();

Board's Timer类:

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:更改计时器的间隔:

public void timer2(int val) {
    interval = val;
}

Board class:每次移动一个棋子时,都会调用Check Full Full。其中,在分数增加后将调用changeLevel(),以查看是否需要根据分数增加等级。

//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()将增加级别,重置分数,清除所有行......您可以看到switch语句将更改基于计时器的全局变量interval等级。

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;      
    }
}

片段类:一旦点击了向上箭头,board.timer2(1);将全局变量interval设置为1 ...这应该加速计时器仅对当前正在下降的片段。 ..如果你看到下面的内容,一旦发生碰撞并且createNewPiece()被调用,将调用timer2(800);来重置间隔......

        //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()将在底部发生碰撞时被调用...这也会调用timer2(800);将全局interval变量重置为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);    
}

问题是,一旦全局变量interval发生变化,似乎没有重置间隔。如何在程序的整个生命周期内更改当前计时器的速度?

由于

1 个答案:

答案 0 :(得分:2)

一般来说,在游戏中使用多个计时器或更改计时器间隔往往会导致各种混乱(至少在单个渲染/事件区域内)。

你应该做的是给游戏一个永不改变的单个“心跳”计时器,然后根据它们的状态改变移动部件的移动量(例如,一个经常掉落的部分将移动2个像素心跳,而一个快速下降的人会移动4)。

不可否认,这会导致抖动,但这只是意味着你应该相应地调整你的心跳和运动速度,直到它看起来像你想要的那样。

编辑:否则,抛弃所有运动内容(这应该发生在计时器的勾号中),并确保你实际上取消并重新创建具有所需新间隔的TimerTask。