I want to have a ****seperate Class**** to have the sounds and i want to call upon that class to play the sounds, but if there is a better way, pls tell me.
Story (can be skipped):
First i used AudioClips that were stored in final statics that i called everytime i needed the sound to play. For single stuff like the background music, this was perfect, but if i wanted to use the sound more than once at a time, like my turrets that shoot, they sometimes play the sound perfectly and sometimes it gets restarted or it is canceled completely. Then i switched to Clips after reading trhough some posts and that some guy found a solution by doin Clips, after using a tutorial.
Sound Class:
package Game.main;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Mixer;
public class Sound {
public static final Sound backgroundMusic4 = new Sound("/backgroundMusic4.wav");
public static final Sound blockDestroy = new Sound("/blockDestroy.wav");
public static final Sound bulletHit = new Sound("/bulletHit.wav");
public static final Sound button = new Sound("/button.wav");
public static final Sound camera = new Sound("/camera.wav");
public static final Sound teleporter = new Sound("/teleporter.wav");
public static final Sound turretShot = new Sound("/turretShot.wav");
public static final Sound walking = new Sound("/walking.wav");
public static Clip clip;
public Sound(String fileLocation){
Mixer.Info[] mixInfos = AudioSystem.getMixerInfo();
Mixer mixer = AudioSystem.getMixer(mixInfos[0]);
DataLine.Info dataInfo = new DataLine.Info(Clip.class, null);
try{
clip =(Clip) mixer.getLine(dataInfo);
}catch(Exception e){
e.printStackTrace();
}
try{
URL soundURL = getClass().getResource(fileLocation);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(soundURL);
clip.open(audioStream);
}catch(Exception e){
e.printStackTrace();
}
}
public void play(){
clip.loop(clip.LOOP_CONTINUOUSLY);
}
public void playOnce(){
clip.start();
}
public void stop(){
clip.stop();
}
}
Turret Class (As example) [Only the last method "shoot()" matters]:
package Game.main.IngameObjects;
import java.applet.AudioClip;
import java.awt.Graphics;
import java.awt.Rectangle;
import Game.main.Controller;
import Game.main.Game;
import Game.main.GameObject;
import Game.main.Sound;
import Game.main.Textures;
import Game.main.classes.EntityC;
public class Turret extends GameObject implements EntityC{
private boolean activated;
private String direction;
private Game game;
private Textures tex;
private Camera activationCam;
private Controller c;
private long lastShot=0;
public Turret (double x, double y, Textures tex, Game game, Controller c, String direction){
super(x,y);
this.game=game;
this.tex=tex;
this.c=c;
if(!direction.equalsIgnoreCase("up") && !direction.equalsIgnoreCase("down") && !direction.equalsIgnoreCase("left") && !direction.equalsIgnoreCase("right")){
System.err.println("ERROR 1: Wrong Direction in Constructor in Class \"java.Game.main.IngameObjects.Camera\"");
System.exit(1);
}else{
this.direction=direction;
}
}
public Turret (double x, double y, Textures tex, Game game, Controller c , Camera cam, String direction){
super(x,y);
this.game=game;
this.tex=tex;
this.c=c;
if(!direction.equalsIgnoreCase("up") && !direction.equalsIgnoreCase("down") && !direction.equalsIgnoreCase("left") && !direction.equalsIgnoreCase("right")){
System.err.println("ERROR 1: Wrong Direction in Constructor in Class \"java.Game.main.IngameObjects.Camera\"");
System.exit(1);
}else{
this.direction=direction;
}
this.activationCam=cam;
}
public void tick() {
if(activationCam==null){
shoot();
}else if(activationCam.getActivated()){
shoot();
}
}
public void render(Graphics g) {
if(activated){
if(direction.equalsIgnoreCase("up")){
g.drawImage(tex.turretActi.get(0), (int)x, (int)y, null);
}else if(direction.equalsIgnoreCase("down")){
g.drawImage(tex.turretActi.get(1), (int)x, (int)y, null);
}else if(direction.equalsIgnoreCase("left")){
g.drawImage(tex.turretActi.get(2), (int)x, (int)y, null);
}else if(direction.equalsIgnoreCase("right")){
g.drawImage(tex.turretActi.get(3), (int)x, (int)y, null);
}
}else{
if(direction.equalsIgnoreCase("up")){
g.drawImage(tex.turretDeac.get(0), (int)x, (int)y, null);
}else if(direction.equalsIgnoreCase("down")){
g.drawImage(tex.turretDeac.get(1), (int)x, (int)y, null);
}else if(direction.equalsIgnoreCase("left")){
g.drawImage(tex.turretDeac.get(2), (int)x, (int)y, null);
}else if(direction.equalsIgnoreCase("right")){
g.drawImage(tex.turretDeac.get(3), (int)x, (int)y, null);
}
}
}
public Rectangle getBounds() {
return new Rectangle((int)x, (int)y, 32, 32);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public void activate() {
activated=true;
}
public void deactivate() {
activated=false;
}
public boolean getActivated() {
return activated;
}
public void setX(double x) {
this.x=x;
}
public void setY(double y) {
this.y=y;
}
public void shoot(){
if(System.currentTimeMillis() - lastShot >= 1000){
Sound.turretShot.playOnce();
lastShot = System.currentTimeMillis();
c.addEntity(new Bullet(x,y,game,tex,c,direction));
}
}
}
Now i have the problem that the turret Shoots once and the sound plays and then its gone (example video: https://youtu.be/q8TR2nR8hUI ). I tried to give every object his own Sound Clip but that very wastefull and last time it reduced my ticks and fps to 1 every 5 seconds or so.
Thats why i wanted to ask for a solution or some heplfull ideas and code.
I red something about and Byte array and dataStreamOutput, or that i could clone the clips but i cant get either one to work.
I am sorry for my somehow bad english, i am german so pls overlook any mistake (unless you can't read it)