在我设计的棋盘游戏中,每个用户都有一个包含100个单元格的网格。用户点击电脑网格中的一个单元格,就会发出声音并变成不同的颜色。然后,电脑会自动点击用户网格中的一个单元格,发出声音并变成不同的颜色。
通过MouseListener(和mouseclick方法)处理用户的单击。目前,该方法做的最后一件事是调用computerMove()方法。这个方法执行和执行计算机移动之前,改变当前的玩家回到人类。当玩家再次点击鼠标时,游戏继续进行。
理想情况下,我希望在每个玩家移动之间有一个暂停(也许是一秒钟)。然而,由于computerMove方法是在mouseclick方法内部调用的,这证明是很麻烦的。通过使用Thread。睡眠甚至是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();
}
}
对应的鼠标点击方法:
@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);
}
}
您应该能够添加一个侦听器并在声音结束时做出反应。看看这个问题:我如何等待java声音剪辑完成播放?
这个对我有效:
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();
}
}
}
}
我会考虑在nextTurn
内部调用computerMove
,在nextTurn
内部进行等待。
您可以使用Thread。在computerMove()
中休眠以暂停执行。你可以用夹子。以微秒为单位获取声音效果的长度。将其与1000相乘,并将其传递给sleep以等待声音效果完成。
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File("water-splash.wav")));
clip.start();
int lengthInMilliseconds = clip.getMicrosecondLength() * 1000;
Thread.sleep(lengthInMilliseconds);