为什么我玩这个 .wav 文件时游戏会滞后?
Why is my game lagging when I play this .wav file?
所以我正在制作游戏,我注意到当我尝试在玩家升级时播放音频时,它会在一瞬间滞后整个游戏。 public void tick()
每秒被调用 60 次。
而且我已经测试过了,唯一落后于我的游戏的是这个 class
中的音频部分
public void tick() {
if (Game.startPressed == true) {
if (HUD.HEALTH != 0) {
if (Game.gamePaused == false) {
playerScoreKeep++;
playerScoreKeepShield++;
if (playerScoreKeepShield >= 3000) {
playerScoreKeepShield = 0;
handler.addObject(new BasicShield(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicShield, handler));
}
if (playerScoreKeep >= 1000) {
try { //This is the part that's causing the game to lag spike really bad
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(this.getClass().getResource("/lvl_up.wav"));
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch(Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
playerScoreKeep = 0;
HUD.playerLevel++;
handler.addObject(new BasicHP(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicHP, handler));
for (int g = 0; g < 2; g++) handler.addObject(new BasicEnemy(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicEnemy, handler));
if (HUD.playerLevel >= 5) {
advRandomDir = r.nextInt(3);
if (advRandomDir == 1) {
handler.addObject(new AdvancedEnemy(10, r.nextInt(Game.HEIGHT), ID.AdvancedEnemy, handler));
}
else if (advRandomDir == 2) {
handler.addObject(new AdvancedEnemy(r.nextInt(Game.WIDTH), 32, ID.Advancedenemy, handler));
} else {
handler.addObject(new AdvancedEnemy(r.nextInt(Game.WIDTH), 32, ID.AdvancedEnemy, handler));
}
handler.addObject(new BasicEnemy(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicEnemy, handler));
if (HUD.playerLevel == 8) {
handler.addObject(new ChaoticEnemy(Game.WIDTH/2, Game.HEIGHT/2, ID.ChaoticEnemy, handler));
} else if (HUD.playerLevel == 9) {
ChaoticEnemy.ChaoticEnemy_Bullet_Speed = 25;
for (int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if (tempObject.getID() == ID.ChaoticEnemy) if (HUD.HEALTH != 0) {
tempObject.velX = 2;
tempObject.velY = 2;
}
}
} else if (HUD.playerLevel == 15) {
ChaoticEnemy.ChaoticEnemy_Bullet_Speed = 20;
for (int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if (tempObject.getID() == ID.ChaoticEnemy) if (HUD.HEALTH != 0) {
tempObject.velX = 3;
tempObject.velY = 3;
}
}
}
}
}
}
}
}
}
这是因为每次访问该部分时都会在线程上读取磁盘。游戏线程需要每秒循环 60 次(每 16 毫秒)以获得流畅的显示,并且从磁盘读取此声音需要超过 16 毫秒。因此,您的游戏很慢。
我认为对于像这样的小音效,最好的方法肯定是将声音预加载到内存中,然后根据需要播放。对于背景音乐等较重的资源,您可能需要采用不同的方法。
或者,如果您必须在每次播放时都从磁盘读取数据,您将希望同时进行(即在另一个线程中),这样您的游戏线程就不会阻塞等待磁盘读取数据。这种方法的缺点是声音可能会比您想要的晚播放一点(但至少游戏不会因等待加载而卡顿)。
一般来说,您要确保您的游戏循环仅在线程上执行非常轻量级的事务。您应该不断寻找提前或离线进行繁重事务的方法。
所以我正在制作游戏,我注意到当我尝试在玩家升级时播放音频时,它会在一瞬间滞后整个游戏。 public void tick()
每秒被调用 60 次。
而且我已经测试过了,唯一落后于我的游戏的是这个 class
中的音频部分public void tick() {
if (Game.startPressed == true) {
if (HUD.HEALTH != 0) {
if (Game.gamePaused == false) {
playerScoreKeep++;
playerScoreKeepShield++;
if (playerScoreKeepShield >= 3000) {
playerScoreKeepShield = 0;
handler.addObject(new BasicShield(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicShield, handler));
}
if (playerScoreKeep >= 1000) {
try { //This is the part that's causing the game to lag spike really bad
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(this.getClass().getResource("/lvl_up.wav"));
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch(Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
playerScoreKeep = 0;
HUD.playerLevel++;
handler.addObject(new BasicHP(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicHP, handler));
for (int g = 0; g < 2; g++) handler.addObject(new BasicEnemy(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicEnemy, handler));
if (HUD.playerLevel >= 5) {
advRandomDir = r.nextInt(3);
if (advRandomDir == 1) {
handler.addObject(new AdvancedEnemy(10, r.nextInt(Game.HEIGHT), ID.AdvancedEnemy, handler));
}
else if (advRandomDir == 2) {
handler.addObject(new AdvancedEnemy(r.nextInt(Game.WIDTH), 32, ID.Advancedenemy, handler));
} else {
handler.addObject(new AdvancedEnemy(r.nextInt(Game.WIDTH), 32, ID.AdvancedEnemy, handler));
}
handler.addObject(new BasicEnemy(r.nextInt(Game.WIDTH - 17), r.nextInt(Game.HEIGHT - 17), ID.BasicEnemy, handler));
if (HUD.playerLevel == 8) {
handler.addObject(new ChaoticEnemy(Game.WIDTH/2, Game.HEIGHT/2, ID.ChaoticEnemy, handler));
} else if (HUD.playerLevel == 9) {
ChaoticEnemy.ChaoticEnemy_Bullet_Speed = 25;
for (int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if (tempObject.getID() == ID.ChaoticEnemy) if (HUD.HEALTH != 0) {
tempObject.velX = 2;
tempObject.velY = 2;
}
}
} else if (HUD.playerLevel == 15) {
ChaoticEnemy.ChaoticEnemy_Bullet_Speed = 20;
for (int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if (tempObject.getID() == ID.ChaoticEnemy) if (HUD.HEALTH != 0) {
tempObject.velX = 3;
tempObject.velY = 3;
}
}
}
}
}
}
}
}
}
这是因为每次访问该部分时都会在线程上读取磁盘。游戏线程需要每秒循环 60 次(每 16 毫秒)以获得流畅的显示,并且从磁盘读取此声音需要超过 16 毫秒。因此,您的游戏很慢。
我认为对于像这样的小音效,最好的方法肯定是将声音预加载到内存中,然后根据需要播放。对于背景音乐等较重的资源,您可能需要采用不同的方法。
或者,如果您必须在每次播放时都从磁盘读取数据,您将希望同时进行(即在另一个线程中),这样您的游戏线程就不会阻塞等待磁盘读取数据。这种方法的缺点是声音可能会比您想要的晚播放一点(但至少游戏不会因等待加载而卡顿)。
一般来说,您要确保您的游戏循环仅在线程上执行非常轻量级的事务。您应该不断寻找提前或离线进行繁重事务的方法。