我在我开发的游戏中使用Java的Clip类时遇到了麻烦。具体来说,我认为问题在于同时多次使用相同的剪辑。我做了一些谷歌搜索,有些人建议在自己的线程中运行剪辑。我想复制剪辑对象,以便在每个线程中使用不同的剪辑对象,以避免需要“重置”剪辑,但我仍然遇到问题。事实上,问题是当同一个剪辑同时播放几次时,游戏似乎会冻结。
有人在Reddit上建议问题可能是因为Clip类不是同步的,而且每次我想要使用它时我都必须打开剪辑。显然,这是行不通的,因为声音经常使用。
如果某人可能能够指出该课程的致命缺陷,请输入以下代码:
/**
This file is part of Generic Zombie Shooter.
Generic Zombie Shooter is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Generic Zombie Shooter is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Generic Zombie Shooter. If not, see <http://www.gnu.org/licenses/>.
**/
package genericzombieshooter.misc;
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
/**
* Contains all pre-loaded sounds.
* @author Darin Beaudreau
*/
public enum Sounds {
// Weapon-Related
POPGUN("shoot2.wav", false),
RTPS("shoot1.wav", false),
BOOMSTICK("shotgun1.wav", false),
FLAMETHROWER("flamethrower.wav", true),
THROW("throw2.wav", false),
EXPLOSION("explosion2.wav", false),
LANDMINE_ARMED("landmine_armed.wav", false),
TELEPORT("teleport.wav", false),
// Zombie-Related
MOAN1("zombie_moan_01.wav", false),
MOAN2("zombie_moan_02.wav", false),
MOAN3("zombie_moan_03.wav", false),
MOAN4("zombie_moan_04.wav", false),
MOAN5("zombie_moan_05.wav", false),
MOAN6("zombie_moan_06.wav", false),
MOAN7("zombie_moan_07.wav", false),
MOAN8("zombie_moan_08.wav", false),
POISONCLOUD("poison_cloud.wav", false),
// Game Sounds
POWERUP("powerup.wav", false),
PURCHASEWEAPON("purchase_weapon.wav", false),
BUYAMMO("buy_ammo2.wav", false),
PAUSE("pause.wav", false),
UNPAUSE("unpause.wav", false);
private Clip clip;
private boolean looped;
Sounds(String filename, boolean loop) {
openClip(filename, loop);
}
private synchronized void openClip(String filename, boolean loop) {
try {
URL audioFile = Sounds.class.getResource("/resources/sounds/" + filename);
AudioInputStream audio = AudioSystem.getAudioInputStream(audioFile);
AudioFormat format = audio.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
clip = (Clip) AudioSystem.getLine(info);
clip.open(audio);
} catch (UnsupportedAudioFileException uae) {
System.out.println(uae);
} catch (IOException ioe) {
System.out.println(ioe);
} catch (LineUnavailableException lue) {
System.out.println(lue);
}
looped = loop;
}
public synchronized void play() {
play(1.0);
}
public synchronized void play(final double gain) {
Runnable soundPlay = new Runnable() {
@Override
public void run() {
Clip clipCopy = (Clip)clip;
FloatControl gainControl = (FloatControl)clipCopy.getControl(FloatControl.Type.MASTER_GAIN);
float dB = (float)(Math.log(gain) / Math.log(10.0) * 20.0);
gainControl.setValue(dB);
if(!looped) reset(clipCopy);
clipCopy.loop((looped)?Clip.LOOP_CONTINUOUSLY:0);
}
};
new Thread(soundPlay).start();
}
public synchronized void reset() {
reset(clip);
}
public synchronized void reset(Clip clipCopy) {
synchronized(clipCopy) { clipCopy.stop(); }
clipCopy.setFramePosition(0);
}
public static void init() {
values();
}
}
我正在尝试做什么,使用枚举和静态play()方法,可能是我想要完成的事情?或者我必须找到另一种方式?我可以使用不同的类,甚至是必要的库,但我宁愿留在核心Java中。
有人可以想办法做我想做的事吗?
答案 0 :(得分:1)
剪辑不支持并发。您可以随时重新启动剪辑,并多次播放。但是在任何给定的时间,一次只能有一个给定Clip的实例播放。
TinySound是一个很好的库,但我不记得他的剪辑是否允许并发游戏。你可以在全部进入之前检查一下。在Java-gaming.org上有一个关于这个库的实质主题。
我不了解Net Beans,但是要在Eclipse中使用Git Hub源,我按照Git Hub提供的有关如何设置帐户和制作克隆的说明,然后将克隆下载到我的桌面上(使用Bash)。说明并不容易,但这是产品(GitHub)的一个非常基本的用途,你应该能够找到支持。
一旦项目在桌面上,我在Eclipse中创建一个新项目,并提供桌面克隆的根目录作为位置。 Eclipse具有用于将外部库链接到项目的其他设置。如果Net Beans没有类似的东西,我会感到非常惊讶。
Eclipse还可以创建项目或从zip文件链接库。 Zips与Jar文件的格式完全相同。 Net Beans应该有一种链接到项目的zip或jar的方法。在Eclipse中,他们对存储在zip中的项目使用术语“archived”。但是我不知道你拥有的zip是否只是作为外部项目加载所需的一切。我对GitHub的体验很小。
如果您想重复使用枪支或其他任何东西,您可能需要为每个要支持的并发副本制作一个剪辑。
我最终编写了自己的剪辑对象并为其提供了多个游标,以及一个混合来自并发游标的数据的界面。它运作得很好!我愿意寄给你一份试用版。它设置为使用连续运行的音频混音器(我认为与TinySound相同)。但是如果我发给你代码,你可能可以将Clip部分重写为独立。 “PFClip”还允许以不同的速度进行平移,音量设置和播放,因此您可以改变枪声的速度。这样做,它听起来像不同的枪(或爆炸,如果你让他们真的很慢)。[在这里获得最大的爆炸插入双关语。]
该库有一些很酷的附加功能:用于循环剪辑的PFLoop(允许一个以平滑的方式重叠两端),我只是制作了镶边,立体声合唱和音高变量回声。与TinySound不同,我不支持44100fps和16位的立体声wav格式。我为我正在制作的游戏写了这个,可以通过浏览器播放:http://hexara.com/game.html windchime效果是使用并发剪辑的东西。
忘记!我从前面开始有另一个混音器的演示,它以各种方式使用单枪声,同时: enter link description here JGO中列出的代码是陈旧的,但是线程中有一个页面,其基本思想可用于制作您自己的并发剪辑。
联系信息在第二个链接网站上提供。