如何在两个动作之间延迟棋盘游戏以便播放声音

时间:2013-04-30 22:11:52

标签: java delay

在我正在设计的棋盘游戏中,每个用户都有一个包含100个单元格的网格。用户单击计算机网格中的单元格,该单元格发出声音并更改为不同的颜色。然后,计算机会自动单击用户网格中的单元格,该单元格会发出声音并更改为不同的颜色。

用户的点击通过MouseListener(和MouseClicked方法)处理。目前,该方法所做的最后一件事是调用computerMove()方法。该方法在将当前播放器更改回人之前执行并执行计算机移动。当人类再次点击鼠标时,游戏就会继续进行。

理想情况下,我想在每个玩家之间进行暂停(可能是一秒钟)。但是,由于在MouseClicked方法中调用了computerMove方法,因此这很麻烦。通过使用Thread.sleep甚至是TimerTask,我能做的最好的事情就是减慢人类玩家的向下移动速度。但是,只要玩家点击鼠标,计算机就会立即响应。

有人对我如何实施延迟有任何建议吗?我是否需要更改调用方法的方式?

ComputerMove方法:

    public void computerMove() {
    if (currentTurn == computer) {
        int xPos = randomGenerator.nextInt(10);
        int yPos = randomGenerator.nextInt(10);
        LogicCell attackedCell = new LogicCell(xPos, yPos);
        playerGridLogic.addCellsThatHaveBeenAttacked(attackedCell);

        if (playerGridLogic.getCellsWithShips().contains(attackedCell)) {
            playerGrid.getCellArray()[xPos][yPos].setBackground(Color.ORANGE);
            hitSound();
        }
        else {
            playerGrid.getCellArray()[xPos][yPos].setBackground(Color.MAGENTA);
            missSound();
        }
        nextTurn();
    }
}

对应的MouseClick方法:

        @Override
    public void mouseClicked(MouseEvent e) {
        if (allComputerShipsPlaced && currentTurn == human) {
            ViewCell currentCell = (ViewCell) e.getSource();
            xPos = currentCell.getXPos();
            yPos = currentCell.getYPos();
            LogicCell attackedCell = new LogicCell(xPos, yPos);
            computerGridLogic.addCellsThatHaveBeenAttacked(attackedCell);

            if (computerGridLogic.getCellsWithShips().contains(attackedCell)) {
                cellArray[xPos][yPos].setBackground(Color.ORANGE);
                hitSound();
            }
            else {
                cellArray[xPos][yPos].setBackground(Color.MAGENTA);
                missSound();
            }
            nextTurn();
            computerMove();
        }
    }

missSound方法()(hitSound非常相似):

    public static void missSound() {
    try {
        Clip clip = AudioSystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(new File("water-splash.wav")));
        clip.start();
    }
    catch (Exception exc)
    {
        exc.printStackTrace(System.out);
    }
}

编辑:我已经尝试将声音类更改为此,但无济于事:

    public static void hitSound()
{
    try
    {
        Clip clip = AudioSystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(new File("bomb-explosion.wav")));
        clip.start();

        LineListener listener = new LineListener() {
            public void update(LineEvent event) {
                if (event.getType() != Type.STOP) {
                    return;
                }
                try {
                    queue.take();
                } catch (InterruptedException e) {
                    //ignore this
                }
            }
        };
        clip.addLineListener(listener);
    }
    catch (Exception exc)
    {
        exc.printStackTrace(System.out);
    }
}

3 个答案:

答案 0 :(得分:1)

您应该能够添加一个侦听器并对声音的结尾作出反应。 请参阅此问题:how can I wait for a java sound clip to finish playing back?

这对我有用:

public class Test {
    public static void main(String[] args) {
        final Object foo = new Object();
        Clip clip;
        try {
            clip = AudioSystem.getClip();
            clip.open(AudioSystem.getAudioInputStream(new File("go.wav")));
            clip.addLineListener(new LineListener() {
                public void update(LineEvent event) {
                    if(event.getType() == LineEvent.Type.STOP){
                        System.out.println("done playing");
                        synchronized(foo) {
                            foo.notify();
                        }

                    }
                }
            });
            clip.start();
        } catch (Exception e) {
            e.printStackTrace();
        }

        synchronized(foo) {
            try {
                foo.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

答案 1 :(得分:0)

我会考虑在computerMove内拨打nextTurn,并在nextTurn内进行等待。

答案 2 :(得分:0)

您可以使用computerMove()中的Thread.sleep暂停执行。您可以使用clip.getMicrosecondsLength以微秒为单位获取声音效果的长度。将它与1000相乘并将其传递给睡眠以等待声音效果完成。

Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File("water-splash.wav")));
clip.start();
int lengthInMilliseconds = clip.getMicrosecondLength() * 1000;
Thread.sleep(lengthInMilliseconds);